Introduction: A Guide to Raspberry Pi Arduino Communication in Embedded Systems

This is a guide to various methods for communications between Raspberry Pi and Arduino. This guide is created from everything I've learned from the creation of a capacities forest. The post of the project can be seen, a video of the project can be seen here, and documentation on the software aspect can be found here.

In this project we wanted to create a forest where one can explore and experience sound and visuals. The Arduino is used for the inputs and the Raspberry Pi is used for networking, visuals, and audio. This allows us to have analog inputs and create multiple nodes to create an immersive experiences.

This guide is documentation of all I have tried to create the project. I will cover various communication protocols and why they didn't work out. I will also cover giving power to the system when out in the world where there is no access to a electrical plug.

While in our project we used capacities touch as our input and visuals and audios as our out put, this can be applied to any other project. If you are interested in using capacities touch, I used this capacities touch library. I would like to note that the capacities touch works best when you also have an Earth ground.

Step 1: ATTiny 85 USI

First we wanted to use and ATTiny 85. The small AVR chip that is compact and low on power consumption. The ATtiny 85 (and it's cousins) do not have I2C or SPI hardware built in, but rather USI (Universal Serial Interface). USI can be used to facilitate I2C and SPI. These methods can also be used to program the ATTiny using the Raspberry Pi.

Hardware hook up is simple for this if you want to use SPI connect MOSI to MOSI, MISO to MISO, and CLK to CLK. I2C connect the SDA to SDA, SCL to SCL, and add pull up resisters (4.7k ohms on 5V) for it to work. I suggest using I2C since it takes up one less pin and pins are limited and I2C library for the ATTiny are better documented.

ATTiny USI library can be found here. The library is simple to use and can be easily implemented.

This is the Code for the ATTiny. The code simply echos what is sent to it and blinks an LED an equal amount of time.

#include <TinyWireS.h>

#define SLAVE_ADDRESS 0x04

#define LED1_PIN 4 // ATtiny Pin 3

void setup()



Blink(LED1_PIN,2); // show it's alive



void loop()


byte byteRcvd = 0;



byteRcvd = TinyWireS.receive();


Blink(LED2_PIN, byteRcvd);



void Blink(byte led, byte times){

for (byte i=0; i< times; i++){


delay (25);


delay (17);



This is a simple code for the Raspberry Pi done in python. The code sends a integer number of your choice and prints what the ATTiny echos back.

import smbus

import timebus = smbus.SMBus(1)

address = 0x04

while True:

i2cread = bus.read_byte(address)

print i2cread time.sleep(0.1)

Using this you should be able to do basic testing and make sure there are no hardware issue. However, later we found that the library is limiting as it has problem doing rapid communication and resulted in frequent crashing. This pushed to move to ATMegas as that will allow is to us the Arduino wire library.

Step 2: ATMega I2C

Moving to the ATMega allows us the Arduino Wire library that is more robust then the libraries for ATTiny. Using the same python code and the wire library examples, This can be set up really fast and easy. Wiring is the same as for the ATTiny.

However, during testing we found that it frequently crashed. Double checked all the code and hardware and started looking deeper into. We hooded up an oscilloscope and found odd irregularities and with some research found that there is a hardware bug in the Raspberry Pi both version one and two. The full article about the hardware bug can be read here. This pushed the move to serial communication.ds

Step 3: Serial Communication

With the hardware I had available I used a Teensy 2.0 as the Arduino. To make things easier I also chooses to use serial over USB rather than the internal pins. This is really simple as on the Ardunio side all that is needed for sending a message is Serial.print. On the python side is simple as you can use pySerial to read the serial bus. Documentation of pySerial can be found here. This works really well without any issues of crashing. I highly recommend this method as it is the most simple and easy to use. I was able to complete this in two hours.

I also would like to note, that there are some python version issues. pySerial only works in python 2 and not python 3. This becomes more of an issue as we move towards communication between the multiple nodes of Raspberry Pis.

Step 4: OSC Communication Between Raspberry Pis

For our system we used OSC. OSC is an easy way to get multiple devices connect to a network to talk to each other. Since pySerial only works in Python 2 makes user to use an OSC library for python 2. This is the OSC library.

Step 5: Power

Power can be tricky when you are out and away from