SCPyduino interface for Firmata
Class that communicates with a microcontroller running Firmata (http://www.firmata.org). Originally written in Python by Joe Turner. ( http://code.google.com/p/pyduino/ )
Some Issues Regarding SCPyduino
In order to use this to communicate with an Arduino, it has to be loaded with the sketch Standard_Firmata.pde. You should be able to find this in the Arduino software examples folder.
This class is still in an early development stage. It's has only been tested on Arduino. Not tested on Windows.
Any suggestions, corrections or comments are welcome.
Creation / Class Methods
*new (port)
Short prose description of method.
port - device path
// List devices
SerialPort.listDevices
//choose appropriate index. You can also cut and paste the path name directly in the port argument
d = SerialPort.devices[6]; // or "/dev/tty.usbserial-A1001NeZ"
f = SCPyduino.new(d);
//wait ~three secs
f.firmataVersion; // posts the version of Firmata returned from the microcontroller if
//connection is ok
f.close; //close the SerialPort connection.
Accessing Instance and Class Variables
digitalPorts
An array of two 8-bit ports. Digital pins 0..7 belongs to .digitalPorts[0], pins [8..13] belongs to .digitalPorts[1].
The Firmata protocol supports up to 16 8-bit ports, but this is yet to be implemented in this class. Before you can read/write to a digital pin, the port has to be activated:
f = SCPyduino.new(d);
f.digitalPorts[1].active_(1);
f.digitalPorts.active.postln; // returns 1
f.close;
analog
An array of analog pins. The Firmata protocol support up to 16 analog pins. In the current impementation the number of analog pins is 6. The pins has to be activated in order to read values from the pins.
f = SCPyduino.new(d);
f.analog[0].active_(1); //activates polling for analog pin 0 on the microcontroller
f.iterate; //tell microcontroller to poll activated pins/ports
f.analog[0].value; // return value stored for analog pin 0
f.close;
digital
An array of digital pins. the firmata protocol supports up to 128 pins (16 * 8-bit ports). In the current implemetation the number of digital pins is set to 14.
Each digital pin can have three modes :
digital_output : for writing to pin, enumerated as 0
digital_input : for reading pin, enumerated as 1
digital_pwm : for PWM output (only on pins: 3, 5, 6, 9, 10, 11), enumerated as 2
All modes are accessible through instance variables and can be used as argument for SCPyduino.digital[].mode():
f = SCPyduino.new(d);
f.digital_input; // returns 0
f.digital_output; // returns 1
f.digital_pwm; // returns 2
f.close;
Pins 0, 1 (Tx, Rx), 15 and 16 are set to \unavailable to prevent user to use these pins for writing/reading data.
The mode is set as follows:
f = SCPyduino.new(d);
f.digital[0].mode_(f.digital_output); //throws an error since we can't use Rx
f.digital[13].mode_(f.digital_output); //works
f.digital[4].mode_(f.digital_pwm); //throws an error since it's not a pwm pin
f.digital[5].mode_(f.digital_pwm); // works
f.digital[2].mode_(f.digital_input);
f.close;
firmataVersion
The version of Firmata returned from the microcontroller.
Polling values from the pins
iterate
Sends message to microcontroller to poll activated pins/ports. Results are returned and stored in
SCPyduino.digital[0..13].value and SCPyduino.analog[0..6].value
close
Closes the SerialPort connection.
Examples
// List devices
SerialPort.listDevices
//choose appropriate index. You can also cut and paste the path name directly in the port argument
d = SerialPort.devices[6]; //select correct index for serial port
p = SCPyduino.new(d);
// - Controlling digital output -
//Activate digital port 1 (PORTB) on the Arduino
p.digitalPorts[1].active_(1)
//Set the mode for digital pin 13 to digital output
p.digital[13].mode_(p.digital_output);
p.digital[13].write(1);//turn on LED
p.digital[13].write(0);//turn off LED
//Make the LED blink
(
a = fork{
loop{
p.digital[13].write(1);
1.wait;
p.digital[13].write(0);
1.wait;
}
};
)
a.stop; // stop blinking
// - Reading a digital pin -
// activate port 0 (PORTA)
p.digitalPorts[0].active_(1);
// set the mode for digital pin 2 to digital_output
p.digital[2].mode_(p.digital_input);
// read digital pin 2 and post value
(
a = fork {
loop {
p.iterate;
p.digital[2].value.postln;
}
}
)
a.stop
// - Reading an analog port -
//active analog pin 0
p.analog[0].active_(1)
//post value of analog pin 0
(
a = fork{
loop{
p.iterate;
p.analog[0].value.postln;
}
};
)
a.stop;
//deactivate reporting analog values
p.analog[0].active(0);
// - pwm output -
p.digitalPorts[0].active_(1);
p.digital[3].mode_(p.digital_pwm);
//pulsating LED
(
var i;
a = fork{
5000.do { |i|
i = (((i % 500) / 500) * 2pi);
p.digital[3].write(sin(i) + 1 * 0.5);
0.005.wait;
}
}
)
a.stop;
p.close // close serialport