phidgets-ffi 0.0.5 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. data/.gitignore +3 -0
  2. data/LICENSE +1 -1
  3. data/README.rdoc +92 -42
  4. data/examples/accelerometer.rb +39 -0
  5. data/examples/advanced_servo.rb +94 -0
  6. data/examples/analog.rb +43 -0
  7. data/examples/bridge.rb +57 -0
  8. data/examples/dictionary.rb +46 -31
  9. data/examples/encoder.rb +59 -0
  10. data/examples/frequency_counter.rb +63 -0
  11. data/examples/gps.rb +91 -0
  12. data/examples/interface_kit_with_block.rb +68 -0
  13. data/examples/interface_kit_without_block.rb +60 -0
  14. data/examples/ir.rb +157 -0
  15. data/examples/led.rb +36 -0
  16. data/examples/manager.rb +16 -10
  17. data/examples/motor_control.rb +108 -0
  18. data/examples/{ffi → raw-ffi}/dictionary.rb +11 -1
  19. data/examples/{ffi → raw-ffi}/interface_kit.rb +19 -2
  20. data/examples/{ffi → raw-ffi}/library_version.rb +0 -0
  21. data/examples/{ffi → raw-ffi}/log.rb +0 -0
  22. data/examples/{ffi → raw-ffi}/manager.rb +6 -3
  23. data/examples/rfid.rb +63 -0
  24. data/examples/servo.rb +45 -30
  25. data/examples/spatial.rb +75 -0
  26. data/examples/stepper.rb +87 -0
  27. data/examples/temperature_sensor.rb +49 -0
  28. data/examples/text_lcd.rb +101 -0
  29. data/lib/phidgets-ffi.rb +34 -3
  30. data/lib/phidgets-ffi/accelerometer.rb +122 -0
  31. data/lib/phidgets-ffi/advanced_servo.rb +304 -0
  32. data/lib/phidgets-ffi/analog.rb +111 -0
  33. data/lib/phidgets-ffi/bridge.rb +167 -0
  34. data/lib/phidgets-ffi/common.rb +506 -103
  35. data/lib/phidgets-ffi/dictionary.rb +136 -23
  36. data/lib/phidgets-ffi/encoder.rb +196 -0
  37. data/lib/phidgets-ffi/error.rb +8 -3
  38. data/lib/phidgets-ffi/ffi/accelerometer.rb +30 -0
  39. data/lib/phidgets-ffi/ffi/advanced_servo.rb +73 -0
  40. data/lib/phidgets-ffi/ffi/analog.rb +29 -0
  41. data/lib/phidgets-ffi/ffi/bridge.rb +44 -0
  42. data/lib/phidgets-ffi/ffi/common.rb +51 -34
  43. data/lib/phidgets-ffi/ffi/constants.rb +3 -1
  44. data/lib/phidgets-ffi/ffi/dictionary.rb +25 -20
  45. data/lib/phidgets-ffi/ffi/encoder.rb +32 -0
  46. data/lib/phidgets-ffi/ffi/frequency_counter.rb +38 -0
  47. data/lib/phidgets-ffi/ffi/gps.rb +32 -0
  48. data/lib/phidgets-ffi/ffi/interface_kit.rb +26 -23
  49. data/lib/phidgets-ffi/ffi/ir.rb +50 -0
  50. data/lib/phidgets-ffi/ffi/led.rb +40 -0
  51. data/lib/phidgets-ffi/ffi/log.rb +7 -6
  52. data/lib/phidgets-ffi/ffi/manager.rb +35 -20
  53. data/lib/phidgets-ffi/ffi/motor_control.rb +66 -0
  54. data/lib/phidgets-ffi/ffi/rfid.rb +36 -0
  55. data/lib/phidgets-ffi/ffi/servo.rb +16 -15
  56. data/lib/phidgets-ffi/ffi/spatial.rb +40 -0
  57. data/lib/phidgets-ffi/ffi/stepper.rb +56 -0
  58. data/lib/phidgets-ffi/ffi/temperature_sensor.rb +42 -0
  59. data/lib/phidgets-ffi/ffi/text_lcd.rb +55 -0
  60. data/lib/phidgets-ffi/frequency_counter.rb +148 -0
  61. data/lib/phidgets-ffi/gps.rb +181 -0
  62. data/lib/phidgets-ffi/interface_kit.rb +205 -92
  63. data/lib/phidgets-ffi/ir.rb +290 -0
  64. data/lib/phidgets-ffi/led.rb +112 -0
  65. data/lib/phidgets-ffi/log.rb +14 -2
  66. data/lib/phidgets-ffi/manager.rb +143 -26
  67. data/lib/phidgets-ffi/motor_control.rb +497 -0
  68. data/lib/phidgets-ffi/phidgets-ffi.rb +15 -2
  69. data/lib/phidgets-ffi/rfid.rb +220 -0
  70. data/lib/phidgets-ffi/servo.rb +103 -61
  71. data/lib/phidgets-ffi/spatial.rb +306 -0
  72. data/lib/phidgets-ffi/stepper.rb +370 -0
  73. data/lib/phidgets-ffi/temperature_sensor.rb +157 -0
  74. data/lib/phidgets-ffi/text_lcd.rb +298 -0
  75. data/lib/phidgets-ffi/version.rb +1 -1
  76. data/phidgets-ffi.gemspec +2 -2
  77. metadata +89 -76
  78. data/examples/ffi/servo.rb +0 -67
  79. data/examples/interface_kit.rb +0 -20
