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
@@ -0,0 +1,87 @@
1
+ require 'rubygems'
2
+ require 'phidgets-ffi'
3
+
4
+ puts "Library Version: #{Phidgets::FFI.library_version}"
5
+
6
+ st = Phidgets::Stepper.new
7
+
8
+ puts "Wait for PhidgetStepper to attached..."
9
+
10
+ #The following method runs when the PhidgetStepper is attached to the system
11
+ st.on_attach do |device, obj|
12
+
13
+ puts "Device attributes: #{device.attributes} attached"
14
+ puts "Class: #{device.device_class}"
15
+ puts "Id: #{device.id}"
16
+ puts "Serial number: #{device.serial_number}"
17
+ puts "Version: #{device.version}"
18
+ puts "# Inputs: #{device.inputs.size}"
19
+ puts "# Steppers: #{device.steppers.size}"
20
+
21
+ puts "Digital input[0] state: #{device.inputs[0].state}"
22
+
23
+ device.steppers[0].engaged = true
24
+
25
+ device.steppers[0].acceleration = (device.steppers[0].acceleration_min) * 2
26
+ device.steppers[0].velocity_limit = (device.steppers[0].velocity_max) / 2
27
+
28
+ begin
29
+ puts "Stepper 0: Current Position: #{device.steppers[0].current_position}"
30
+ rescue Phidgets::Error::UnknownVal => e
31
+ puts "Exception caught: #{e.message}"
32
+ end
33
+
34
+ end
35
+
36
+ st.on_detach do |device, obj|
37
+ puts "#{device.attributes.inspect} detached"
38
+ end
39
+
40
+ st.on_error do |device, obj, code, description|
41
+ puts "Error #{code}: #{description}"
42
+ end
43
+
44
+ st.on_input_change do |device, input, state, obj|
45
+ print "Input #{input.index}'s state has changed to #{state}\n"
46
+ end
47
+
48
+ st.on_velocity_change do |device, stepper, velocity, obj|
49
+ puts "Stepper #{stepper.index}'s velocity has changed to #{velocity}"
50
+ end
51
+
52
+ st.on_position_change do |device, stepper, position, obj|
53
+ puts "Stepper #{stepper.index}'s position has changed to #{position}"
54
+ end
55
+
56
+ st.on_current_change do |device, stepper, current, obj|
57
+ puts "Stepper #{stepper.index}'s current has changed to #{current}"
58
+ end
59
+
60
+ sleep 5
61
+
62
+ if(st.attached?)
63
+ sleep 2
64
+
65
+ puts 'Moving to position 200'
66
+ st.steppers[0].target_position = 200
67
+ sleep 2
68
+
69
+ puts 'Moving to position 1200'
70
+ st.steppers[0].target_position = 1200
71
+ sleep 2
72
+
73
+ puts 'Moving to position 0'
74
+ st.steppers[0].target_position = 0
75
+ sleep 2
76
+
77
+ if (st.steppers[0].stopped == true)
78
+ puts 'Stepper 0 has stopped'
79
+ else
80
+ puts 'Stepper 0 has not stopped yet'
81
+ end
82
+
83
+ st.steppers[0].engaged = false
84
+ end
85
+
86
+ sleep 1
87
+ st.close
@@ -0,0 +1,49 @@
1
+ require 'rubygems'
2
+ require 'phidgets-ffi'
3
+
4
+ puts "Library Version: #{Phidgets::FFI.library_version}"
5
+
6
+ temp = Phidgets::TemperatureSensor.new
7
+
8
+ puts "Wait for PhidgetTemperatureSensor to attached..."
9
+
10
+ #The following method runs when the PhidgetTemperatureSensor is attached to the system
11
+ temp.on_attach do |device, obj|
12
+
13
+ puts "Device attributes: #{device.attributes} attached"
14
+ puts "Class: #{device.device_class}"
15
+ puts "Id: #{device.id}"
16
+ puts "Serial number: #{device.serial_number}"
17
+ puts "Version: #{device.version}"
18
+ puts "# Inputs: #{device.thermocouples.size}"
19
+
20
+ begin
21
+ puts temp.thermocouples[0].inspect
22
+ temp.thermocouples[0].sensitivity = 0.02
23
+ puts "Thermocouple Type: #{temp.thermocouples[0].type = Phidgets::FFI::TemperatureSensorThermocoupleTypes[:thermocouple_type_k_type]}"
24
+ sleep 1
25
+ puts "Temperature min: #{temp.thermocouples[0].temperature_min} degrees celcius"
26
+ puts "Temperature max: #{temp.thermocouples[0].temperature_max} degrees celcius"
27
+ puts "Temperature[0]: #{temp.thermocouples[0].temperature} degrees celcius"
28
+ puts ''
29
+ rescue Phidgets::Error::UnknownVal => e
30
+ puts "Exception caught: #{e.message}"
31
+ end
32
+
33
+ end
34
+
35
+ temp.on_detach do |device, obj|
36
+ puts "#{device.attributes.inspect} detached"
37
+ end
38
+
39
+ temp.on_error do |device, obj, code, description|
40
+ puts "Error #{code}: #{description}"
41
+ end
42
+
43
+ temp.on_temperature_change do |device, input, temperature, obj|
44
+ puts "Input #{input.index}'s temperature changed to #{temperature}"
45
+ end
46
+
47
+ sleep 5
48
+
49
+ temp.close
@@ -0,0 +1,101 @@
1
+ require 'rubygems'
2
+ require 'phidgets-ffi'
3
+
4
+ puts "Library Version: #{Phidgets::FFI.library_version}"
5
+
6
+ lcd = Phidgets::TextLCD.new
7
+
8
+ puts "Wait for PhidgetTextLCD to attached..."
9
+
10
+ #The following method runs when the PhidgetTextLCD is attached to the system
11
+ lcd.on_attach do |device, obj|
12
+
13
+ puts "Device attributes: #{device.attributes} attached"
14
+ puts "Class: #{device.device_class}"
15
+ puts "Id: #{device.id}"
16
+ puts "Serial number: #{device.serial_number}"
17
+ puts "Version: #{device.version}"
18
+ puts "# Screens: #{device.screens.size}"
19
+
20
+ puts "Device attributes: #{device.attributes} attached"
21
+ puts "Class: #{device.device_class}"
22
+ puts "Id: #{device.id}"
23
+ puts "Serial number: #{device.serial_number}"
24
+ puts "Version: #{device.version}"
25
+ puts "# screens: #{device.screens.size}"
26
+
27
+ if(lcd.id.to_s == "textlcd_adapter") #the TextLCD Adapter supports screen_size and initialize_screen
28
+ device.screens[0].screen_size = Phidgets::FFI::TextLCDScreenSizes[:screen_size_2x8]
29
+ device.screens[0].initialize_screen
30
+ device.screens[1].initialize_screen
31
+ end
32
+
33
+ sleep 1
34
+
35
+ device.screens[0].contrast = 100
36
+ device.screens[0].back_light = true
37
+ device.screens[0].cursor = true
38
+ device.screens[0].cursor_blink = true
39
+ sleep 1
40
+
41
+ puts device.screens[0].inspect
42
+
43
+ end
44
+
45
+ lcd.on_detach do |device, obj|
46
+ puts "#{device.attributes.inspect} detached"
47
+ end
48
+
49
+ lcd.on_error do |device, obj, code, description|
50
+ puts "Error #{code}: #{description}"
51
+ end
52
+
53
+ sleep 2
54
+
55
+ if(lcd.attached?)
56
+
57
+ sleep 3
58
+
59
+ puts "Screen 0, # rows: #{lcd.screens[0].rows.size}"
60
+ puts "Screen 0, # columns: #{lcd.screens[0].rows[0].maximum_length}"
61
+
62
+ puts 'Displaying row number'
63
+ lcd.screens[0].rows.size.times do |i|
64
+ lcd.screens[0].rows[i].display_string = "Row #{i}"
65
+ end
66
+
67
+ sleep 3
68
+ #Switching screens if supported
69
+ if(lcd.id.to_s == "textlcd_adapter")
70
+ puts 'Switching to the next screen'
71
+ lcd.screens[1].screen_size = Phidgets::FFI::TextLCDScreenSizes[:screen_size_2x16]
72
+ lcd.screens[1].cursor_blink = true
73
+ lcd.screens[1].rows[0].display_string = "Screen #2"
74
+ end
75
+
76
+ sleep 3
77
+ #Storing 7 custom characters as well as displaying them.
78
+ puts 'Displaying custom characters'
79
+ lcd.custom_characters[0].set_custom_character(949247, 536)
80
+ lcd.custom_characters[1].set_custom_character(1015791, 17180)
81
+ lcd.custom_characters[2].set_custom_character(1048039, 549790)
82
+ lcd.custom_characters[3].set_custom_character(1031395, 816095)
83
+ lcd.custom_characters[4].set_custom_character(498785, 949247)
84
+ lcd.custom_characters[5].set_custom_character(232480, 1015791)
85
+ lcd.custom_characters[6].set_custom_character(99328, 1048039)
86
+ lcd.screens[0].rows[0].display_string = "#{lcd.custom_characters[0].string_code}#{lcd.custom_characters[1].string_code}#{lcd.custom_characters[2].string_code}#{lcd.custom_characters[3].string_code}#{lcd.custom_characters[4].string_code}#{lcd.custom_characters[5].string_code}#{lcd.custom_characters[6].string_code}"
87
+
88
+ sleep 3
89
+
90
+ #Display 'Hello' with ASCII Code(hexadecimal)
91
+ puts 'Displaying characters in ASCII code'
92
+ lcd.screens[0].rows[1].display_string = "\x48\x65\x6c\x6c\x6f"
93
+
94
+
95
+ #Displays a single character for a specific column for a row
96
+ lcd.screens[0].rows[1].display_character(5, 0x21) #hex code for exclamation mark in ASCII
97
+
98
+ end
99
+
100
+ sleep 5
101
+ lcd.close
data/lib/phidgets-ffi.rb CHANGED
@@ -1,18 +1,49 @@
1
1
  require 'ffi'
