Firmata is a protocol for communicating with microcontrollers from software on a host computer. So you can control an Arduino with a Raspberry Pi using Firmata.
There is a tutorial for Firmata and Raspberry Pi in The MagPi Issue 7 and here is also a small guide.
Sketch upload via hardware serial port of the Raspberry Pi
Sketch upload with USB FTDI adapter
The RPi-UNO-HAT can be connected via USB or UART:
USB connection (FTDI adapter)
UART connection (hardware serial port)
$ sudo raspi-config
and select Advanced > Interfacing Options > Serial > Disable shell > Enable serial port hardware
Install pySerial and pyFirmata using pip:
$ sudo apt-get update
$ sudo apt-get install python-serial
$ sudo pip install pyfirmata
Create a test script named Firmata.py:
$ nano Firmata.py
import time
import pyfirmata
# start connection to Arduino
# USB: /dev/ttyUSB0 or /dev/ttyACM0
# UART: /dev/ttyS0 or /dev/ttyAMA0
board = pyfirmata.Arduino('/dev/ttyAMA0')
board.digital[13].write(1) # switch on LED
time.sleep(3) # 3s delay
board.digital[13].write(0) # switch off LED
time.sleep(3) # 3s delay
board.exit()
Run the script:
$ python Firmata.py
Install Node and Firmata library:
$ sudo apt-get install node
$ sudo npm install -g firmata
If the node package is not found then add Adafruit to the package repository: $ curl -sLS https://apt.adafruit.com/add | sudo bash
Create a test script named Firmata.js:
$ nano Firmata.js
var firmata = require('firmata');
// start connection to Arduino
// USB: /dev/ttyUSB0 or /dev/ttyACM0
// UART: /dev/ttyS0 or /dev/ttyAMA0
var board = new firmata.Board('/dev/ttyAMA0', function(err)
{
if(err)
{
console.log(err);
return;
}
console.log('connected');
board.pinMode(13, board.MODES.OUTPUT);
// switch on LED
board.digitalWrite(13, board.HIGH);
// switch off LED after 3s
setTimeout(function()
{
board.digitalWrite(13, board.LOW);
process.exit(0);
}, 3000);
});
Run the script:
$ sudo node Firmata.js
A small guide to show the communication via I2C between the Arduino (RPi-UNO-HAT) and Raspberry Pi.
The I2C pins of the Raspberry Pi are connected to the AVR and the Shield connectors (SDA+SCL) on the RPi-UNO-HAT.
Upload the following Sketch:
#include <Wire.h>
#define ADDRESS 0x30
void setup()
{
pinMode(13, OUTPUT); // set pin 13 as output (LED connected)
digitalWrite(13, LOW); // set pin 13 to low (0V)
Wire.begin(ADDRESS); // join I2C bus with respective address
Wire.onReceive(receive); // receive data function
Wire.onRequest(request); // send data function
}
void loop()
{
// do nothing
}
void receive(int numBytes) // function that runs when data is received
{
unsigned char c;
while(Wire.available())
{
c = Wire.read();
if(c == 0x00) // LED off, if byte equals 0
{
digitalWrite(13, LOW);
}
else if(c == 0x01) // LED on, if byte equals 1
{
digitalWrite(13, HIGH);
}
}
}
void request() // function that runs when data is requested
{
Wire.write(0xAA); // send 0xAA
}
Activate I2C:
$ sudo modprobe i2c_bcm2708 baudrate=100000
$ sudo modprobe i2c-dev
Note: For a Device Tree Kernel add to /boot/config.txt
the following line: dtparam=i2c1=on
(before any dtoverlay statement).
Install i2c-tools and python-smbus:
$ sudo apt-get install i2c-tools
$ sudo apt-get install python-smbus
Test I2C bus:
$ sudo i2cdetect -y 1
Switch on LED:
$ sudo i2cset -y 1 0x30 0x01
Switch off LED:
$ sudo i2cset -y 1 0x30 0x00
Create a test script named I2CTest.py:
$ nano I2CTest.py
import time
import smbus
bus = smbus.SMBus(1)
addr = 0x30
while True:
bus.write_byte(addr, 0x01)
print "on"
time.sleep(1)
bus.write_byte(addr, 0x00)
print "off"
time.sleep(1)
Run the script:
$ sudo python I2CTest.py