@@ -1,57 +1,92 @@
1
1
  module Phidgets
2
- class InterfaceKit
3
2
 
3
+ # This class represents a PhidgetInterfaceKit.
4
+ class InterfaceKit
5
+
4
6
  Klass = Phidgets::FFI::CPhidgetInterfaceKit
5
7
  include Phidgets::Common
6
8
 
7
- attr_reader :inputs, :outputs, :sensors
8
-
9
- def initialize(serial_number=-1, &block)
10
- create
11
- open(serial_number)
12
- wait_for_attachment
13
- load_inputs
14
- load_outputs
15
- load_sensors
16
- if block_given?
17
- yield self
18
- close
19
- delete
20
- end
21
- end
9
+ # Collection of digital inputs
10
+ # @return [InterfaceKitInputs]
11
+ attr_reader :inputs
12
+
13
+ # Collection of digital outputs
14
+ # @return [InterfaceKitOutputs]
15
+ attr_reader :outputs
16
+
17
+ # Collection of analog sensor inputs
18
+ # @return [InterfaceKitSensors]
19
+ attr_reader :sensors
20
+
21
+ attr_reader :attributes
22
22
 
23
- def attributes
23
+ # The attributes of a PhidgetInterfaceKit
24
+ def attributes
24
25
  super.merge({
25
26
  :inputs => inputs.size,
26
27
  :outputs => outputs.size,
27
28
  :sensors => sensors.size,
29
+ :ratiometric => ratiometric
28
30
  })
29
31
  end
30
32
 
33
+ # Sets an input change handler callback function. This is called when a digital input on the PhidgetInterfaceKit board has changed.
34
+ #
35
+ # @param [String] obj Object to pass to the callback function. This is optional.
36
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
37
+ # @example
38
+ # ifkit.on_input_change do |device, input, state, obj|
39
+ # print "Digital Input #{input.index}, changed to #{state}\n"
40
+ # end
41
+ # As this runs in it's own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.
42
+ # @return [Boolean] returns true or raises an error
31
43
  def on_input_change(obj=nil, &block)
32
44
  @on_input_change_obj = obj
33
45
  @on_input_change = Proc.new { |device, obj_ptr, index, state|
34
- yield @inputs[index], (state == 0 ? false : true), object_for(obj_ptr)
46
+ yield self, @inputs[index], (state == 0 ? false : true), object_for(obj_ptr)
35
47
  }
36
48
  Klass.set_OnInputChange_Handler(@handle, @on_input_change, pointer_for(obj))
37
49
  end
38
50
 
51
+ # Sets an output change handler callback function. This is called when a digital output on the PhidgetInterfaceKit board has changed.
52
+ #
53
+ # @param [String] obj Object to pass to the callback function. This is optional.
54
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
55
+ # @example
56
+ # ifkit.on_output_change do |device, output, state, obj|
57
+ # print "Digital Output #{output.index}, changed to #{state}\n"
58
+ # end
59
+ # As this runs in it's own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.
60
+ # @return [Boolean] returns true or raises an error
39
61
  def on_output_change(obj=nil, &block)
40
62
  @on_output_change_obj = obj
