rs232 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (4) hide show
  1. data/README +26 -28
  2. data/lib/rs232.rb +57 -39
  3. data/rakefile.rb +15 -6
  4. metadata +11 -6
data/README CHANGED
@@ -1,34 +1,32 @@
1
- ##
2
- #
3
- # RS232
4
- #
5
- # Ruby interface to Windows Serial Port API
6
- #
7
- # author hugo benichi
8
- # email hugo.benichi@m4x.org
9
- # copyright 2012 hugo benichi
10
- # version 0.1.3
11
- #
12
- ##
13
-
14
- installation:
15
-
16
- run in the root directory
17
- rake gem_install
18
-
19
- it will compile the gem library and produce a .gem package for ruby
20
- it will then install the .gem automatically
21
-
22
- usage:
23
-
1
+
2
+
3
+ RS232
4
+
5
+ Ruby interface to Windows Serial Port API
6
+
7
+ author hugo benichi
8
+ email hugo[dot]benichi[at]m4x[dot]org
9
+ copyright 2012 hugo benichi
10
+ version 0.1.4
11
+
12
+
13
+ Installation:
14
+
15
+ To compile the gem, produce a .gem package and install it automatically, run
16
+ from the root directory:
17
+
18
+ $ rake gem_install
19
+
20
+ Usage:
21
+
24
22
  cf test/test_rs232.rb
25
-
23
+
26
24
  first, require the gem with
27
25
  require 'rs232'
28
-
29
- then instance an object of RS232, passing an address, and optionally parameters to configure
26
+
27
+ then create an RS232 instance, passing an address and optional conf params
30
28
  serial_port = RS232.new 'COM1'
31
-
29
+
32
30
  the default parameters are
33
31
  baud rate: 9600
34
32
  8 bits
@@ -37,4 +35,4 @@
37
35
  control flow hardware (RTS/CTS)
38
36
  delimiters "\r\n"
39
37
 
40
- you can directly use the RS232 instance with the 'write', 'read', and 'query' commands
38
+ you can use RS232 instances with 'write', 'read' and 'query' commands
@@ -2,8 +2,10 @@ class RS232
2
2
 
3
3
  require 'ffi'
4
4
 
5
- attr_accessor :report, :delimiter
6
- attr_reader :count, :error
5
+ attr_accessor :report, # flag set by client, if true reports read/write bits
6
+ :delimiter # line delimiter caracters, default: "\r\n"
7
+ attr_reader :count, # number of last read/write bits
8
+ :error # last error/status code
7
9
 
8
10
  # serial port object constructor
9
11
  # also sets the parameters and timeout properties through an hash argument
@@ -27,10 +29,14 @@ class RS232
27
29
  share = params[:share] || 0 #Win32::FILE_SHARE_DELETE
28
30
  type = params[:file] || Win32::OPEN_EXISTING
29
31
  attr = params[:attr] || Win32::FILE_ATTRIBUTE_NORMAL
32
+
30
33
  @serial = Win32::CreateFileA( address, mode, share, nil, type, attr, nil)
31
34
  @error = Win32.error_check
35
+
32
36
  puts "RS232 >> got file handle 0x%.8x for com port %s" % [@serial, address]
33
- DCB.new.tap do |p|
37
+
38
+ # com port connection configuration with C struct
39
+ DCB.new.tap do |p| # check below for DCB struct definition
34
40
  p[:dcblength] = DCB::Sizeof
35
41
  Win32::GetCommState @serial, p
36
42
  p[:baudrate] = params[:baudrate] || 9600
@@ -40,6 +46,8 @@ class RS232
40
46
  Win32::SetCommState @serial, p
41
47
  @error = Win32.error_check
42
48
  end
49
+
50
+ # com port connection timeouts configuration with C struct
43
51
  CommTimeouts.new.tap do |timeouts|
44
52
  timeouts[:read_interval_timeout] = params[:read_interval_timeout] || 50
45
53
  timeouts[:read_total_timeout_multiplier] = params[:read_total_timeout_multiplier] || 50
@@ -49,13 +57,15 @@ class RS232
49
57
  Win32::SetCommTimeouts @serial, timeouts
50
58
  @error = Win32.error_check
51
59
  end
60
+
52
61
  grow_buffer 128
53
62
  @count = FFI::MemoryPointer.new :uint, 1
54
63
  @report = false
55
64
  @delimiter = params[:delimiter] || "\r\n"
56
65
  end
57
66
 
