class Aio::Board

This is the main class that communicates with the Arduino board.

It implements several mechanisms like ACK/NAK for confirming command execution and {en.wikipedia.org/wiki/Longitudinal_redundancy_check redundancy checks} to ensure data integrity.

Public Class Methods

new(port) { |self| ... } click to toggle source

@example Modes of initialization

# explicit
board = Aio::Board.new("/dev/ttyUSB1")

# block mode (closes the connection at the end)
Aio::Board.new("/dev/ttyUSB0") do |board|
  # code...
end

@param port [String] the device/address used for communication. @yield [self] an optional block of code to execute. @raise [DeviceError] when the serial port is unavailable.

# File lib/aio/board.rb, line 24
def initialize(port)
        @serial = SerialPort.new(port, BAUDRATE, 8, 1, SerialPort::NONE)
rescue Errno::ENOENT
        raise Aio::DeviceError, "Unavailable serial port at address => '#{port}'"
else
        @serial.flow_control = SerialPort::NONE
        @serial.read_timeout = TIMEOUT
        @serial.sync = true
        
        if block_given?
                yield(self)
                close
        end
end

Public Instance Methods

analogRead(pin) click to toggle source

Reads the value from a specified analog pin.

@param pin [Integer] pin number (as stated in the board). @return [Integer, nil] an integer between 0 and 1023 or nil on error. @raise (see pinMode)

# File lib/aio/board.rb, line 99
def analogRead(pin)
        try(nil) {
                sendCMD [4, pin, empty]
                onACK do
                        onData(4) do |bytes|
                                bytes[0] + (bytes[1] << 8)
                        end
                end
        }
end
analogReference(type) click to toggle source

Configures the reference voltage used for analog input.

@param type [Integer] {DEFAULT}, {EXTERNAL}, {INTERNAL}, {INTERNAL1V1} or {INTERNAL2V56}. @return (see pinMode) @raise (see pinMode)

# File lib/aio/board.rb, line 130
def analogReference(type)
        try(false) {
                sendCMD [6, type, empty]
                onACK {true}
        }
end
analogWrite(pin, value) click to toggle source

Writes an analog value (PWM wave) to a pin.

@param pin [Integer] pin number (as stated in the board). @param value [Integer] an integer between 0 (always off) and 255 (always on). @return (see pinMode) @raise (see pinMode)

# File lib/aio/board.rb, line 117
def analogWrite(pin, value)
        try(false) {
                sendCMD [5, pin, value]
                onACK {true}
        }
end
close() click to toggle source

Closes the connection with the board.

@return [nil]

# File lib/aio/board.rb, line 43
def close
        @serial.close
        nil
end
digitalRead(pin) click to toggle source

Reads the value from a specified digital pin.

@param pin [Integer] pin number (as stated in the board). @return [Integer, nil] {HIGH} (1), {LOW} (0) or nil on error. @raise (see pinMode)

# File lib/aio/board.rb, line 68
def digitalRead(pin)
        try(nil) {
                sendCMD [2, pin, empty]
                onACK do
                        onData(4) do |bytes|
                                bytes[0]
                        end
                end
        }
end
digitalWrite(pin, state) click to toggle source

Writes a {HIGH} (1) or a {LOW} (0) value to a digital pin.

@param pin [Integer] pin number (as stated in the board). @param state [Integer] {HIGH} (1) or {LOW} (0). @return (see pinMode) @raise (see pinMode)

# File lib/aio/board.rb, line 86
def digitalWrite(pin, state)
        try(false) {
                sendCMD [3, pin, state]
                onACK {true}
        }
end
millis() click to toggle source

Returns the number of milliseconds since the Arduino board began running the current program.

@return [Integer, nil] a 32bit integer or nil on error. @raise (see pinMode)

# File lib/aio/board.rb, line 142
def millis
        try(nil) {
                sendCMD [7, empty, empty]
                onACK do
                        onData(4) do |bytes|
                                bytes[0] + (bytes[1] << 8) + (bytes[2] << 16) + (bytes[3] << 24)
                        end
                end
        }
end
pinMode(pin, mode) click to toggle source

Sets the mode of operation for a specific pin.

@param pin [Integer] pin number (as stated in the board). @param mode [Integer] mode of operation: {INPUT}, {OUTPUT} or {INPUT_PULLUP}. @return [Boolean] if the command was successful. @raise [DeviceError] on unexpected device errors.

# File lib/aio/board.rb, line 55
def pinMode(pin, mode)
        try(false) {
                sendCMD [1, pin, mode]
                onACK {true}
        }
end
ready?() click to toggle source

Tells if the board is ready.

@return [Boolean] @raise (see pinMode)

# File lib/aio/board.rb, line 158
def ready?
        try(false) {
                sendCMD [8, empty, empty]
                onACK {true}
        }
end

Private Instance Methods

empty() click to toggle source
# File lib/aio/board.rb, line 216
def empty
        rand(256)
end
getLRC(ary) click to toggle source
# File lib/aio/board.rb, line 211
def getLRC(ary)
        lrc = ary.inject(0) {|acc,val| (acc + (val.to_i & 0xff)) & 0xff}
        (lrc ^ 0xff) + 1
end
onACK(&block) click to toggle source
# File lib/aio/board.rb, line 181
def onACK(&block)
        if @serial.readbyte == ACK
                instance_eval(&block)
        else
                raise Aio::CommandError
        end
end
onData(n, &block) click to toggle source
# File lib/aio/board.rb, line 189
def onData(n, &block)
        bytes = readBytes(n)
        lrc = @serial.readbyte
        if lrc == getLRC(bytes)
                instance_exec(bytes, &block)
        else
                raise Aio::CommandError
        end
end
readBytes(n) click to toggle source
# File lib/aio/board.rb, line 205
def readBytes(n)
        bytes = []
        n.times {bytes << @serial.readbyte}
        bytes
end
sendCMD(ary) click to toggle source
# File lib/aio/board.rb, line 199
def sendCMD(ary)
        @serial.putc(SYNCBYTE)
        ary.each {|byte| @serial.putc(byte.to_i)}
        @serial.putc(getLRC(ary))
end
try(ret, &block) click to toggle source
# File lib/aio/board.rb, line 167
def try(ret, &block)
        instance_eval(&block)
rescue => e
        @serial.flush_input
        case e
                when EOFError, Aio::CommandError
                        return ret
                when Errno::EIO
                        raise(Aio::DeviceError, e.message)
                else
                        raise
        end
end