41
63
  @on_output_change = Proc.new { |device, obj_ptr, index, state|
42
- yield @outputs[index], (state == 0 ? false : true), object_for(obj_ptr)
64
+ yield self, @outputs[index], (state == 0 ? false : true), object_for(obj_ptr)
43
65
  }
44
66
  Klass.set_OnOutputChange_Handler(@handle, @on_output_change, pointer_for(obj))
45
67
  end
46
68
 
69
+ # Sets a sensor change handler callback function. This is called when a sensor on the PhidgetInterfaceKit has changed by at least the sensitivity value that has been set for this input.
70
+ #
71
+ # @param [String] obj Object to pass to the callback function. This is optional.
72
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
73
+ # @example
74
+ # ifkit.on_sensor_change do |device, input, value, obj|
75
+ # print "Analog Input #{input.index}, changed to #{value}\n"
76
+ # end
77
+ # As this runs in it's own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.
78
+ # @return [Boolean] returns true or raises an error
47
79
  def on_sensor_change(obj=nil, &block)
48
- @on_sensor_change_obj = obj
80
+ @on_sensor_change_obj = obj
49
81
  @on_sensor_change = Proc.new { |device, obj_ptr, index, value|
50
- yield @sensors[index], value, object_for(obj_ptr)
51
- }
82
+ yield self, @sensors[index], value, object_for(obj_ptr)
83
+ }
52
84
  Klass.set_OnSensorChange_Handler(@handle, @on_sensor_change, pointer_for(obj))
53
85
  end
54
-
86
+
87
+ # Returns the ratiometric state of the Phidget.
88
+ #
89
+ # @return [Boolean] returns the ratiometric state or raises an error
55
90
  def ratiometric
56
91
  ptr = ::FFI::MemoryPointer.new(:int)
57
92
  Klass.getRatiometric(@handle, ptr)
@@ -59,107 +94,130 @@ module Phidgets
59
94
  end
60
95
  alias_method :ratiometric?, :ratiometric
61
96
 
62
- def ratiometric=(val)
63
- tmp = val ? 1 : 0
97
+ # Sets the ratiometric state of the Phidget.
98
+ # @param [Boolean] new_state new ratiometric state
99
+ # @return [Boolean] returns the ratiometric state or raises an error
100
+ def ratiometric=(new_state)
101
+ tmp = new_state ? 1 : 0
64
102
  Klass.setRatiometric(@handle, tmp)
65
-
66
- val
67
- end
68
- private
69
-
70
- def load_inputs
71
- ptr = ::FFI::MemoryPointer.new(:int)
72
- Klass.getInputCount(@handle, ptr)
73
-
74
- @inputs = []
75
- ptr.get_int(0).times do |i|
76
- @inputs << InterfaceKitInput.new(@handle, i)
77
- end
103
+ new_state
78
104
  end
105
+
106
+ # This class represents an digital input for a PhidgetInterfaceKit. All the properties of an digital input are stored in this class.
107
+ class InterfaceKitInputs
79
108
 
80
- def load_outputs
81
- ptr = ::FFI::MemoryPointer.new(:int)
82
- Klass.getOutputCount(@handle, ptr)
83
-
84
- @outputs = []
85
- ptr.get_int(0).times do |i|
86
- @outputs << InterfaceKitOutput.new(@handle, i)
87
- end
88
- end
89
-
90
- def load_sensors
91
- ptr = ::FFI::MemoryPointer.new(:int)
92
- Klass.getSensorCount(@handle, ptr)
93
-
94
- @sensors = []
95
- ptr.get_int(0).times do |i|
96
- @sensors << InterfaceKitSensor.new(@handle, i)
97
- end
98
- end
99
- end
100
-
101
- class InterfaceKitInput
102
- Klass = Phidgets::FFI::CPhidgetInterfaceKit
109
+ Klass = Phidgets::FFI::CPhidgetInterfaceKit
110
+
111
+ private
112
+ def initialize(handle, index)
113
+ @handle, @index = handle, index.to_i
114
+ end
103
115
 
104
- attr_reader :index
116
+ public
105
117
 
106
- def initialize(handle, index)
107
- @handle, @index = handle, index.to_i
118
+ # Displays data for the digital input
119
+ def inspect
120
+ "#<#{self.class} @index=#{index}, @state=#{state}>"
108
121
  end
109
122
 