2
2
  require 'phidgets-ffi/phidgets-ffi'
3
+
3
4
  require 'phidgets-ffi/ffi/core_ext'
4
5
  require 'phidgets-ffi/ffi/constants'
5
6
  require 'phidgets-ffi/ffi/common'
6
7
  require 'phidgets-ffi/ffi/dictionary'
7
8
  require 'phidgets-ffi/ffi/manager'
8
9
  require 'phidgets-ffi/ffi/log'
9
- require 'phidgets-ffi/ffi/servo'
10
+ require 'phidgets-ffi/ffi/accelerometer'
11
+ require 'phidgets-ffi/ffi/advanced_servo'
12
+ require 'phidgets-ffi/ffi/analog'
13
+ require 'phidgets-ffi/ffi/bridge'
14
+ require 'phidgets-ffi/ffi/encoder'
15
+ require 'phidgets-ffi/ffi/frequency_counter'
16
+ require 'phidgets-ffi/ffi/gps'
10
17
  require 'phidgets-ffi/ffi/interface_kit'
18
+ require 'phidgets-ffi/ffi/ir'
19
+ require 'phidgets-ffi/ffi/led'
20
+ require 'phidgets-ffi/ffi/motor_control'
21
+ require 'phidgets-ffi/ffi/rfid'
22
+ require 'phidgets-ffi/ffi/servo'
23
+ require 'phidgets-ffi/ffi/spatial'
24
+ require 'phidgets-ffi/ffi/stepper'
25
+ require 'phidgets-ffi/ffi/temperature_sensor'
26
+ require 'phidgets-ffi/ffi/text_lcd'
11
27
 
