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.
- data/.gitignore +3 -0
- data/LICENSE +1 -1
- data/README.rdoc +92 -42
- data/examples/accelerometer.rb +39 -0
- data/examples/advanced_servo.rb +94 -0
- data/examples/analog.rb +43 -0
- data/examples/bridge.rb +57 -0
- data/examples/dictionary.rb +46 -31
- data/examples/encoder.rb +59 -0
- data/examples/frequency_counter.rb +63 -0
- data/examples/gps.rb +91 -0
- data/examples/interface_kit_with_block.rb +68 -0
- data/examples/interface_kit_without_block.rb +60 -0
- data/examples/ir.rb +157 -0
- data/examples/led.rb +36 -0
- data/examples/manager.rb +16 -10
- data/examples/motor_control.rb +108 -0
- data/examples/{ffi → raw-ffi}/dictionary.rb +11 -1
- data/examples/{ffi → raw-ffi}/interface_kit.rb +19 -2
- data/examples/{ffi → raw-ffi}/library_version.rb +0 -0
- data/examples/{ffi → raw-ffi}/log.rb +0 -0
- data/examples/{ffi → raw-ffi}/manager.rb +6 -3
- data/examples/rfid.rb +63 -0
- data/examples/servo.rb +45 -30
- data/examples/spatial.rb +75 -0
- data/examples/stepper.rb +87 -0
- data/examples/temperature_sensor.rb +49 -0
- data/examples/text_lcd.rb +101 -0
- data/lib/phidgets-ffi.rb +34 -3
- data/lib/phidgets-ffi/accelerometer.rb +122 -0
- data/lib/phidgets-ffi/advanced_servo.rb +304 -0
- data/lib/phidgets-ffi/analog.rb +111 -0
- data/lib/phidgets-ffi/bridge.rb +167 -0
- data/lib/phidgets-ffi/common.rb +506 -103
- data/lib/phidgets-ffi/dictionary.rb +136 -23
- data/lib/phidgets-ffi/encoder.rb +196 -0
- data/lib/phidgets-ffi/error.rb +8 -3
- data/lib/phidgets-ffi/ffi/accelerometer.rb +30 -0
- data/lib/phidgets-ffi/ffi/advanced_servo.rb +73 -0
- data/lib/phidgets-ffi/ffi/analog.rb +29 -0
- data/lib/phidgets-ffi/ffi/bridge.rb +44 -0
- data/lib/phidgets-ffi/ffi/common.rb +51 -34
- data/lib/phidgets-ffi/ffi/constants.rb +3 -1
- data/lib/phidgets-ffi/ffi/dictionary.rb +25 -20
- data/lib/phidgets-ffi/ffi/encoder.rb +32 -0
- data/lib/phidgets-ffi/ffi/frequency_counter.rb +38 -0
- data/lib/phidgets-ffi/ffi/gps.rb +32 -0
- data/lib/phidgets-ffi/ffi/interface_kit.rb +26 -23
- data/lib/phidgets-ffi/ffi/ir.rb +50 -0
- data/lib/phidgets-ffi/ffi/led.rb +40 -0
- data/lib/phidgets-ffi/ffi/log.rb +7 -6
- data/lib/phidgets-ffi/ffi/manager.rb +35 -20
- data/lib/phidgets-ffi/ffi/motor_control.rb +66 -0
- data/lib/phidgets-ffi/ffi/rfid.rb +36 -0
- data/lib/phidgets-ffi/ffi/servo.rb +16 -15
- data/lib/phidgets-ffi/ffi/spatial.rb +40 -0
- data/lib/phidgets-ffi/ffi/stepper.rb +56 -0
- data/lib/phidgets-ffi/ffi/temperature_sensor.rb +42 -0
- data/lib/phidgets-ffi/ffi/text_lcd.rb +55 -0
- data/lib/phidgets-ffi/frequency_counter.rb +148 -0
- data/lib/phidgets-ffi/gps.rb +181 -0
- data/lib/phidgets-ffi/interface_kit.rb +205 -92
- data/lib/phidgets-ffi/ir.rb +290 -0
- data/lib/phidgets-ffi/led.rb +112 -0
- data/lib/phidgets-ffi/log.rb +14 -2
- data/lib/phidgets-ffi/manager.rb +143 -26
- data/lib/phidgets-ffi/motor_control.rb +497 -0
- data/lib/phidgets-ffi/phidgets-ffi.rb +15 -2
- data/lib/phidgets-ffi/rfid.rb +220 -0
- data/lib/phidgets-ffi/servo.rb +103 -61
- data/lib/phidgets-ffi/spatial.rb +306 -0
- data/lib/phidgets-ffi/stepper.rb +370 -0
- data/lib/phidgets-ffi/temperature_sensor.rb +157 -0
- data/lib/phidgets-ffi/text_lcd.rb +298 -0
- data/lib/phidgets-ffi/version.rb +1 -1
- data/phidgets-ffi.gemspec +2 -2
- metadata +89 -76
- data/examples/ffi/servo.rb +0 -67
- 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
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
|
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
|
-
|
80
|
+
@on_sensor_change_obj = obj
|
49
81
|
@on_sensor_change = Proc.new { |device, obj_ptr, index, value|
|
50
|
-
|
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
|
-
|
63
|
-
|
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
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
@
|
85
|
-
|
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
|
-
|
116
|
+
public
|
105
117
|
|
106
|
-
|
107
|
-
|
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
|
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
|
-
|
121
|
-
|
153
|
+
private
|
122
154
|
def initialize(handle, index)
|
123
155
|
@handle, @index = handle, index.to_i
|
124
156
|
end
|
125
157
|
|
126
|
-
|
127
|
-
|
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
|
-
|
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
|
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
|
-
|
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}, @
|
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
|
-
|
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
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
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
|
-
|
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.
|
253
|
+
Klass.getDataRate(@handle, @index, ptr)
|
191
254
|
ptr.get_int(0)
|
192
255
|
end
|
193
256
|
|
194
|
-
|
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
|
-
|
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.
|
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
|
-
|
207
|
-
|
303
|
+
@outputs = []
|
304
|
+
ptr.get_int(0).times do |i|
|
305
|
+
@outputs << InterfaceKitOutputs.new(@handle, i)
|
306
|
+
end
|
307
|
+
end
|
208
308
|
|
209
|
-
|
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
|