123
+ # @return [Integer] returns index of the digital input, or raises an error.
124
+ def index
125
+ @index
126
+ end
127
+
128
+ # @return [Boolean] returns state of the digital input, or raises an error.
110
129
  def state
111
130
  ptr = ::FFI::MemoryPointer.new(:int)
112
131
  Klass.getInputState(@handle, @index, ptr)
113
132
  (ptr.get_int(0) == 0) ? false : true
114
133
  end
134
+
135
+ # @return [Boolean] returns true if the state is true.
136
+ def on
137
+ state == true
138
+ end
139
+ alias_method :on?, :on
140
+
141
+ # @return [Boolean] returns true if the state is off.
142
+ def off
143
+ !on
144
+ end
145
+ alias_method :off?, :off
146
+
115
147
  end
116
148
 
117
- class InterfaceKitOutput
149
+ # This class represents an digital output for a PhidgetInterfaceKit. All the properties of an digital output are stored and modified in this class.
150
+ class InterfaceKitOutputs
118
151
  Klass = Phidgets::FFI::CPhidgetInterfaceKit
119
152
 
120
- attr_reader :index
121
-
153
+ private
122
154
  def initialize(handle, index)
123
155
  @handle, @index = handle, index.to_i
124
156
  end
125
157
 
126
- def state=(val)
127
- tmp = val ? 1 : 0
158
+ public
159
+
160
+ # Displays data for the digital output
161
+ def inspect
162
+ "#<#{self.class} @index=#{index}, @state=#{state}>"
163
+ end
164
+
165
+ # @return [Integer] returns index of the digital output, or raises an error.
166
+ def index
167
+ @index
168
+ end
169
+
170
+ # Sets the state of the digital output, or raises an error.
171
+ # @param [Boolean] new_state new state
172
+ # @return [Boolean] sets the state of the digital output, or raises an error.
173
+ def state=(new_state)
174
+ tmp = new_state ? 1 : 0
128
175
  Klass.setOutputState(@handle, @index, tmp)
129
-
130
- val
176
+ new_state
131
177
  end
132
178
 
179
+ # @return [Boolean] returns state of the digital output, or raises an error.
133
180
  def state
134
181
  ptr = ::FFI::MemoryPointer.new(:int)
135
182
  Klass.getOutputState(@handle, @index, ptr)
136
183
  (ptr.get_int(0) == 0) ? false : true
137
184
  end
138
185
 
186
+ # @return [Boolean] returns true if the state is true.
139
187
  def on
140
188
  state == true
141
189
  end
142
- alias_method :on?, :state
190
+ alias_method :on?, :on
143
191
 
192
+ # @return [Boolean] returns true if the state is off.
144
193
  def off
145
194
  !on
146
195
  end
147
196
  alias_method :off?, :off
148
197
  end
149
-
150
- class InterfaceKitSensor
198
+
199
+ # This class represents an analog sensor for a PhidgetInterfaceKit. All the properties of an analog sensor are stored and modified in this class.
200
+ class InterfaceKitSensors
151
201
  Klass = Phidgets::FFI::CPhidgetInterfaceKit
152
202
 
153
- attr_reader :index
154
-
203
+ private
155
204
  def initialize(handle, index)
156
205
  @handle, @index = handle, index.to_i
157
206
  end
158
-
207
+
208
+ public
209
+
210
+ # Displays data for the analog sensor
159
211
  def inspect
160
- "#<#{self.class} @value=#{value}, @raw_value=#{raw_value}, @rate=#{rate}, @trigger=#{trigger}, @max_rate=#{max_rate}, @min_rate=#{min_rate}>"
212
+ "#<#{self.class} @value=#{value}, @raw_value=#{raw_value}, @data_rate=#{data_rate}, @sensitivity=#{sensitivity}, @data_rate_max=#{data_rate_max}, @data_rate_min=#{data_rate_min}>"
161
213
  end
162
214
 
215
+ # @return [Integer] returns index of the analog input, or raises an error.
216
+ def index
217
+ @index
218
+ end
219
+
220
+ # @return [Integer] returns value of the analog input, or raises an error.
163
221
  def value
164
222
  ptr = ::FFI::MemoryPointer.new(:int)
165
223
  Klass.getSensorValue(@handle, @index, ptr)
@@ -167,46 +225,101 @@ module Phidgets
167
225
  end
168
226
  alias_method :to_i, :value
169
227
 
