Connecting Arduino to Rasberry Pi
Contents
Introduction
Arduino, a microcontroller board, and Raspberry Pi, a fully functional mini-computer, are both cheap solutions for harnessing the Internet of Things at home.
Unlike your regular computer, both devices are very good at reading the world around them. That’s because they both include plenty of inputs and outputs for sensory add-ons to test light, temperature, humidity and more.
With Raspberry Pi and I2C communication, you can connect the Pi with single or multiple Arduino boards.The Raspberry Pi has only 8 GPIO’s, so it would be really useful to have additional Inputs and outputs by combining the Raspberry Pi and Arduino.
In this article you will see how to configure the devices and setup Raspberry Pi as master and Arduino as slave for I2C communication.
Wiring
RPI | Arduino |
GPIO 1 (SDA) | PIN 4 (SDA) |
GPIO 1 (SCL) | PIN 5 (SCL) |
GND | GND |
Code Example
- Remove I2C from Blacklist:
$ cat /etc/modprobe.d/raspi-blacklist.conf
# blacklist spi and i2c by default
blacklist spi-bcm2708
# blacklist i2c-bcm2708
- Load i2c.dev in Module File
- Add this to the end of /etc/modules
i2c-dev
- Install I2C Tools
$ sudo apt-get install i2c-tools
- Allow Pi User to Access I2C Devices
$ sudo adduser pi i2c
- Now reboot the RPI. After that you should see the i2c devices:
pi@raspberrypi ~ $ ll /dev/i2c* crw-rw---T 1 root i2c 89, 0 May 25 11:56 /dev/i2c-0 crw-rw---T 1 root i2c 89, 1 May 25 11:56 /dev/i2c-1
- Now we run a simple test, scan the i2c bus:
pi@raspberrypi ~ $ i2cdetect -y 1
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | |
00: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
10: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
20: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
30: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
40: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
50: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
60: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
70: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
- Install Python-SMBus
sudo apt-get install python-smbus
Configure Arduino As Slave Device For I2C
Load this sketch on the Arduino. We basically define an address for the slave (in this case, 4) and callback functions for sending data, and receiving data. When we receive a digit, we acknowledge by sending it back. If the digit happens to be ’1′, we switch on the LED. This program has only been tested with Arduino IDE 1.0.
#include <Wire.h>
#define SLAVE_ADDRESS 0x04 int number = 0; int state = 0;
void setup() { pinMode(13, OUTPUT); Serial.begin(9600); Wire.begin(SLAVE_ADDRESS); Wire.onReceive(receiveData); Wire.onRequest(sendData); Serial.println("Ready!"); } void loop() { delay(100); } void receiveData(int byteCount){ while(Wire.available()) { number = Wire.read(); Serial.print("data received: "); Serial.println(number); if (number == 1){ if (state == 0){ digitalWrite(13, HIGH); state = 1; } else{ digitalWrite(13, LOW); state = 0; } } } } void sendData(){ Wire.write(number); }
Configure Raspberry Pi As Master Device
Since we have a listening Arduino slave, we now need a I2C master. This testing program has been written in Python. This is what it does: the Raspberry Pi asks you to enter a digit and sends it to the Arduino, the Arduino acknowledges the received data by send the exact same number back.
import smbus import time< # for RPI version 1, use "bus = smbus.SMBus(0)" bus = smbus.SMBus(1) # This is the address we setup in the Arduino Program address = 0x04 def writeNumber(value): bus.write_byte(address, value) # bus.write_byte_data(address, 0, value) return -1 def readNumber(): number = bus.read_byte(address) # number = bus.read_byte_data(address, 1) return number while True: var = input("Enter 1 - 9: ") if not var: continue writeNumber(var) print "RPI: Hi Arduino, I sent you ", var # sleep one second time.sleep(1) number = readNumber() print "Arduino: Hey RPI, I received a digit ", number print
- To make sure this is working, run i2cdetect -y 1 again in the terminal, you should get something like this. 04 is the address we defined in the Arduino sketch.
pi@raspberrypi ~ $ i2cdetect -y 1
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e | f | |
00: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
10: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
20: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
30: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
40: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
50: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
60: | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
70: | -- | -- | -- | -- | 04 | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- | -- |
References
- http://www.adafruit.com/blog/2014/02/21/connecting-an-arduino-to-a-raspberry-pi-using-i2c-raspberry_pi-piday-raspberrypi/
- http://codeandlife.com/2012/07/29/arduino-and-raspberry-pi-serial-communication/
- http://mitchtech.net/raspberry-pi-arduino-spi/
More information
- Connect Arduino to the Mobile Network
- Connecting Arduinos together
- Connecting Arduino to Rasberry Pi
- Connecting Arduino to the Internet - How to add a webserver, HTTP client, etc
- Connecting Arduino to Android via USB cable
- Connecting Arduino to PC serial port
- Connecting Arduino to Windows and Linux through an USB cable
- Connecting Arduino to GSM GPS shield
- Connecting Arduino to GPRS/GSM Quadband Module (SIM900)