12
28
  require 'phidgets-ffi/common'
13
29
  require 'phidgets-ffi/log'
14
30
  require 'phidgets-ffi/dictionary'
15
- require 'phidgets-ffi/error'
16
31
  require 'phidgets-ffi/manager'
32
+ require 'phidgets-ffi/error'
33
+ require 'phidgets-ffi/accelerometer'
34
+ require 'phidgets-ffi/advanced_servo'
35
+ require 'phidgets-ffi/analog'
36
+ require 'phidgets-ffi/bridge'
37
+ require 'phidgets-ffi/encoder'
38
+ require 'phidgets-ffi/frequency_counter'
39
+ require 'phidgets-ffi/gps'
40
+ require 'phidgets-ffi/interface_kit'
41
+ require 'phidgets-ffi/ir'
42
+ require 'phidgets-ffi/led'
43
+ require 'phidgets-ffi/motor_control'
44
+ require 'phidgets-ffi/rfid'
17
45
  require 'phidgets-ffi/servo'
18
- require 'phidgets-ffi/interface_kit'
46
+ require 'phidgets-ffi/spatial'
47
+ require 'phidgets-ffi/stepper'
48
+ require 'phidgets-ffi/temperature_sensor'
49
+ require 'phidgets-ffi/text_lcd'
@@ -0,0 +1,122 @@
1
+ module Phidgets
2
+
3
+ # This class represents a PhidgetAccelerometer.
4
+ class Accelerometer
5
+
6
+ Klass = Phidgets::FFI::CPhidgetAccelerometer
7
+ include Phidgets::Common
8
+
9
+ # Collection of accelerometer axes
10
+ # @return [AccelerometerAxes]
11
+ attr_reader :axes
12
+
13
+ attr_reader :attributes
14
+
15
+ # The attributes of a PhidgetAccelerometer
16
+ def attributes
17
+ super.merge({
18
+ :axes => axes.size
19
+ })
20
+ end
21
+
22
+ # Sets an acceleration change handler callback function. This is called when the acceleration of an axis changes by more than the set sensitivity.
23
+ #
24
+ # @param [String] obj Object to pass to the callback function. This is optional.
25
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
26
+ # @example
27
+ # acc.on_acceleration_change do |device, axis, acceleration, obj|
28
+ # puts "Axis #{axis.index}'s acceleration changed to #{acceleration}"
29
+ # end
30
+ # 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.
31
+ # @return [Boolean] returns true or raises an error
32
+ def on_acceleration_change(obj=nil, &block)
33
+ @on_acceleration_change_obj = obj
34
+ @on_acceleration_change = Proc.new { |device, obj_ptr, ind, acc|
35
+ yield self, axes[ind], acc, object_for(obj_ptr)
36
+ }
37
+ Klass.set_OnAccelerationChange_Handler(@handle, @on_acceleration_change, pointer_for(obj))
38
+ end
39
+
40
+ private
41
+
42
+ def load_device_attributes
43
+ load_axes
44
+ end
45
+
46
+ def load_axes
47
+
48
+ ptr = ::FFI::MemoryPointer.new(:int)
49
+ Klass.getAxisCount(@handle, ptr)
50
+ @axes = []
51
+ ptr.get_int(0).times do |i|
52
+ @axes << AccelerometerAxes.new(@handle, i)
53
+ end
54
+
55
+ end
56
+
57
+ def remove_specific_event_handlers
58
+ Klass.set_OnAccelerationChange_Handler(@handle, nil, nil)
59
+ end
60
+
61
+ # This class represents an axis of acceleration for a PhidgetAccelerometer. All the properties of an accelerometer axis are stored and modified in this class.
62
+ class AccelerometerAxes
63
+ Klass = Phidgets::FFI::CPhidgetAccelerometer
64
+
65
+ private
66
+ def initialize(handle, index)
67
+ @handle, @index = handle, index.to_i
68
+ end
69
+
70
+ public
71
+
72
+ # Displays data for the axis
73
+ def inspect
74
+ "#<#{self.class} @acceleration=#{acceleration}, @acceleration_max=#{acceleration_max}, @acceleration_min=#{acceleration_min}, @sensitivity=#{sensitivity}>"
75
+ end
76
+
77
+ # @return [Integer] returns index of the axis, or raises an error.
78
+ def index
79
+ @index
80
+ end
81
+
82
+ # @return [Float] returns the acceleration value of the axis, or raises an error.
83
+ def acceleration
84
+ ptr = ::FFI::MemoryPointer.new(:double)
85
+ Klass.getAcceleration(@handle, @index, ptr)
86
+ ptr.get_double(0)
87
+ end
88
+
89
+ # @return [Float] returns the largest acceleration value that the axis will return, or raises an error.
90
+ def acceleration_max
91
+ ptr = ::FFI::MemoryPointer.new(:double)
92
+ Klass.getAccelerationMax(@handle, @index, ptr)
93
+ ptr.get_double(0)
94
+ end
95
+
96
+ # @return [Float] returns the largest(negative) acceleration value that the axis will return, or raises an error.
97
+ def acceleration_min
98
+ ptr = ::FFI::MemoryPointer.new(:double)
99
+ Klass.getAccelerationMin(@handle, @index, ptr)
100
+ ptr.get_double(0)
101
+ end
102
+
103
+ # Sets the sensitivity of the acceleration data for the axis, or raises an error.
104
+ # @param [Float] new_sensitivity new sensitivity
105
+ # @return [Float] returns sensitivity of the acceleration data for the axis, or raises an error.
106
+ def sensitivity=(new_sensitivity)
107
+ Klass.setAccelerationChangeTrigger(@handle, @index, new_sensitivity.to_f)
108
+ new_sensitivity.to_f
109
+ end
110
+
111
+ # @return [Float] returns sensitivity of the acceleration data for the axis, or raises an error.
112
+ def sensitivity
113
+ ptr = ::FFI::MemoryPointer.new(:double)
114
+ Klass.getAccelerationChangeTrigger(@handle, @index, ptr)
115
+ ptr.get_double(0)
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+ end
122
+
@@ -0,0 +1,304 @@
1
+ module Phidgets
2
+
3
+ # This class represents a PhidgetAdvancedServo.
4
+ class AdvancedServo
5
+
6
+ Klass = Phidgets::FFI::CPhidgetAdvancedServo
7
+ include Phidgets::Common
8
+
9
+ # Collection of servo motors
10
+ # @return [AdvancedServoServos]
11
+ attr_reader :advanced_servos
12
+
13
+ attr_reader :attributes
14
+
15
+ # The attributes of a PhidgetAdvancedServo
16
+ def attributes
17
+ super.merge({
18
+ :advanced_servos => advanced_servos.size,
19
+ })
20
+ end
21
+
22
+ # Sets a velocity change handler callback function. This is called when the velocity of a servo changes.
23
+ #
24
+ # @param [String] obj Object to pass to the callback function. This is optional.
25
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
26
+ # @example
27
+ # adv.on_velocity_change do |device, servo, velocity, obj|
28
+ # puts "Servo #{servo.index}'s velocity has changed to #{velocity}"
29
+ # end
30
+ # 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.
31
+ # @return [Boolean] returns true or raises an error
32
+ def on_velocity_change(obj=nil, &block)
33
+
34
+ @on_velocity_change_obj = obj
35
+ @on_velocity_change = Proc.new { |device, obj_ptr, index, velocity|
36
+ yield self, @advanced_servos[index], velocity, object_for(obj_ptr)
37
+ }
38
+ Klass.set_OnVelocityChange_Handler(@handle, @on_velocity_change, pointer_for(obj))
39
+ end
40
+
41
+ # Sets a position change handler callback function. This is called when the servo position has changed.
42
+ #
43
+ # @param [String] obj Object to pass to the callback function. This is optional.
44
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
45
+ # @example
46
+ # adv.on_position_change do |device, servo, position, obj|
47
+ # puts "Servo #{servo.index}'s position has changed to #{position}"
48
+ # end
49
+ # 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.
50
+ # @return [Boolean] returns true or raises an error
51
+ def on_position_change(obj=nil, &block)
52
+
53
+ @on_position_change_obj = obj
54
+ @on_position_change = Proc.new { |device, obj_ptr, index, position|
55
+ yield self, @advanced_servos[index], position, object_for(obj_ptr)
56
+ }
57
+ Klass.set_OnPositionChange_Handler(@handle, @on_position_change, pointer_for(obj))
58
+ end
59
+
60
+ # Sets a current change handler handler callback function. This is called when the current consumed by a motor changes.
61
+ #
62
+ # @param [String] obj Object to pass to the callback function. This is optional.
63
+ # @param [Proc] Block When the callback is executed, the device and object are yielded to this block.
64
+ # @example
65
+ # adv.on_current_change do |device, servo, current, obj|
66
+ # puts "Servo #{servo.index}'s current has changed to #{current}"
67
+ # end
68
+ # 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.
69
+ # @return [Boolean] returns true or raises an error
70
+ def on_current_change(obj=nil, &block)
71
+
72
+ @on_current_change_obj = obj
73
+ @on_current_change = Proc.new { |device, obj_ptr, index, current|
74
+ yield self, @advanced_servos[index], current, object_for(obj_ptr)
75
+ }
76
+ Klass.set_OnCurrentChange_Handler(@handle, @on_current_change, pointer_for(obj))
77
+ end
78
+
79
+
80
+ # This class represents a servo motor for a PhidgetAdvancedServo. All the properties of an servo motor are stored and modified in this class.
81
+ class AdvancedServoServos
82
+ Klass = Phidgets::FFI::CPhidgetAdvancedServo
83
+
84
+ private
85
+ def initialize(handle, index)
86
+ @handle, @index = handle, index.to_i
87
+ end
88
+
89
+ public
90
+ # Displays data for the servo motor.
91
+ def inspect
92
+ "#<#{self.class} @index=#{index}, @acceleration=#{acceleration}, @acceleration_min=#{acceleration_min}, @acceleration_max=#{acceleration_max}, @current=#{current}, @engaged=#{engaged}, @position=#{position}, @position_max=#{position_max}, @position_min=#{position_min}, @speed_ramping=#{speed_ramping}, @stopped=#{stopped}, @type=#{type}, @velocity=#{velocity}, @velocity_limit=#{velocity_limit}, @velocity_min=#{velocity_min}, @velocity_max=#{velocity_max}>"
93
+ end
94
+
95
+ # @return [Integer] returns the index of the servo motor, or raises an error.
96
+ def index
97
+ @index
98
+ end
99
+
100
+ # @return [Float] returns the acceleration of a servo, in degrees/second, or raises an error.
101
+ def acceleration
102
+ ptr = ::FFI::MemoryPointer.new(:double)
103
+ Klass.getAcceleration(@handle, @index, ptr)
104
+ ptr.get_double(0)
105
+ end
106
+
107
+ # Sets the acceleration of a servo, in degrees/second, or raises an error.
108
+ # @param [Integer] new_acceleration new acceleration
109
+ # @return [Float] returns acceleration of a servo, in degrees/second, or raises an error.
110
+ def acceleration=(new_acceleration)
111
+ Klass.setAcceleration(@handle, @index, new_acceleration.to_f)
112
+ new_acceleration
113
+ end
114
+
115
+ # @return [Float] returns the largest acceleration value that the servo motor will accept, or raises an error.
116
+ def acceleration_max
117
+ ptr = ::FFI::MemoryPointer.new(:double)
118
+ Klass.getAccelerationMax(@handle, @index, ptr)
119
+ ptr.get_double(0)
120
+ end
121
+
122
+ # @return [Float] returns the smallest acceleration value that the servo motor will accept, or raises an error.
123
+ def acceleration_min
124
+ ptr = ::FFI::MemoryPointer.new(:double)
125
+ Klass.getAccelerationMin(@handle, @index, ptr)
126
+ ptr.get_double(0)
127
+ end
128
+
129
+ # @return [Float] returns the current consumption of a servo motor, in Amps, or raises an error.
130
+ def current
131
+ ptr = ::FFI::MemoryPointer.new(:double)
132
+ Klass.getCurrent(@handle, @index, ptr)
133
+ ptr.get_double(0)
134
+ end
135
+
136
+ # @return [Boolean] returns the engaged state of a servo motor, or raises an error.
137
+ def engaged
138
+ ptr = ::FFI::MemoryPointer.new(:int)
139
+ Klass.getEngaged(@handle, @index, ptr)
140
+ (ptr.get_int(0) == 0) ? false : true
141
+ end
142
+
143
+ # Sets the engaged state of a servo motor, or raises an error.
144
+ # @param [Boolean] new_state new state
145
+ # @return [Boolean] returns engaged state of a servo motor, or raises an error.
146
+ def engaged=(new_state)
147
+ tmp = new_state ? 1 : 0
148
+ Klass.setEngaged(@handle, @index, tmp)
149
+ new_state
150
+ end
151
+
152
+ # @return [Float] returns the position of the servo motor, in degrees, or raises an error.
153
+ def position
154
+ ptr = ::FFI::MemoryPointer.new(:double)
155
+ Klass.getPosition(@handle, @index, ptr)
156
+ ptr.get_double(0)
157
+ end
158
+
159
+ # Sets the position of the servo motor, in degrees, or raises an error.
160
+ # @param [Float] new_position new position
161
+ # @return [Float] returns the position of the servo motor, in degrees, or raises an error.
162
+ def position=(new_position)
163
+ Klass.setPosition(@handle, @index, new_position.to_f)
164
+ new_position
165
+ end
166
+
167
+ # @return [Float] returns the largest position value that the servo motor will accept, or raises an error.
168
+ def position_max
169
+ ptr = ::FFI::MemoryPointer.new(:double)
170
+ Klass.getPositionMax(@handle, @index, ptr)
171
+ ptr.get_double(0)
172
+ end
173
+
174
+ # Sets the largest position value that the servo motor will accept, or raises an error.
175
+ # @param [Float] new_position_max new maximum position
176
+ # @return [Float] returns the largest position value that the servo motor will accept, or raises an error.
177
+ def position_max=(new_position_max)
178
+ Klass.setPositionMax(@handle, @index, new_position_max.to_f)
179
+ new_position_max
180
+ end
181
+
182
+ # @return [Float] returns the smallest position value that the servo motor will accept, or raises an error.
183
+ def position_min
184
+ ptr = ::FFI::MemoryPointer.new(:double)
185
+ Klass.getPositionMin(@handle, @index, ptr)
186
+ ptr.get_double(0)
187
+ end
188
+
189
+ # Sets the smallest position value that the servo motor will accept, or raises an error.
190
+ # @param [Float] new_position_min new minimum position
191
+ # @return [Float] returns the smallest position value that the servo motor will accept, or raises an error.
192
+ def position_min=(new_position_min)
193
+ Klass.setPositionMin(@handle, @index, new_position_min.to_f)
194
+ new_position_min
195
+ end
196
+
197
+ # @return [Boolean] returns the speed ramping state of the servo motor, or raises an error.
198
+ def speed_ramping
199
+ ptr = ::FFI::MemoryPointer.new(:int)
200
+ Klass.getSpeedRampingOn(@handle, @index, ptr)
201
+ (ptr.get_int(0) == 0) ? false : true
202
+ end
203
+
204
+ # Sets the speed ramping state that the servo motor will accept, or raises an error.
205
+ # @param [Boolean] new_state new state
206
+ # @return [Boolean] returns the speed ramping state that the servo motor will accept, or raises an error.
207
+ def speed_ramping=(new_state)
208
+ tmp = new_state ? 1 : 0
209
+ Klass.setSpeedRampingOn(@handle, @index, tmp)
210
+ new_state
211
+ end
212
+
213
+ # @return [Boolean] returns the stopped state of the servo motor, or raises an error.
214
+ def stopped
215
+ ptr = ::FFI::MemoryPointer.new(:int)
216
+ Klass.getStopped(@handle, @index, ptr)
217
+ (ptr.get_int(0) == 0) ? false : true
218
+ end
219
+
220
+ # @return [Phidgets::FFI::AdvancedServoType] returns the servo type of the servo motor, or raises an error.
221
+ def type
222
+ ptr = ::FFI::MemoryPointer.new(:int)
223
+ Klass.getServoType(@handle, @index, ptr)
224
+ Phidgets::FFI::ServoType[ptr.get_int(0)]
225
+ end
226
+
227
+ # Sets the servo type of the servo motor, or raises an error. This determines how degrees are calculated from PCM pulses, and sets min and max angles. The default type is :default.
228
+ # @param [Phidgets::FFI::AdvancedServoType] new_type new type
229
+ # @return [Phidgets::FFI::AdvancedServoType] returns the servo type of the servo motor, or raises an error.
230
+ def type=(new_type=:default)
231
+ ptr = ::FFI::MemoryPointer.new(:int)
232
+ Klass.setServoType(@handle, @index, Phidgets::FFI::AdvancedServoType[new_type])
233
+ new_type
234
+ end
235
+
236
+ # @return [Float] returns the current velocity of the servo motor, or raises an error.
237
+ def velocity
238
+ ptr = ::FFI::MemoryPointer.new(:double)
239
+ Klass.getVelocity(@handle, @index, ptr)
240
+ ptr.get_double(0)
241
+ end
242
+
243
+ # @return [Float] returns the velocity limit of the servo motor, or raises an error.
244
+ def velocity_limit
245
+ ptr = ::FFI::MemoryPointer.new(:double)
246
+ Klass.getVelocityLimit(@handle, @index, ptr)
247
+ ptr.get_double(0)
248
+ end
249
+
250
+ # Sets the velocity limit of the servo motor, or raises an error.
251
+ # @param [Float] new_velocity_limit new velocity limit
252
+ # @return [Float] returns the velocity limit of the servo motor, or raises an error.
253
+ def velocity_limit=(new_velocity_limit)
254
+ Klass.setVelocityLimit(@handle, @index, new_velocity_limit.to_f)
255
+ new_velocity_limit
256
+ end
257
+
258
+ # @return [Float] returns the largest velocity value that the servo motor will accept, or raises an error.
259
+ def velocity_max
260
+ ptr = ::FFI::MemoryPointer.new(:double)
261
+ Klass.getVelocityMax(@handle, @index, ptr)
262
+ ptr.get_double(0)
263
+ end
264
+
265
+ # @return [Float] returns the smallest velocity value that the servo motor will accept, or raises an error.
266
+ def velocity_min
267
+ ptr = ::FFI::MemoryPointer.new(:double)
268
+ Klass.getVelocityMin(@handle, @index, ptr)
269
+ ptr.get_double(0)
270
+ end
271
+
272
+ # Sets custom servo parameters for using a servo not in the predefined list. Pulse widths are specified in microseconds, velocity in degrees/second.
273
+ # @return [Boolean] returns the true if the servo parameters has successfully been set, or raises an error.
274
+ def set_servo_parameters(min_us, max_us, degrees, velocity_max)
275
+ Klass.setServoParameters(@handle, @index, min_us, max_us, degrees, velocity_max)
276
+ true
277
+ end
278
+
279
+ end #AdvancedServoServos
280
+
281
+ private
282
+
283
+ def load_device_attributes
284
+ load_advanced_servos
285
+ end
286
+
287
+ def load_advanced_servos
288
+ ptr = ::FFI::MemoryPointer.new(:int)
289
+ Klass.getMotorCount(@handle, ptr)
290
+ @advanced_servos = []
291
+ ptr.get_int(0).times do |i|
292
+ @advanced_servos << AdvancedServoServos.new(@handle, i)
293
+ end
294
+
295
+ end
296
+
297
+ def remove_specific_event_handlers
298
+ Klass.set_OnPositionChange_Handler(@handle, nil, nil)
299
+ Klass.set_OnVelocityChange_Handler(@handle, nil, nil)
300
+ Klass.set_OnCurrentChange_Handler(@handle, nil, nil)
301
+ end
302
+ end
303
+
304
+ end