228
+ # @return [Integer] returns raw value of the analog input, or raises an error.
170
229
  def raw_value
171
230
  ptr = ::FFI::MemoryPointer.new(:int)
172
231
  Klass.getSensorRawValue(@handle, @index, ptr)
173
232
  ptr.get_int(0)
174
233
  end
175
234
 
176
- def trigger
235
+ # @return [Integer] returns sensitivity of the analog input, or raises an error.
236
+ def sensitivity
177
237
  ptr = ::FFI::MemoryPointer.new(:int)
178
238
  Klass.getSensorChangeTrigger(@handle, @index, ptr)
179
239
  ptr.get_int(0)
180
240
  end
181
241
 
182
- def trigger=(val)
183
- Klass.setSensorChangeTrigger(@handle, @index, val.to_i)
184
-
185
- val.to_i
242
+ # Sets the sensitivity of the analog input, or raises an error.
243
+ # @param [Integer] new_sensitivity new sensitivity
244
+ # @return [Integer] returns sensitivity of the analog input, or raises an error.
245
+ def sensitivity=(new_sensitivity)
246
+ Klass.setSensorChangeTrigger(@handle, @index, new_sensitivity.to_i)
247
+ new_sensitivity.to_i
186
248
  end
187
-
188
- def max_rate
249
+
250
+ # @return [Integer] returns data rate of the analog input, or raises an error.
251
+ def data_rate
189
252
  ptr = ::FFI::MemoryPointer.new(:int)
190
- Klass.getDataRateMax(@handle, @index, ptr)
253
+ Klass.getDataRate(@handle, @index, ptr)
191
254
  ptr.get_int(0)
192
255
  end
193
256
 
194
- def min_rate
257
+ # Sets the data rate of the analog input, or raises an error.
258
+ # @param [Integer] new_data_rate data rate
259
+ # @return [Integer] returns the data rate of the analog input, or raises an error.
260
+ def data_rate=(new_data_rate)
261
+ Klass.setDataRate(@handle, @index, new_data_rate.to_i)
262
+ new_data_rate.to_i
263
+ end
264
+
265
+ # @return [Integer] returns minimum data rate of the analog input, or raises an error.
266
+ def data_rate_min
195
267
  ptr = ::FFI::MemoryPointer.new(:int)
196
268
  Klass.getDataRateMin(@handle, @index, ptr)
197
269
  ptr.get_int(0)
198
270
  end
199
271
 
200
- def rate
272
+ # @return [Integer] returns maximum data rate of the analog input, or raises an error.
273
+ def data_rate_max
201
274
  ptr = ::FFI::MemoryPointer.new(:int)
202
- Klass.getDataRate(@handle, @index, ptr)
275
+ Klass.getDataRateMax(@handle, @index, ptr)
203
276
  ptr.get_int(0)
204
277
  end
278
+
279
+ end #InterfaceKitSensors
280
+
281
+ private
282
+
283
+ def load_device_attributes
284
+ load_inputs
285
+ load_outputs
286
+ load_sensors
287
+ end
288
+
289
+ def load_inputs
290
+ ptr = ::FFI::MemoryPointer.new(:int)
291
+ Klass.getInputCount(@handle, ptr)
292
+
293
+ @inputs = []
294
+ ptr.get_int(0).times do |i|
295
+ @inputs << InterfaceKitInputs.new(@handle, i)
296
+ end
297
+ end
298
+
299
+ def load_outputs
300
+ ptr = ::FFI::MemoryPointer.new(:int)
301
+ Klass.getOutputCount(@handle, ptr)
205
302
 
206
- def rate=(val)
207
- Klass.setDataRate(@handle, @index, val.to_i)
303
+ @outputs = []
304
+ ptr.get_int(0).times do |i|
305
+ @outputs << InterfaceKitOutputs.new(@handle, i)
306
+ end
307
+ end
208
308
 
209
- val.to_i
309
+ def load_sensors
310
+ ptr = ::FFI::MemoryPointer.new(:int)
311
+ Klass.getSensorCount(@handle, ptr)
312
+ @sensors = []
313
+ ptr.get_int(0).times do |i|
314
+ @sensors << InterfaceKitSensors.new(@handle, i)
315
+ end
210
316
  end