58
- # writes a string to the Serial port and happens the delimiter characters stores in @delimiters
67
+ # writes a string to the Serial port
68
+ # automatically appends the delimiter characters stored in @delimiter
59
69
  def write string
60
70
  command = "%s%s" % [string.chomp, @delimiter]
61
71
  grow_buffer command.length
@@ -66,7 +76,7 @@ class RS232
66
76
  puts "write count %i" % @count.read_uint32 if @report
67
77
  end
68
78
 
69
- # read a string from the Serial port
79
+ # reads a string from the Serial port
70
80
  def read
71
81
  Win32::ReadFile @serial, @buffer, @buflen, @count, nil
72
82
  @error = Win32.error_check
@@ -74,27 +84,31 @@ class RS232
74
84
  @buffer.read_string.chomp
75
85
  end
76
86
 
77
- # write and read helper method
87
+ # write + read helper method for queries
78
88
  def query string
79
89
  write string
80
90
  read
81
91
  end
82
92
 
83
- # close the Com port
93
+ # closes the Com port TODO: sets this as object finilizer
84
94
  def stop
85
95
  Win32::CloseHandle @serial
86
96
  @error = Win32.error_check
87
97
  end
88
98
 
89
- # increase the buffer size for reading and writing
90
- def grow_buffer size
91
- @buffer = FFI::MemoryPointer.new :char, @buflen = size if @buffer.nil? || @buflen < size
99
+ # increases the buffer size for reading and writing
100
+ def grow_buffer size
101
+ if @buffer.nil? || @buflen < size
102
+ @buffer = FFI::MemoryPointer.new :char, @buflen = size
103
+ end
92
104
  end
93
105
 
94
106
  # wraps the native Windows API functions for file IO and COMM port found in kernel32.dll
95
107
  module Win32
108
+
96
109
  extend FFI::Library
97
110
  ffi_lib 'kernel32.dll'
111
+
98
112
  [
99
113
  [ :GetLastError, [], :uint32],
100
114
  [ :CreateFileA, [:pointer, :uint32, :uint32, :pointer, :uint32, :uint32, :pointer], :pointer],
@@ -110,55 +124,59 @@ class RS232
110
124
  [ :GetCommTimeouts, [:pointer, :pointer], :int32],
111
125
  [ :SetCommTimeouts, [:pointer, :pointer], :int32],
112
126
  ].each{ |sig| attach_function *sig }
127
+
113
128
  def self.error_code
114
129
  err = self::GetLastError()
115
130
  "error code: %i | 0x%.8x" % [err,err]
116
131
  end
132
+
117
133
  def self.error_check
118
134
  self::GetLastError().tap{ |err| puts "error: %i | 0x%.8x" % [err,err] if err != 0 }
119
135
  end
120
- # consts from Windows seven sdk. extract with
121
- # grep -i "generic_read" *.h
122
- # from the /Include directory
123
- FILE_SHARE_DELETE = 0x00000004
124
- FILE_SHARE_READ = 0x00000001
125
- FILE_SHARE_WRITE = 0x00000002
126
- FILE_SHARE_ALL = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE
136
+
137
+ # consts from Windows seven sdk. extract with
138
+ # grep -i "generic_read" *.h
139
+ # from the /Include directory
140
+ FILE_SHARE_DELETE = 0x00000004
141
+ FILE_SHARE_READ = 0x00000001
142
+ FILE_SHARE_WRITE = 0x00000002
143
+ FILE_SHARE_ALL = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE
127
144
  GENERIC_READ = 0x80000000
128
145
  GENERIC_WRITE = 0x40000000
129
- CREATE_NEW = 1
130
- CREATE_ALWAYS = 2
146
+ CREATE_NEW = 1
147
+ CREATE_ALWAYS = 2
131
148
  OPEN_EXISTING = 3
132
- OPEN_ALWAYS = 4
149
+ OPEN_ALWAYS = 4
133
150
  FILE_ATTRIBUTE_NORMAL = 0x00000080
151
+
134
152
  end
135
153
 
136
154
  # this struct is used by windows to configure the COMM port
137
155
  class DCB < FFI::Struct
138
156
  layout :dcblength, :uint32,
139
157
  :baudrate, :uint32,
