rs232 0.1.3 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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