317
+
318
+ def remove_specific_event_handlers
319
+ Klass.set_OnSensorChange_Handler(@handle, nil, nil)
320
+ Klass.set_OnOutputChange_Handler(@handle, nil, nil)
321
+ Klass.set_OnInputChange_Handler(@handle, nil, nil)
322
+ end
211
323
  end
324
+
212
325
  end
@@ -0,0 +1,290 @@
1
+ module Phidgets
2
+
3
+ # This class represents a PhidgetIR.
4
+ class IR
5
+
6
+ Klass = Phidgets::FFI::CPhidgetIR
7
+ include Phidgets::Common
8
+
9
+ # This represents the encoding parameters needed to transmit a code.
10
+ #
11
+ # Examples:
12
+ #
13
+ # puts ir.code_info[:bit_count]
14
+ # puts ir.code_info[:encoding]
15
+ # puts ir.code_info[:length]
16
+ # puts ir.code_info[:gap]
17
+ # puts ir.code_info[:trail]
18
+ # puts ir.code_info[:header]
19
+ # puts ir.code_info[:one]
20
+ # puts ir.code_info[:zero]
21
+ # puts ir.code_info[:repeat]
22
+ # puts ir.code_info[:min_repeat]
23
+ # puts ir.code_info[:toggle_mask]
24
+ # puts ir.code_info[:carrier_frequency]
25
+ # puts ir.code_info[:duty_cycle]
26
+ class IR_code_info < ::FFI::Struct
27
+
28
+ # Number of bits in the code
29
+ # @return [Integer] returns the number of bits
30
+ attr_accessor :bit_count
31
+
32
+ # Encoding used to encode the data
33
+ # @return [Phidgets::FFI::IREncoding] returns the encoding type
34
+ attr_accessor :encoding
35
+
36
+ # Constant or variable length encoding
37
+ # @return [Phidgets::FFI::IRLength] returns the length type
38
+ attr_accessor :length
39
+
40
+ # Gap time in us
41
+ # @return [Integer] returns the gap time
42
+ attr_accessor :gap
43
+
44
+ # Trail time in us - can be 0 for none
45
+ # @return [Integer] returns the the trail time
46
+ attr_accessor :trail
47
+
48
+ # Header pulse and space - can be 0 for none
49
+ # @return [FFI::Struct::InlineArray[2<Integer>]] returns the header
50
+ attr_accessor :header
51
+
52
+ # Pulse and space times to represent a '1' bit, in us
53
+ # @return [FFI::Struct::InlineArray[2<Integer>]] returns the pulse and space times
54
+ attr_accessor :one
55
+
56
+ # Pulse and space times to represent a '0' bit, in us
57
+ # @return [FFI::Struct::InlineArray[2<Integer>]] returns the pulse and space times
58
+ attr_accessor :zero
59
+
60
+ # A series or pulse and space times to represent the repeat code. Start and end with pulses and null terminate - can be 0 for none
61
+ # @return [FFI::Struct::InlineArray[26<Integer>]] returns the repeat code
62
+ attr_accessor :repeat
63
+
64
+ # Minimum number of times to repeat a code on transmit
65
+ # @return [Integer] returns the minimum repeat
66
+ attr_accessor :min_repeat
67
+
68
+ # Bit toggles, which are applied to the code after each transmit
69
+ # @return [FFI::StructLayout::CharArray[16<Integer>]] returns the bit toggles
70
+ attr_accessor :toggle_mask
71
+
72
+ # Carrier frequency in Hz - defaults to 38kHz
73
+ # @return [Integer] returns the carrier frequency
74
+ attr_accessor :carrier_frequency
75
+
76
+ # Duty cycle in precent(10-50%) - defaults to 33
77
+ # @return [Integer] returns the duty cycle
78
+ attr_accessor :duty_cycle
79
+
80
+ layout :bit_count, :int,
81
+ :encoding, Phidgets::FFI::IREncoding,
82
+ :length, Phidgets::FFI::IRLength,
83
+ :gap, :int,
84
+ :trail, :int,
85
+ :header, [:int, 2],
86
+ :one, [:int, 2],
87
+ :zero, [:int, 2],
88
+ :repeat, [:int, 26],
89
+ :min_repeat, :int,
90
+ :toggle_mask, [:uchar, 16],
91
+ :carrier_frequency, :int,
92
+ :duty_cycle, :int
93
+
94
+ end
95
+
96
+ # Sets a raw data handler callback function. This is called whenever a new IR data is available. Data is in the form of an array of microsecond pulse values. This can be used if the user wishes to do their own data decoding, or for codes that the PhidgetIR cannot automatically recognize.
97
+ #
98
+ # @param [String] obj Object to pass to the callback function. This is optional.
99
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
100
+ # @example
101
+ # ir.on_raw_data do |device, raw_data, data_length, obj|
102
+ # puts "Raw data: #{raw_data}, length: #{data_length}"
103
+ # end
104
+ # As this runs in it's own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.
105
+ # @return [Boolean] returns true or raises an error
106
+ def on_raw_data(obj=nil, &block)
107
+ @on_raw_data_obj = obj
108
+ @on_raw_data = Proc.new { |device, obj_ptr, raw_data, data_length|
109
+ data = []
110
+ data_length.times { |i|
111
+ data << raw_data[i].get_int(0)
112
+ }
113
+
114
+ yield self, data, data_length, object_for(obj_ptr)
115
+ }
116
+ Klass.set_OnRawData_Handler(@handle, @on_raw_data, pointer_for(obj))
117
+ end
118
+
119
+ # Sets a code handler callback function. This is called whenever a new code is recognized.
120
+ #
121
+ # @param [String] obj Object to pass to the callback function. This is optional.
122
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
123
+ # @example
124
+ # ir.on_code do |device, data, data_length, bit_count, repeat, obj|
125
+ # puts "Code #{data} received, length: #{data_length}, bit count: #{bit_count}, repeat: #{repeat}"
126
+ # end
127
+ # As this runs in it's own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.
128
+ # @return [Boolean] returns true or raises an error
129
+ def on_code(obj=nil, &block)
130
+ @on_code_obj = obj
131
+ @on_code = Proc.new { |device, obj_ptr, data, data_length, bit_count, repeat|
132
+ data_string = []
133
+ data_length.times { |i|
134
+ data_string[i] = data[i].get_uchar(0).to_s(16)
135
+ }
136
+
137
+ yield self, data_string, data_length, bit_count, repeat, object_for(obj_ptr)
138
+ }
139
+ Klass.set_OnCode_Handler(@handle, @on_code, pointer_for(obj))
140
+ end
141
+
142
+ # Sets a learn handler callback function. This is called when a new code has been learned. This generally requires the button to be held down for a second or two.
143
+ #
144
+ # @param [String] obj Object to pass to the callback function. This is optional.
145
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
146
+ # @example
147
+ # ir.on_learn do |device, data, data_length, code_info, obj|
148
+ # puts "Code #{data} learnt"
149
+ # end
150
+ # As this runs in it's own thread, be sure that all errors are properly handled or the thread will halt and not fire any more.
151
+ # @return [Boolean] returns true or raises an error
152
+ def on_learn(obj=nil, &block)
153
+ @on_learn_obj = obj
154
+ @on_learn = Proc.new { |device, obj_ptr, int_data, data_length, code_info|
155
+ data = []
156
+ data_length.times { |i|
157
+ data[i] = int_data[i].get_uchar(0).to_s(16)
158
+ }
159
+
160
+ code_info_struct = IR_code_info.new(code_info)
161
+
162
+ yield self, data, data_length, code_info_struct, object_for(obj_ptr)
163
+ }
164
+ Klass.set_OnLearn_Handler(@handle, @on_learn, pointer_for(obj))
165
+ end
166
+
167
+ # Transmits a code
168
+ # @param [Array<String>] data data to send
169
+ # @param [IR_code_info] code_info code info structure specifying the attributes of the code to send. Anything that is not set is set to default.
170
+ # @return [Boolean] returns true if the code was successfully transmitted, or raises an error.
171
+ def transmit(data, code_info)
172
+
173
+ pdata = ::FFI::MemoryPointer.new(:uchar, 16)
174
+
175
+ data_ffi = []
176
+ data.size.times { |i|
177
+ data_ffi[i] = data[i].to_i(16)
178
+ }
179
+
180
+ data_ffi = ::FFI::MemoryPointer.new(:uchar, 16).write_array_of_uchar(data_ffi)
181
+
182
+ Klass.Transmit(@handle, data_ffi, code_info)
183
+ true
184
+ end
185
+
186
+ # Transmits a repeat of a previously transmitted code, or raises an error.
187
+ # @return [Boolean] returns true if the code was successfully transmitted, or raises an error.
188
+ def transmit_repeat
189
+ Klass.TransmitRepeat(@handle)
190
+ true
191
+ end
192
+
193
+ # Transmits raw data as a series of pulses and spaces.
194
+ # @param [Array] data data to send
195
+ # @param [Integer] length length of the data array
196
+ # @param [Integer] carrier_frequency carrier frequency in Hz. Leave as 0 for default
197
+ # @param [Integer] duty_cycle duty cycle(10-50). Leave as 0 for default
198
+ # @param [Integer] gap_time gap time in us. This guarantees a gap time(no transmitting) after the data is sent, but can be set to 0
199
+ # @return [Boolean] returns true if the raw data was successfully transmitted, or raises an error.
200
+ def transmit_raw(data, length, carrier_frequency, duty_cycle, gap)
201
+ c_data = ::FFI::MemoryPointer.new(:int, data.size).write_array_of_int(data)
202
+ Klass.TransmitRaw(@handle, c_data, length.to_i, carrier_frequency.to_i, duty_cycle.to_i, gap.to_i)
203
+ true
204
+ end
205
+
206
+ # Reads any available raw data. This should be polled continuously(every 20ms) to avoid missing data. Read data always starts with a space and ends with a pulse.
207
+ # @return [Array<Integer>] returns true if the raw data was successfully transmitted, or raises an error.
208
+ # @return [Integer] returns the data length, or raises an error.
209
+ def read_raw_data
210
+ data_ffi = ::FFI::MemoryPointer.new(:int, 16)
211
+
212
+ data_length = ::FFI::MemoryPointer.new(:int)
213
+ data_length.write_int(16)
214
+
215
+ Klass.getRawData(@handle, data_ffi, data_length)
216
+
217
+ data = []
218
+
219
+ data_length.get_int(0).times { |i|
220
+ data << data_ffi[i].get_int(0)
221
+ }
222
+
223
+ [data, data_length.get_int(0)]
224
+ end
225
+
226
+ # Gets the last code that was received.
227
+ # @return [Array<String>] returns the last code, or raises an error.
228
+ # @return [Integer] returns the data length, or raises an error.
229
+ # @return [Object] returns the bit count, or raises an error.
230
+ def last_code
231
+ data_ffi = ::FFI::MemoryPointer.new(:uchar, 16)
232
+
233
+ data_length = ::FFI::MemoryPointer.new(:int)
234
+ data_length.write_int(16)
235
+
236
+ bit_count = ::FFI::MemoryPointer.new(:int)
237
+
238
+ Klass.getLastCode(@handle, data_ffi, data_length, bit_count)
239
+
240
+ data = []
241
+
242
+ data_length.get_int(0).times { |i|
243
+ data << data_ffi[i].get_uchar(0).to_s(16)
244
+ }
245
+
246
+ [data, data_length.get_int(0), bit_count.get_int(0)]
247
+
248
+ end
249
+
250
+ # Gets the last code that was learned.
251
+ # @return [Array<String>] returns the last learned code, or raises an error.
252
+ # @return [Integer] returns the data length, or raises an error.
253
+ # @return [IR_code_info] returns the code info structure for the learned code, or raises an error.
254
+ def last_learned_code
255
+
256
+ data_ffi = ::FFI::MemoryPointer.new(:uchar, 16)
257
+
258
+ data_length = ::FFI::MemoryPointer.new(:int)
259
+ data_length.write_int(16)
260
+
261
+ code_info = ::FFI::MemoryPointer.new(IR_code_info)
262
+
263
+ Klass.getLastLearnedCode(@handle, data_ffi, data_length, code_info)
264
+
265
+ data = []
266
+
267
+ data_length.get_int(0).times { |i|
268
+ data << data_ffi[i].get_uchar(0).to_s(16)
269
+ }
270
+
271
+ code_info_struct = IR_code_info.new(code_info)
272
+
273
+ [data, data_length.get_int(0), code_info_struct]
274
+
275
+ end
276
+
277
+ private
278
+
279
+ def load_device_attributes
280
+
281
+ end
282
+
283
+ def remove_specific_event_handlers
284
+ Klass.set_OnCode_Handler(@handle, nil, nil)
285
+ Klass.set_OnLearn_Handler(@handle, nil, nil)
286
+ Klass.set_OnRawData_Handler(@handle, nil, nil)
287
+ end
288
+ end
289
+
290
+ end