140
- :flags, :uint32, # the :flag uint32 is actually a bit fields compound with structure
141
- :wreserved, :uint16, # uint32 fBinary :1;
142
- :xonlim, :uint16, # uint32 fParity :1;
143
- :xofflim, :uint16, # uint32 fParity :1;
144
- :bytesize, :uint8, # uint32 fOutxCtsFlow :1;
145
- :parity, :uint8, # uint32 fOutxDsrFlow :1;
146
- :stopbits, :uint8, # uint32 fDtrControl :2;
147
- :xonchar, :int8, # uint32 fDsrSensitivity :1;
148
- :xoffchar, :int8, # uint32 fTXContinueOnXoff :1;
149
- :errorchar, :int8, # uint32 fOutX :1;
150
- :eofchar, :int8, # uint32 fInX :1;
151
- :evtchar, :int8, # uint32 fErrorChar :1;
152
- :wreserved1, :uint16 # uint32 fNull :1;
153
- # uint32 fRtsControl :2;
154
- # uint32 fAbortOnError :1;
155
- # uint32 fDummy2 :17;
156
- Sizeof = 28 # this is used to tell windows the size of its own struct, not sure why it is necessary (different Windows version)
157
- ONESTOPBIT = 0
158
+ :flags, :uint32, # :flag is actually a bit fields compound:
159
+ :wreserved, :uint16, # uint32 fBinary :1;
160
+ :xonlim, :uint16, # uint32 fParity :1;
161
+ :xofflim, :uint16, # uint32 fParity :1;
162
+ :bytesize, :uint8, # uint32 fOutxCtsFlow :1;
163
+ :parity, :uint8, # uint32 fOutxDsrFlow :1;
164
+ :stopbits, :uint8, # uint32 fDtrControl :2;
165
+ :xonchar, :int8, # uint32 fDsrSensitivity :1;
166
+ :xoffchar, :int8, # uint32 fTXContinueOnXoff :1;
167
+ :errorchar, :int8, # uint32 fOutX :1;
168
+ :eofchar, :int8, # uint32 fInX :1;
169
+ :evtchar, :int8, # uint32 fErrorChar :1;
170
+ :wreserved1, :uint16 # uint32 fNull :1;
171
+ # uint32 fRtsControl :2;
172
+ # uint32 fAbortOnError :1;
173
+ # uint32 fDummy2 :17;
174
+ Sizeof = 28 # this is used to tell windows the size of its own struct,
175
+ ONESTOPBIT = 0 # not sure why necessary (different Windows versions ?)
158
176
  NOPARITY = 0
159
177
  end
160
178
 
161
- # this structure is used to set timeout properties of the opened COM ports
179
+ # this struct is used to set timeout properties of the opened COM ports
162
180
  class CommTimeouts < FFI::Struct
163
181
  layout :read_interval_timeout, :uint32,
164
182
  :read_total_timeout_multiplier, :uint32,
@@ -1,11 +1,20 @@
1
- task :test_global do ruby "test/test_rs232.rb" end
2
- task :test_local do ruby "-Ilib test/test_rs232.rb" end
1
+ task :test_global do # test if run after gem install
2
+ ruby "test/test_rs232.rb"
3
+ end
4
+
5
+ task :test_local do # test if run from gem root dir
6
+ ruby "-Ilib test/test_rs232.rb"
7
+ end
8
+
9
+ task :gem_build do
10
+ sh "gem build rs232.gemspec"
11
+ end
3
12
 
4
- task :gem_build do sh "gem build rs232.gemspec" end
5
13
  task :gem_install => :gem_build do
6
- gemfile = Dir.new("./").entries.select{ |f| f =~ /rs232-[\d]+\.[\d]+\.[\d]+.gem/ }.sort[-1]
7
- puts "installing %s" % gemfile
14
+ gemfile = Dir.new("./").entries.select{ |f|
15
+ f =~ /rs232-[\d]+\.[\d]+\.[\d]+.gem/
16
+ }.sort[-1]
8
17
  sh "gem install --local %s" % gemfile
9
18
  end
10
19
 
11
- task :default => :test_local
20
+ task :default => :test_local
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rs232
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.3
4
+ version: 0.1.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-07-24 00:00:00.000000000 Z
12
+ date: 2013-03-19 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
16
- requirement: &16159800 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,15 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *16159800
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
25
30
  description: Allows to script access to the serial port on Windows. Simple read and
26
31
  write commands
27
- email: hugo.benichi@m4x.org
32
+ email: hugo[dot]benichi[at]m4x[dot]org
28
33
  executables: []
29
34
  extensions: []
30
35
  extra_rdoc_files: []
@@ -53,7 +58,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
53
58
  version: '0'
54
59
  requirements: []
55
60
  rubyforge_project:
56
- rubygems_version: 1.8.11
61
+ rubygems_version: 1.8.23
57
62
  signing_key:
58
63
  specification_version: 3
59
64
  summary: Ruby interface to Windows Serial Port API