Class: Firmata::Board
- Inherits:
-
Object
- Object
- Firmata::Board
- Includes:
- EventSpitter
- Defined in:
- lib/firmata/board.rb
Defined Under Namespace
Classes: Pin
Constant Summary collapse
- INPUT =
Public: Fixnum byte for pin mode input.
0x00
- OUTPUT =
Public: Fixnum byte for pin mode output.
0x01
- ANALOG =
Public: Fixnum byte for pin mode analog.
0x02
- PWM =
Public: Fixnum byte for pin mode pulse width modulation.
0x03
- SERVO =
Public: Fixnum byte for pin mode servo.
0x04
- LOW =
0
- HIGH =
1
- REPORT_VERSION =
Internal: Fixnum byte command for protocol version
0xF9
- SYSTEM_RESET =
Internal: Fixnum byte command for system reset
0xFF
- DIGITAL_MESSAGE =
Internal: Fixnum byte command for digital I/O message
0x90
- DIGITAL_MESSAGE_RANGE =
Pubilc: Fixnum byte for range for digital pins for digital 2 byte data format
0x90..0x9F
- ANALOG_MESSAGE =
Internal: Fixnum byte command for an analog I/O message
0xE0
- ANALOG_MESSAGE_RANGE =
Internal: Fixnum byte range for analog pins for analog 14-bit data format
0xE0..0xEF
- REPORT_ANALOG =
Internal: Fixnum byte command to report analog pin
0xC0
- REPORT_DIGITAL =
Internal: Fixnum byte command to report digital port
0xD0
- PIN_MODE =
Internal: Fixnum byte command to set pin mode (I/O)
0xF4
- START_SYSEX =
Internal: Fixnum byte command for start of Sysex message
0xF0
- END_SYSEX =
Internal: Fixnum byte command for end of Sysex message
0xF7
- CAPABILITY_QUERY =
Internal: Fixnum byte sysex command for capabilities query
0x6B
- CAPABILITY_RESPONSE =
Internal: Fixnum byte sysex command for capabilities response
0x6C
- PIN_STATE_QUERY =
Internal: Fixnum byte sysex command for pin state query
0x6D
- PIN_STATE_RESPONSE =
Internal: Fixnum byte sysex command for pin state response
0x6E
- ANALOG_MAPPING_QUERY =
Internal: Fixnum byte sysex command for analog mapping query
0x69
- ANALOG_MAPPING_RESPONSE =
Internal: Fixnum byte sysex command for analog mapping response
0x6A
- FIRMWARE_QUERY =
Internal: Fixnum byte sysex command for firmware query and response
0x79
Instance Attribute Summary collapse
-
#analog_pins ⇒ Object
readonly
Public: Returns the Array of analog pins on Arduino.
-
#firmware_name ⇒ Object
readonly
Public: Returns the String firmware name of Arduion.
-
#pins ⇒ Object
readonly
Public: Returns the Array of pins on Arduino.
-
#serial_port ⇒ Object
readonly
Public: Returns the SerialPort port the Arduino is attached to.
Instance Method Summary collapse
-
#analog_write(pin, value) ⇒ Object
(also: #servo_write)
Public: Write an analog messege.
-
#connect ⇒ Object
Public: Make connection to Arduio.
-
#connected? ⇒ Boolean
Pubilc: Check if a connection to Arduino has been made.
-
#delay(seconds) ⇒ Object
Public: Ask the Arduino to sleep for a number of seconds.
-
#digital_write(pin, value) ⇒ Object
Public: Write a value to a digital pin.
-
#initialize(port) ⇒ Board
constructor
Public: Initialize a Board.
-
#process(data) ⇒ Object
Internal: Process a series of bytes.
-
#query_analog_mapping ⇒ Object
Public: Ask the Arduino which pins (used with pin mode message) correspond to the analog channels.
-
#query_capabilities ⇒ Object
Public: Ask the Arduino about its capabilities and current state.
-
#query_firmware ⇒ Object
Public: Ask the Ardution for its firmware name.
-
#query_pin_state(pin) ⇒ Object
Public: Ask the Arduino for the current configuration of any pin.
-
#read ⇒ Object
Internal: Read data from the underlying serial port.
-
#read_and_process ⇒ Object
Public: Read the serial port and process the results.
-
#report_version ⇒ Object
Public: Ask the Arduino to report its version.
-
#reset ⇒ Object
Public: Send a SYSTEM_RESET to the Arduino.
-
#set_pin_mode(pin, mode) ⇒ Object
Public: Set the mode for a pin.
-
#start_pin_reporting ⇒ Object
Public: Turn pin analog and digital reporting on.
-
#stop_pin_reporting ⇒ Object
Public: Turn pin analog and digital reporting off.
-
#toggle_pin_reporting(state) ⇒ Object
Internal: Toggle the pin analog and digtal reporting off and on.
-
#version ⇒ Object
Public: The major and minor firmware version on the board.
-
#write(*commands) ⇒ Object
Internal: Write data to the underlying serial port.
Constructor Details
#initialize(port) ⇒ Board
Public: Initialize a Board
port - a String port or an Object that responds to read and write.
75 76 77 78 79 80 81 82 83 |
# File 'lib/firmata/board.rb', line 75 def initialize(port) @serial_port = port.is_a?(String) ? SerialPort.new(port, 57600, 8, 1, SerialPort::NONE) : port @serial_port.read_timeout = 2 @major_version = 0 @minor_version = 0 @pins = [] @analog_pins = [] @connected = false end |
Instance Attribute Details
#analog_pins ⇒ Object (readonly)
Public: Returns the Array of analog pins on Arduino.
68 69 70 |
# File 'lib/firmata/board.rb', line 68 def analog_pins @analog_pins end |
#firmware_name ⇒ Object (readonly)
Public: Returns the String firmware name of Arduion.
70 71 72 |
# File 'lib/firmata/board.rb', line 70 def firmware_name @firmware_name end |
#pins ⇒ Object (readonly)
Public: Returns the Array of pins on Arduino.
66 67 68 |
# File 'lib/firmata/board.rb', line 66 def pins @pins end |
#serial_port ⇒ Object (readonly)
Public: Returns the SerialPort port the Arduino is attached to.
64 65 66 |
# File 'lib/firmata/board.rb', line 64 def serial_port @serial_port end |
Instance Method Details
#analog_write(pin, value) ⇒ Object Also known as: servo_write
Public: Write an analog messege.
pin - The Integer pin to write to. value - The Integer value to write to the pin between 0-255.
Returns nothing.
306 307 308 309 |
# File 'lib/firmata/board.rb', line 306 def analog_write(pin, value) @pins[pin].value = value write(ANALOG_MESSAGE | pin, value & 0x7F, (value >> 7) & 0x7F) end |
#connect ⇒ Object
Public: Make connection to Arduio.
Returns Firmata::Board board.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/firmata/board.rb', line 95 def connect unless @connected once('report_version', ->() do once('firmware_query', ->() do once('capability_query', ->() do once('analog_mapping_query', ->() do @connected = true emit('ready') end) query_analog_mapping end) query_capabilities end) end) until connected? read_and_process delay(0.5) end end self end |
#connected? ⇒ Boolean
Pubilc: Check if a connection to Arduino has been made.
Returns Boolean connected state.
88 89 90 |
# File 'lib/firmata/board.rb', line 88 def connected? @connected end |
#delay(seconds) ⇒ Object
Public: Ask the Arduino to sleep for a number of seconds.
seconds - The Integer seconds to sleep for.
Returns nothing.
324 325 326 |
# File 'lib/firmata/board.rb', line 324 def delay(seconds) sleep(seconds) end |
#digital_write(pin, value) ⇒ Object
Public: Write a value to a digital pin.
pin - The Integer pin to write to. value - The value to write (HIGH or LOW).
Returns nothing.
287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/firmata/board.rb', line 287 def digital_write(pin, value) port = (pin / 8).floor port_value = 0 @pins[pin].value = value 8.times do |i| port_value |= (1 << i) unless @pins[8 * port + i].value.zero? end write(DIGITAL_MESSAGE | port, port_value & 0x7F, (port_value >> 7) & 0x7F) end |
#process(data) ⇒ Object
Internal: Process a series of bytes.
data: The String data to process.
Returns nothing.
145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 |
# File 'lib/firmata/board.rb', line 145 def process(data) bytes = StringIO.new(String(data)).bytes bytes.each do |byte| case byte when REPORT_VERSION @major_version = bytes.next @minor_version = bytes.next emit('report_version') when ANALOG_MESSAGE_RANGE least_significant_byte = bytes.next most_significant_byte = bytes.next value = least_significant_byte | (most_significant_byte << 7) pin = byte & 0x0F if analog_pin = analog_pins[pin] pins[analog_pin].value = value end when DIGITAL_MESSAGE_RANGE port = byte & 0x0F first_bitmask = bytes.next second_bitmask = bytes.next port_value = first_bitmask | (second_bitmask << 7) 8.times do |i| pin_number = 8 * port + i if pin = pins[pin_number] and pin.mode == INPUT value = (port_value >> (i & 0x07)) & 0x01 pin.value = value emit('digital-read', pin_number, value) end end when START_SYSEX current_buffer = [byte] begin current_buffer.push(bytes.next) end until current_buffer.last == END_SYSEX command = current_buffer[1] case command when CAPABILITY_RESPONSE supportedModes = 0 n = 0 current_buffer.slice(2, current_buffer.length - 3).each do |byte| if byte == 127 modesArray = [] # the pin modes [ INPUT, OUTPUT, ANALOG, PWM, SERVO ].each do |mode| modesArray.push(mode) unless (supportedModes & (1 << mode)).zero? end @pins.push(Pin.new(modesArray, OUTPUT, 0)) supportedModes = 0 n = 0 next end supportedModes |= (1 << byte) if n.zero? n ^= 1 end emit('capability_query') when ANALOG_MAPPING_RESPONSE pin_index = 0 current_buffer.slice(2, current_buffer.length - 3).each do |byte| @pins[pin_index].analog_channel = byte @analog_pins.push(pin_index) unless byte == 127 pin_index += 1 end emit('analog_mapping_query') when PIN_STATE_RESPONSE pin = pins[current_buffer[2]] pin.mode = current_buffer[3] pin.value = current_buffer[4] pin.value |= (current_buffer[5] << 7) if current_buffer.size > 6 pin.value |= (current_buffer[6] << 14) if current_buffer.size > 7 when FIRMWARE_QUERY @firmware_name = current_buffer.slice(4, current_buffer.length - 5).reject { |b| b.zero? }.map(&:chr).join emit('firmware_query') else puts 'bad byte' end end end rescue StopIteration # do nadda end |
#query_analog_mapping ⇒ Object
Public: Ask the Arduino which pins (used with pin mode message) correspond to the analog channels.
Returns nothing.
369 370 371 |
# File 'lib/firmata/board.rb', line 369 def query_analog_mapping write(START_SYSEX, ANALOG_MAPPING_QUERY, END_SYSEX) end |
#query_capabilities ⇒ Object
Public: Ask the Arduino about its capabilities and current state.
Returns nothing.
362 363 364 |
# File 'lib/firmata/board.rb', line 362 def query_capabilities write(START_SYSEX, CAPABILITY_QUERY, END_SYSEX) end |
#query_firmware ⇒ Object
Public: Ask the Ardution for its firmware name.
Returns nothing.
346 347 348 |
# File 'lib/firmata/board.rb', line 346 def query_firmware write(FIRMWARE_QUERY) end |
#query_pin_state(pin) ⇒ Object
Public: Ask the Arduino for the current configuration of any pin.
pin - The Integer pin to query on the board.
Returns nothing.
355 356 357 |
# File 'lib/firmata/board.rb', line 355 def query_pin_state(pin) write(START_SYSEX, PIN_STATE_QUERY, pin.to_i, END_SYSEX) end |
#read ⇒ Object
Internal: Read data from the underlying serial port.
Returns String data read for serial port.
135 136 137 138 |
# File 'lib/firmata/board.rb', line 135 def read serial_port.read_nonblock(4096) rescue EOFError end |
#read_and_process ⇒ Object
Public: Read the serial port and process the results
Returns nothing.
255 256 257 |
# File 'lib/firmata/board.rb', line 255 def read_and_process process(read) end |
#report_version ⇒ Object
Public: Ask the Arduino to report its version.
Returns nothing.
339 340 341 |
# File 'lib/firmata/board.rb', line 339 def report_version write(REPORT_VERSION) end |
#reset ⇒ Object
Public: Send a SYSTEM_RESET to the Arduino
Returns nothing.
262 263 264 |
# File 'lib/firmata/board.rb', line 262 def reset write(SYSTEM_RESET) end |
#set_pin_mode(pin, mode) ⇒ Object
Public: Set the mode for a pin.
pin - The Integer pin to set. mode - The Fixnum mode (INPUT, OUTPUT, ANALOG, PWM or SERVO)
Examples
set_pin_mode(13, OUTPUT)
Returns nothing.
276 277 278 279 |
# File 'lib/firmata/board.rb', line 276 def set_pin_mode(pin, mode) pins[pin].mode = mode write(PIN_MODE, pin, mode) end |
#start_pin_reporting ⇒ Object
Public: Turn pin analog and digital reporting on.
Returns nothing.
389 390 391 |
# File 'lib/firmata/board.rb', line 389 def start_pin_reporting toggle_pin_reporting(1) end |
#stop_pin_reporting ⇒ Object
Public: Turn pin analog and digital reporting off.
Returns nothing.
396 397 398 |
# File 'lib/firmata/board.rb', line 396 def stop_pin_reporting toggle_pin_reporting(0) end |
#toggle_pin_reporting(state) ⇒ Object
Internal: Toggle the pin analog and digtal reporting off and on.
state - The Integer to turn the pin on (1) or off (0).
Returns nothing.
379 380 381 382 383 384 |
# File 'lib/firmata/board.rb', line 379 def toggle_pin_reporting(state) 16.times do |i| write(REPORT_DIGITAL | i, state) write(REPORT_ANALOG | i, state) end end |
#version ⇒ Object
Public: The major and minor firmware version on the board. Will report as “0.0” if report_version command has not been run.
Returns String the firmware version as “minor.major”.
332 333 334 |
# File 'lib/firmata/board.rb', line 332 def version [@major_version, @minor_version].join('.') end |
#write(*commands) ⇒ Object
Internal: Write data to the underlying serial port.
commands - Zero or more byte commands to be written.
Examples
write(START_SYSEX, CAPABILITY_QUERY, END_SYSEX)
Returns nothing.
128 129 130 |
# File 'lib/firmata/board.rb', line 128 def write(*commands) serial_port.write_nonblock(commands.map(&:chr).join) end |