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 Arduino.
-
#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.
-
#toggle_pin_reporting(pin, state = HIGH, mode = REPORT_DIGITAL) ⇒ Object
Public: Toggle pin reporting on or off.
-
#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.
76 77 78 79 80 81 82 83 84 |
# File 'lib/firmata/board.rb', line 76 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.
69 70 71 |
# File 'lib/firmata/board.rb', line 69 def analog_pins @analog_pins end |
#firmware_name ⇒ Object (readonly)
Public: Returns the String firmware name of Arduion.
71 72 73 |
# File 'lib/firmata/board.rb', line 71 def firmware_name @firmware_name end |
#pins ⇒ Object (readonly)
Public: Returns the Array of pins on Arduino.
67 68 69 |
# File 'lib/firmata/board.rb', line 67 def pins @pins end |
#serial_port ⇒ Object (readonly)
Public: Returns the SerialPort port the Arduino is attached to.
65 66 67 |
# File 'lib/firmata/board.rb', line 65 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.
314 315 316 317 |
# File 'lib/firmata/board.rb', line 314 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 Arduino.
Returns Firmata::Board board.
96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 |
# File 'lib/firmata/board.rb', line 96 def connect unless @connected once('report_version', ->() do once('firmware_query', ->() do once('capability_query', ->() do once('analog_mapping_query', ->() do 2.times { |i| toggle_pin_reporting(i) } @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.
89 90 91 |
# File 'lib/firmata/board.rb', line 89 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.
332 333 334 |
# File 'lib/firmata/board.rb', line 332 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.
295 296 297 298 299 300 301 302 303 304 305 306 |
# File 'lib/firmata/board.rb', line 295 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.
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 251 252 253 254 255 256 257 258 |
# File 'lib/firmata/board.rb', line 149 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 emit('analog-read', pin, value) emit("analog-read-#{pin}", 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) 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 supported_modes = 0 n = 0 current_buffer.slice(2, current_buffer.length - 3).each do |byte| if byte == 127 modes = [] # the pin modes [ INPUT, OUTPUT, ANALOG, PWM, SERVO ].each do |mode| modes.push(mode) unless (supported_modes & (1 << mode)).zero? end @pins.push(Pin.new(modes, OUTPUT, 0)) supported_modes = 0 n = 0 next end supported_modes |= (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.
377 378 379 |
# File 'lib/firmata/board.rb', line 377 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.
370 371 372 |
# File 'lib/firmata/board.rb', line 370 def query_capabilities write(START_SYSEX, CAPABILITY_QUERY, END_SYSEX) end |
#query_firmware ⇒ Object
Public: Ask the Ardution for its firmware name.
Returns nothing.
354 355 356 |
# File 'lib/firmata/board.rb', line 354 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.
363 364 365 |
# File 'lib/firmata/board.rb', line 363 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.
139 140 141 142 |
# File 'lib/firmata/board.rb', line 139 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.
263 264 265 |
# File 'lib/firmata/board.rb', line 263 def read_and_process process(read) end |
#report_version ⇒ Object
Public: Ask the Arduino to report its version.
Returns nothing.
347 348 349 |
# File 'lib/firmata/board.rb', line 347 def report_version write(REPORT_VERSION) end |
#reset ⇒ Object
Public: Send a SYSTEM_RESET to the Arduino
Returns nothing.
270 271 272 |
# File 'lib/firmata/board.rb', line 270 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.
284 285 286 287 |
# File 'lib/firmata/board.rb', line 284 def set_pin_mode(pin, mode) pins[pin].mode = mode write(PIN_MODE, pin, mode) end |
#toggle_pin_reporting(pin, state = HIGH, mode = REPORT_DIGITAL) ⇒ Object
Public: Toggle pin reporting on or off.
pin - The Integer pin to toggle. mode - The Integer mode the pin will report. The valid values are
REPORT_DIGITAL or REPORT_ANALOG (default: REPORT_DIGITAL).
state - The Integer state to toggle the pin. The valid value are
HIGH or LOW (default: HIGH)
Returns nothing.
390 391 392 |
# File 'lib/firmata/board.rb', line 390 def toggle_pin_reporting(pin, state = HIGH, mode = REPORT_DIGITAL) write(mode | pin, state) 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”.
340 341 342 |
# File 'lib/firmata/board.rb', line 340 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.
132 133 134 |
# File 'lib/firmata/board.rb', line 132 def write(*commands) serial_port.write_nonblock(commands.map(&:chr).join) end |