You are on page 1of 41

Menu

Search

RASPBERRY PI AND ARDUINO CONNECTED USING I2C

Share this:

Facebook 33 Google Twitter Email Reddit

With Raspberry Pi and I2C communication, we can connect the Pi with single or multiple Arduino boards. The Raspberry Pi has
only 8 GPIOs, so it would be really useful to have additional Inputs and outputs by combining the Raspberry Pi and Arduino.

There are many ways of Linking them such as using USB cable and Serial Connection. Why do we choose to use I2C? One
reason could be it does not use your serial, USB on the Pi. Given the fact that there are only 2 USB ports, this is definitely a big
advantage. Secondly, flexibility. You can easily connect up to 128 slaves with the Pi. Also we can just link them directly without a
Logic Level Converter.

converted by Web2PDFConvert.com
In this article I will describe how to configure the devices and setup Raspberry Pi as master and Arduino as slave for I2C
communication. Article1 and Article2 if you dont know what is I2C.

In the next article I will be doing some Voice Recognition, if you are interested see here Raspberry Pi Voice Recognition Works
Like Siri

How Does It Work? Is It Safe?


The Raspberry Pi is running at 3.3 Volts while the Arduino is running at 5 Volts. There are tutorials suggest using a level
converter for the I2C communication. This is NOT needed if the Raspberry Pi is running as master and the Arduino is running
as slave.

The reason it works is because the Arduino does not have any pull-ups resistors installed, but the P1 header on the Raspberry
Pi has 1k8 ohms resistors to the 3.3 volts power rail. Data is transmitted by pulling the lines to 0v, for a high logic signal. For
low logic signal, its pulled up to the supply rail voltage level. Because there is no pull-up resistors in the Arduino and because
3.3 volts is within the low logic level range for the Arduino everything works as it should.

converted by Web2PDFConvert.com
Remember though that if other I2C devices are added to the bus they must have their pull-up resistors removed. For more
information, see here.

These are the images showing where the I2C pins are on the Raspberry Pi and Arduino.

Note that the built-in pull-up resistors are only available on the Pis I2C pins (Pins 3 (SDA) and 5 (SCL), i.e. the GPIO0 and GPIO1 on
a Rev. 1 board, GPIO2 and GPIOP3 on a Rev. 2 board:

On the Arduino Uno, the I2C pins are pins A4 (SDA) and A5 (SCL), On the Arduino Mega, they are 20 (SDA), 21 (SCL)

For information about the Arduino I2C Configuration and for other models of Arduino, check out this documentation Wire library.

Setup Environment on Raspberry Pi for I2C Communication


I will describe the process briefly here, if you are in doubt please refer to a more detailed process here and here.

Remove I2C from Blacklist:

$ cat /etc/modprobe.d/raspi-blacklist.conf
# blacklist spi and i2c by default (many users don't need them)
blacklist spi-bcm2708
#blacklist i2c-bcm2708

converted by Web2PDFConvert.com
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
0123456789abcdef
00: -- -- -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Hint: if youre using the first revision of the RPI board, use -y 0 as parameter. The I2C bus address changed between those two
revisions.

Install Python-SMBus
This provides I2C support for Python, documentation can be found here. Alternatively, Quck2Wire is also available.

sudo apt-get install python-smbus

converted by Web2PDFConvert.com
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.

[sourcecode language=cpp]

#include <Wire.h>

#define SLAVE_ADDRESS 0x04


int number = 0;
int state = 0;

void setup() {
pinMode(13, OUTPUT);
Serial.begin(9600); // start serial for output
// initialize i2c as slave
Wire.begin(SLAVE_ADDRESS);

// define callbacks for i2c communication


Wire.onReceive(receiveData);
Wire.onRequest(sendData);

Serial.println(Ready!);
}

void loop() {
delay(100);
}

// callback for received data


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); // set the LED on
state = 1;

converted by Web2PDFConvert.com
}
else{
digitalWrite(13, LOW); // set the LED off
state = 0;
}
}
}
}

// callback for sending data


void sendData(){
Wire.write(number);
}

[/sourcecode]

Configure Raspberry Pi As Master Device


Since we have a listening Arduino slave, we now need a I2C master.

I have written this testing program 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.

In the video, I used a built-in programming tool called IDLE in Raspberry Pi for compiling.

[sourcecode language=python]

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

converted by Web2PDFConvert.com
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
[/sourcecode]

For more read/write functions, check out this useful look up table for the functions.

Connect Your Arduino With Raspberry Pi


Finally, we need to connect the Raspberry Pi and Arduino on the I2C bus. Connection is easy:

RPI Arduino (Uno/Duemillanove)


--------------------------------------------
GPIO 0 (SDA) <--> Pin 4 (SDA)
GPIO 1 (SCL) <--> Pin 5 (SCL)
Ground <--> Ground

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.

converted by Web2PDFConvert.com
pi@raspberrypi ~ $ i2cdetect -y 1
0123456789abcdef
00: -- 04 -- -- -- -- -- -- -- -- -- -- --
10: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
70: -- -- -- -- -- -- -- --

Thats the end of this article, for results, please see video on top. From here, you can add sensors to the Arduino, to send data
back to the Raspberry. Or have servos and motors on the Arduino that can be controlled from the Raspberry Pi. Its just Fun.

Updates: 07/07/2013
Someone messaged me asking how to use logic level converter for i2c connection between Raspberry Pi an d Arduino. I
happen to have a spare Logic Level converter, so I gave it a go.

This is how I connect them.

GPIO0 (SDA) -- | TX1 -- TX0 | -- A4 (SDA)


GPIO1 (SCL) -- | RX0 -- RX1 | -- A5 (SCL)
3.3V -- | LV -- HV | -- 5V
GND -- | GND -- GND | -- GND

But the result was a little weird. The data successfully sent to the Arduino, and the data was also received successfully from the
Arduino on the Pi, but the data was wrong at the raspberry pi side.

When I sent number 1 to the Arduino, I got 0 back.


When I sent 2, I got 1 back.
sent 3 and got 1 back
sent 4 and got 2 back etc

I dont know why this is happening, something to do with the converter? or maybe the connection is wrong? I dont have time to

converted by Web2PDFConvert.com
figure this out. Since I can get it working without a logic level converter, i will leave it for now, if you do know why, please let me
know.

Related

Posted in Electronics, Featured, Raspberry Pi and tagged arduino, raspberry pi on 25th May 2013. 96 Replies

Raspberry Pi and Arduino Connected Over Serial GPIO Raspberry Pi Voice Recognition Works Like Siri

96 thoughts on Raspberry Pi and Arduino Connected Using I2C

Robson

converted by Web2PDFConvert.com
12th March 2017 at 12:56 am

Hello,

On the voltage level converter, I believe it is not necessary because I2C works with open collector (drain), and only Raspberry Pi
would have pullup resistors enabled. So the bus will work at 3.3V correctly.

See this image:


i1.wp.com/maxembedded.les.wordpress.com/2014/02/i2c-bus-interface-a-closer-look1.png

Reply

Robson
11th March 2017 at 1:37 pm

Nice, but you can use USB (serial) instead

Reply

sridhar
17th February 2017 at 12:24 pm

i connected every thing according to your tutorial. but data is not transferring, i am using raspi3 model b, arduino uno.
i didnot get any errors while compiling. pl somebody help me to tell what type of erros may be.

Reply

Roger Ram Jet


16th February 2017 at 11:49 pm

Firstly thank you for writing this blog. I have taken your code and made it work between a Raspberry Pi zero and Arduino type
(DFRobot bluno beetle). Press 1 and get 1 back. I then modied your Python code so that it missed out the manual input and
1 was programmed to var all the time. So it just looped round. I added a delay of time.sleep(0.5) after the writeNumber
command. After reducing the delay down to roughly 0.01 or there abouts I hit the, what I believe to be, the clock stretching bug
of the Raspberry Pi which I have been struggling with. Apparently the Raspberry Pi doesnt do clock stretching but the Arduino
does and there lies the bug. Some I2C sensors dont do clock stretching so they are ne with the Raspberry Pi. Again what I
believe from research on the internet.
Again thank you for your code that conrmed that I hadnt done something wrong with my code.

These statements are made in good faith but please do your own research.

Reply

converted by Web2PDFConvert.com
Mirko Hessel-von Molo
6th July 2016 at 3:46 pm

Hi Oscar,

thanks for your tutorial. However, Im a bit puzzled about your statement that the Arduino does not have pull up resistors
installed. Quite to the contrary, from the Arduino documentation I gather that the ATMega microcontrollers do have pull up
resistors on the I2C lines, albeit very weak ones (20k Ohms to 70 kOhms, see e. g. http://playground.arduino.cc/Main/I2CBi-
directionalLevelShifter) which are enabled by the Arduino Wire library.

So as far as I can see, the hardware setup youre proposing (using the Raspberry Pi pullup to 3.3 Volts) is a bit risky: When the
I2C bus is idle, you have 3.3 Volts on the Raspberry Pi connected via the raspberry pullups and the arduino pullups to 5 Volts on
the Arduino. Assuming the total resistance to be around 20 kOhms (the 1k8 resistors on the Raspberry dont inuence this
much) this should lead to a continuous current of 85 micro-Ampere _into_ the 3.3 Volts port on the Raspberry. Can we be sure
this is small enough not to mess things up on the Raspberry side?

Reply

Pavel
2nd July 2016 at 12:28 pm

Hi, Oscar, tell me pls, how i can connect more than 1 arduino? Maybe you have a article about it? Ore examples? I afraid try it
myself. :-(

Reply

Oscar Post author


9th July 2016 at 11:05 pm

no sorry i dont, with I2C you should be able to connect more than 1 Arduino, you just need to set an unique address ID on each
one Google Arduino I2C you should be able to nd a tutorial

Reply

Marco Tarantino
30th June 2016 at 11:04 am

Hi Oscar,

Thanks for your post. Ive used the examples of code you posted here in a project of mine. Recently, Ive put that code on github
and only later it occurred to me that your code is, well, yours.

So, I would like to ask for your permission to share this code (you can nd it here https://github.com/metis-

converted by Web2PDFConvert.com
vela/raspmetis/blob/master/data_fetch.py). Admittedly, the present version contains what I believe are 13 lines in common with
yours, but I still think youre the author of those lines and, moreover, in the history there is a verbatim copy of your code.

Reply

Linus
3rd June 2016 at 11:17 am

Just a quick correction while using that logic lever shifter the conection that you tried is wrong should be

GPIO0 (SDA) | TX1 TX0 | A4 (SDA)


NC |RXO RX1 | NC
3.3V | LV HV | 5V
GND | GND GND | GND
NC |RX1 RX0 | NC
GPIO1 (SCL) | TX1 TX0 | A5 (SCL)

also made de order more as it is on the pdb.

Reply

Verlene
17th February 2016 at 11:10 am

When some one searches for his necessary thing,


therefore he/she wants to be available that in detail,
thus that thing is maintained over here. ironsteelcenter

Reply

jep
22nd February 2016 at 3:23 pm

Hi Oscar,

The C++ code posted by Milliways2 didnt compile for me, heres a version that does.

Compile with g++ -o i2ctest i2ctest.c -l wiringPi

// I2cTest
//
// Based on https://oscarliang.com/raspberry-pi-arduino-connected-i2c/
// Requires WiringPi http://wiringpi.com/

converted by Web2PDFConvert.com
#include
#include
#include

const int address = 0x04; // This is the address we setup in the Arduino Program
int fd;

int writeNumber(unsigned value) {


return wiringPiI2CWrite(fd, value);
}

int readNumber(void) {
return wiringPiI2CRead(fd);
}

int main(int argc, const char * argv[]) {


unsigned int var;
int number;

fd = wiringPiI2CSetup(address); // Automatically selects i2c on GPIO

while(true) {
std::cout <> var;
writeNumber(var);
std::cout << "Sent: " << var << std::endl;
number = readNumber();
std::cout << "Received: " << number << "\n\n";
}
return 0;
}

Reply

Rodrigo
7th February 2016 at 12:21 am

Hey Oscar,
great tutorial, thanks a lot!
It took me a while to make the code work in python3 but I nally made it!
You need to install python3-smbus and change a couple of things in the python script (linke x indentation, cast value to an int
in writeNumber , put parentheses in print functions, etc.)
Im new to python but this code worked ne for me:

import smbus

converted by Web2PDFConvert.com
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, int(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)

Reply

4ntoine
12th January 2016 at 12:55 pm

Check out ArduinoCode Arduino IDE that runs on iOS but is able to compile and upload using Raspberry Pi:
http://www.arduinocode.info/2016/01/raspberry-pi.html

Reply

BombDoc
22nd December 2015 at 12:35 am

Hi Oscar,

converted by Web2PDFConvert.com
I am trying to send sketches from my rpi to arduino using a i2c connection.
I have a grove pi+ board on my pi 2 and a grove base shield on my arduino mega.
I have there neat cable that plugs into the i2c connectors on the bord. I cut the red wire from the cable. I can not get it to work,
now is this a software problem or should I cross the yellow and white wires to get them talking. I am very new to this but I think
it should work.

Reply

Nicolas
20th December 2015 at 12:18 pm

File i2cTest.py, line 3


SyntaxError: Non-ASCII character \xe2 in le i2cTest.py on line 3, but no encoding declared; see python.org/peps/pep-
0263.html for details / your script

Reply

Rob
23rd November 2015 at 7:43 pm

Hi Oscar, cheers for the small example! Quick and simple starting point for my setup :)

Reply

Paresh
18th November 2015 at 8:46 am

Hi Oscar,
Im getting error bus=smbus.SMBus(1) IOError[Error 2] No suh le or directory what should i do?

Reply

Vinay
10th November 2015 at 6:05 pm

Hi Oscar, Thanks a lot. Works like a charm.

Reply

dona
23rd October 2015 at 2:19 am

converted by Web2PDFConvert.com
Hi Oscar,

I have a project that send data from arduino to raspberry via i2c.
I have tried your code and its work. Thanks!
The problem is, i want to reset the data that arduino sent to raspberry.
For now, i just do it with push the button in arduino to reset data.
But, i want now raspberry give a command to reset data in arduino.
How i could do this? its a bit confusing.

Reply

Kassus
12th December 2015 at 10:35 am

Hi Dona,

Maybe you should connect one of GPIOs to Arduinos reset pin?

Reply

Ronda
14th July 2015 at 1:48 am

Hi Oscar,

Great information in this blog post! Thanks for sharing. I wanted to let you know about a kickstarter we have going for an I2C 8
GPIO Extneder board for the Arduino & Raspberry Pi. It will add 8 GPIO pins and will cost a lot less than another Arduino or RP
board. The kickstarter is called Really, Really Useful Breakout Boards for Your Raspberry Pi and Arduino. Heres a link if youre
interested; Id love to hear your thoughts! http:// kck.st/ 1HYLam1

Reply

Bill Harvey
26th June 2015 at 4:12 pm

Hi;

This is a great guide that I desparately need to work however following some updates to Raspbian there are some errors in this
guide such as setting up i2c and the sketch test code to set the Arduino to listen.
I know it says Arduino IDE 1.0 but is there an updated version of the guide anywhere??

The errors in Sketch are not many:

sketch_jun26a:17: error: stray \ in program

converted by Web2PDFConvert.com
sketch_jun26a:17: error: stray \ in program
sketch_jun26a:29: error: stray \ in program
sketch_jun26a:29: error: stray \ in program
sketch_jun26a.ino: In function void setup():
sketch_jun26a:17: error: u201cReady was not declared in this scope
sketch_jun26a.ino: In function void receiveData(int):
sketch_jun26a:29: error: u201cdata was not declared in this scope

May be a copy and paste issue??

Reply

Jan
28th June 2015 at 9:12 am

Hi Bill,
ive had the same error.

You have to replace the with this one quotation marks.

I hope this will x your error!

Jan

Reply

Bill Harvey
13th September 2015 at 10:20 pm

Sorry forgot to say thanks yes it was a problem with the way the code copied from this web page :-)

Manju Hubli
14th August 2015 at 4:34 am

hey just delete whatever you have written in print or println statement and rewrite again ,you should get comment inside printf
or println in green or skyblue(or other than black). now save and compile..
now your program is ready to upload.

Reply

Georg
4th February 2015 at 11:08 pm

converted by Web2PDFConvert.com
re logic level converter:
I found a comment on watterott.com/en/4-channel-I2C-safe-Bi-directional-Logic-Level-Converter-BSS138
that hints that the problem with your trial might have been due to I2C, which uses a funky pull-up system to transfer data back
and forth and this particular converter (as shown in picture).
I am thinking about ordering the converter linked above and will report back if I succeed ;)

Reply

Drac
31st December 2014 at 5:18 pm

Your post has been very helpful for newcomers like myself.
Ive been trying to control an led on arduino using a push button And it worked. Then I attached a Raspberry pi and controlled
the led on the arduino via i2c It was fun!!!

But when I try to connect them both together( to be able to control via i2c and also using a push button on the arduino to on
and o the same led) I run in to many troubles.
I would really appreciate it if you could show me a way to make it work!

Reply

nvw
27th December 2014 at 11:08 am

Ive been digging a bit on this statement: The reason it works is because the Arduino does not have any pull-ups resistors
installed

The ATmega328P chip datasheet shows SDA and SCL are bits of Port C, described as follows:
Port C is a 7-bit bi-directional I/O port with internal pull-up resistors (selected for each bit)

And the section specically describing SDA/SCL says:


Note that the internal pull-ups in the AVR pads can be enabled by setting the PORT bits corresponding to the SCL and SDA pins,
as explained in the I/O Port section.

Looking up the Arduino Wire library code I see the following:

The Wire.begin() & Wire.begin(int address) functions both call twi_init() which contains the following code:

// activate internal pullups for twi.


digitalWrite(SDA, 1);
digitalWrite(SCL, 1);

I understand from the above that ATmega328P based Arduinos do have pull-up resistors enabled when using the Arduino Wire
library for the SDA/SCL pins and thus should not be used on a 3.3V i2c bus without a logical level converter.

converted by Web2PDFConvert.com
What am I missing?

Reply

Bill Harvey
26th June 2015 at 10:50 am

I am about to connect a Rapsberry Pi Model B to an Arduino Nano ATMega-328P to control motors connected to the Arduino via
a Web Page using Apache on the RPi.

Reading you post can I do this with or without a Logic Level Converter and if so which type? What about Serial connection via
USB?

Reply

sandeep
20th November 2014 at 7:34 am

hi oscar,
i did all you posted and everything is ok, but whenever i run python code it gives error like these

root@raspberrypi:/home/pi# python test19.py


enter 1-9: 1
Traceback (most recent call last):
File test19.py, line 21, in
writeNumber(var)
File test19.py, line 9, in writeNumber
bus.write_byte(address, value)
IOError: [Errno 5] Input/output error
root@raspberrypi:/home/pi#

Reply

Oscar Post author


21st November 2014 at 4:57 pm

because the device of that address you are sending the data to is not there. please google the error before asking.

Reply

Milliways2
8th November 2014 at 4:41 am

converted by Web2PDFConvert.com
A c++ version of the test program

// I2cTest
//
// Based on https://oscarliang.com/raspberry-pi-arduino-connected-i2c/
// Requires WiringPi http://wiringpi.com/

#include
#include wiringPi.h
#include wiringPiI2C.h

const int address = 0x04; // This is the address we setup in the Arduino Program
int fd;

int writeNumber(unsigned value) {


return wiringPiI2CWrite(fd, value);
}

int readNumber(void) {
return wiringPiI2CRead(fd);
}

int main(int argc, const char * argv[]) {


unsigned int var;
int number;

fd = wiringPiI2CSetup(address); // Automatically selects i2c on GPIO

std::cout <> var;


while(var) {
writeNumber(var);
std::cout << "Arduino, I sent you " << var << std::endl;
number = readNumber();
std::cout << "Arduino, I received a digit " << number << std::endl;
std::cout <> var;
}
return 0;
}

Reply

Lin
17th September 2014 at 4:18 am

Hi, im new bie with raspberry.

converted by Web2PDFConvert.com
I want to connect it to my arduino uno using i2c.
my question is:
1. 04 is the address we dened in the Arduino sketch. > so couldnt we change the address to 01 or 02 or ?
2. I send data from arduino to raspberry.
So i make counter in arduino then i send that counter to raspberry.
So far is it running well, my counter is 1,2,3,50,90,110,255 is it ne and raspberry can show data correctly.
But when it takes 256, raspberry turn into 0.
What happen with that? is it raspberry just can show my counter till 255? what causes it?
Thanks

Reply

Oscar Post author


17th September 2014 at 12:16 pm

1. yes you can, from 0x00 to 0xFF I believe


2. because you are sending a byte (8 bits), which can only be 0 to 255, when you send 256, it overows, and it will go back to 0.

Reply

chichara
15th September 2014 at 4:29 am

Hi, is it possible if 1 raspberry as a master connected to 5 arduino as a slave using i2c communication?

Reply

Oscar Post author


15th September 2014 at 10:18 am

yes it is possible.

Reply

chichara
17th September 2014 at 4:56 am

Hi, so where i can connect pin SDA SCL? coz in raspberry just have one SDA and SCL.
Or GPIO can set as SDA SCL?
*sorry im beginner with this.

converted by Web2PDFConvert.com
Oscar Post author
17th September 2014 at 12:21 pm

same SDA SCL pins.


the RPI can identify each slave by their unique address.

Brian92127
7th August 2014 at 3:07 am

Excellent tutorial!
As a tip for anyone else trying this one: if you copy/paste the python code make sure you delete all of the spaces and replace
them with tabs. For every 4 spaces I deleted I replaced them with 1 tab. Eight spaces deleted equals two tabs, and so on. Also,
there are a couple of blank lines that are not actually blank. Python recognizes a space and will choke on it so make sure to
delete/remove the spaces from the blank lines as well. Thanks again Oscar!

Reply

Oscar Post author


7th August 2014 at 12:20 pm

yes, it is a problem with python source code on my blog, it somehow changes the indentation of the code and python relies on
it
Thank you for the tip!

Reply

eco_bach
18th July 2014 at 7:57 pm

Hey Oscar. Great post!


But 2 problems.

1- Sending values larger than 255!

2- Sending a continuous stream of data . My goal is to send MouseXY data in realtime.

Since I am a novice arduino hacker, havent made much progress.

Reply

Oscar Post author


21st July 2014 at 10:03 am

converted by Web2PDFConvert.com
Hi eco_bach,

depends on what the possible maximum number you would send, then you should work out how many bytes of data needs to
be sent, in order to represent that max number. For example if you send 2 bytes of data, it represents a number between 0-
65536.
And now, modify the receiving side code, as you will expect to receive 2 bytes of data every time.

Reply

Guillaume L.
5th July 2014 at 10:47 am

Thanks!

Perfect tutorial!

Two reamarks :
ll /dev/i2c* required the uncommented alias ll in le .bashrc (or using ls -la)

If you use a Arduino Leonardo pins are :


Pin 2 (SDA)
Pin 3 (SCL)

Reply

Oscar Post author


5th July 2014 at 11:44 am

Cheers Mate! :)

Reply

Mike W
23rd February 2015 at 2:15 pm

Further, I was just following this on 2015-02-16 of Rasbian and had to use sudo to see anything under /dev/i2c.

Reply

Daniel Eriksson
29th April 2014 at 10:01 pm

Hi.

converted by Web2PDFConvert.com
I would like to share some important info regarding Wire library on Arduino. I spent many hours debugging communication on
the Raspberry Pi when I randomly got IOError: [Errno 5] Input/output error.

Dont put heavy code in receiveData() function on you Arduino. This code is called from an interrupt and to execute code here
will disrupt communication. I suggest you to put received data in your own buer and close the function as soon as you can.

Like this:

unsigned char tmpBuer[120];


unsigned char currentPos = 0;

void receiveData(int byteCount){


unsigned int number = 0;
currentPos = 0;
while(Wire.available()) {
number = Wire.read();
tmpBuer[currentPos] = number;
currentPos++;
}
}

Good luck!

/Daniel

Reply

kay
29th April 2014 at 2:20 pm

Not sure if anyone said this already but that particular logic level converter is not suitable for I2C, that is why you are getting
errors. Try this one adafruit.com/product/757 from adafruit or look for I2C converters that are I2C compatible

Reply

Bobbie
20th February 2014 at 9:13 pm

Magnicent web site. Plenty of helpful info here.


I am sending it to a few pals ans additionally sharing in delicious.
And naturally, thanks on your sweat!

Reply

converted by Web2PDFConvert.com
Moises
28th January 2014 at 12:28 am

Theres denately a great deal to nd out about this topic.


I really like all the points youve made.

Reply

laviritel
7th January 2014 at 11:39 pm

Hello.
Thanks for this great tutorial. Everething works ne.
I have one question, maybe You can help me. For example, Im going to send a byte array from arduino to RPi, my array looks
like this:
sysState[0]=00000001
sysState[1]=11111111
I send it this way:
Wire.write(sysState,sizeof(sysState))
And the question is, it is possible to read this two values in Python on RPi? At moment I receive only rst value. Thank you again.

Reply

Oscar
8th January 2014 at 11:30 am

I actually tried to do that as well, but because I am not familiar with Python, and there isnt much information about i2c
communication with Python on the internet, I couldnt nd a way to do it. I would suggest reading it byte by byte if you are not
getting the answer from anyway.

Reply

Lenard
29th December 2013 at 11:36 pm

Hi, its nice post concerning media print, we all be aware of media is a wonderful source of data.

Reply

Ramonita
14th December 2013 at 3:15 am

converted by Web2PDFConvert.com
Hello, I enjoy reading all of your post. I like to write a little comment to support you.

Reply

Avinash Babu
5th December 2013 at 2:18 am

hi
can we connect multiple Arduino Uno boards to Rapberry pi ? can you provide any link or explain procedure for connecting
multiple Arduino uno boards to Raspberry pi ?
thanks for your help in advance..

Reply

Oscar
5th December 2013 at 9:17 am

yes, like I said in the post you can link up to 128 devices. You just need to assign each on with a dierent address. sorry i cant
give you more explanation right now, hope that helps.

Reply

panic
30th November 2013 at 5:06 pm

Hi i have absolutely the same issue here i dont get it. did you nd a way to manage multibyte send from arduino ??
thanks

Reply

Balazs
12th November 2013 at 5:03 pm

Hi!
I would like to transfer multiply bytes at once. With the python method bus.write_block_data() I was able to do this in direction
to Arduino.
But I cannot transfer more bytes from the Arduino. I guess I should use the Wire.write(resultBuer, resultLen); on the Arduino
side, but bus.read_block_data() does not make the Arduino to enter the sendData() callback.
Anyone has a hint on this?
Thx,
Balazs

converted by Web2PDFConvert.com
Reply

boy
17th October 2013 at 8:56 am

I have a bit of a trouble here.

I did all the instruction until i2cdetect -y 1 in the terminal


and it shows the address 04.

The problem is when I tried the program above no matter what I wrote the arduino would not response . I have no idea what is
wrong. I tried update and upgrade the Rpi the result is still the same. Is it possible that the pi is broken?

Thanks in advance for the answer

Reply

boy
22nd October 2013 at 7:24 am

I managed to solve the problem, seems like the psition of variable print in the code needs to be parallel with number. Thanks a
bunch for the code

Reply

shivam
16th February 2016 at 5:56 pm

Hi boy,

I am facing the same issue

Can you please let me know the exact code to which you are referring?
where is this variable print?

Thanks in advance for your help

shivam
16th February 2016 at 6:22 pm

Hi boy,

converted by Web2PDFConvert.com
I made it worked

Few indention mistakes.

Brian
6th October 2013 at 3:53 pm

Absolutely AWESOME article. I was able to get my Rpi rev2 talking to my arduino micro in no time and your sample code and
instructions were spot on!
One problem I encountered was a sequence issue resulting in Rpi not booting up.
When physically wired between Rpi GPIO and Arduino you MUST have Ardiuno code running and it be available for
communication. If not, my Rpi would lock up in boot. Took me a little while to gure out and was a bit alarming at rst but
quickly gured it out.

Thank you for this AWESOME tutorial on i2c with Rpi and Arduino!

Reply

John
6th October 2013 at 12:28 am

I dont know how the Sparkfun converter is made, but the circuit in the Philips AN97055 document works perfectly using your
code between the Pi and Arduino.

http://www.nxp.com/documents/application_note/an97055.pdf

Reply

Oscar
10th October 2013 at 11:24 am

great to hear that, but it works without one anyway (its been a while and its still running)

Reply

Frans Merrild
26th August 2013 at 7:41 pm

Hi,

I am doing a new project with the Raspberry PI, and we are doing a sensor board consisting of PIR, IR, temperature, humidity, air
quality sensor, siren, andcamera.

converted by Web2PDFConvert.com
What do you think would be the best way to integrate these sensors to the Raspberry PI. Do we need to have an external
processor board, or might we just as well connect all of these directly to the Raspberry PI?

Reply

Oscar
27th August 2013 at 11:09 am

is it like a weather station kind of thing? :-)


I think you can get those sensors with I2C communications, and connect them directly to the raspberry pi!

this sounds very interesting I might do a separate post for it!

thanks for sharing the idea.

Reply

Marcelo
20th August 2013 at 12:43 am

Try to use only the TX of the Logic Level converter from Sparkfun.
TX are bi-directional.
RX are uni-directional.
GPIO0 (SDA) | TX1 TX0 | A4 (SDA)
| RX0 RX1 |
3.3V | LV HV | 5V
GND | GND GND | GND
GPIO1 (SCL) | TX1 TX0 | A5 (SCL)

Reply

udelunar
19th August 2013 at 6:00 pm

Hi!!
i try send string, but i cant :(. how i send??

Thx!!!

Reply

Kostas Maragos
31st July 2013 at 10:39 am

converted by Web2PDFConvert.com
Hey Oscar, thank you for this great post.

I nally got to trying it out myself and I had trouble getting it to work on my Raspberry Pi running Arch Linux. The package
python-smbus does not seem to be available for Arch Linux.

After some research, I decided to give Quick2Wire a try. After modifying the code, it worked like a charm. I have created a
repository on github (https://github.com/kmaragos/raspi2cino) hoping it might help others. FYI, I have tested this with an
Arduino Pro Mini, Nano and Uno.

I have included the URL to your post. I hope it is ok with you. Let me know if there is any other specic attribution method I
should use. Thanks again for an amazing tutorial!

Reply

Oscar
31st July 2013 at 10:44 am

Hi Kostas

Absolutely ne, thats very kind of you created a open source project for this! :-)

Cheers
O.

Reply

Pablo Torres
30th July 2013 at 11:28 am

Hi, sorry to disturb you, I have a very important question, I have a project in my house where I use an arduino board in each
room to control everything that is on that room. I want to command this arduinos (8) from a tablet running android, how can i
do it? Using wi on each one? Using Bluetooth on each one? Using one as a master and connecting this one to the rest and to
the tablet? Doing the same but using a raspberry pi? Can you help me? Just point me the direction you think its better. Thanks so
much

Reply

Oscar
30th July 2013 at 11:47 am

You are limited to 2 choices by the Androoid Tablet, Bluetooth (BT) or Wi.

BT is quite easy to use on Arduino, but its very range limited. Not to mention you have 8! I am not sure if Bluetooth can support
that many connections at the same time on the Arduino (i have not looked into this)

converted by Web2PDFConvert.com
Another option would be wi. Its not common to use wi on Arduino (have not seen people implemented this) what are you
controlling in each room?

I personally would use Raspberry Pi to replace the Arduinos for what you described, because it supports wi (which has longer
range than BT), and all clients can connect to the network at the same time. If you are short of GPIO or need Analogue I/O, you
can always extend it by adding new components.

Reply

tweety
22nd July 2013 at 2:41 pm

Hello Oscar,

Very good tuto. Tested and working. But is it really safe AND reliable ? Reading on internet, some says yes some say no ! Im
quite lost.

And what do you mean by Remember though that if other I2C devices are added to the bus they must have their pull-up
resistors removed. I have a ds18b20+ sensor. You mean that I dont have to use the 4.7k resistor ?
Do you have a sample schema for connecting those other i2c devices.

@Dantheman2865 : you mean the spakfun module is not working for linking raspberry and arduino ?

Reply

Oscar
22nd July 2013 at 2:49 pm

hey~ thanks for the comment.


It is very controversial whether we should connect both devices directly.

Like I explained there are pullup resistors on the Pi, so in theory it should be okay (I have been using this conguration since I
wrote this tutorial, I have not had any problem with it yet.)
But if you are not condent and doesnt want to take the risk, USE a level converter. They are so cheap (~$1) so there is no
reason why you shouldnt do more to protect your pi.

Reply

Dantheman2865
18th July 2013 at 8:55 pm

I think the reason your Level Shifter doesnt work is because its uni-directional. If thats the Sparkfun Level Shifter, you need to

converted by Web2PDFConvert.com
use Transmit and Receive properly based on the circuitry involved. I2C has one uni-directional signal (Clock) and one *Bi*-
directional signal (Data). There is some circuit theory behind this, but here is a product that will work for you:
https://www.adafruit.com/products/757

Reply

Oscar
18th July 2013 at 11:47 pm

that could be the reason, I didnt really look at the specication when I was using it, so you might be right!
Thanks for the pointing that out! :-)

Reply

merill
6th August 2013 at 1:11 pm

For me, the line with resistor is uni-directional but the line with the transistor is bi-directional.
When im using it, i let the two resistor-line alone and i use the two other (extreme Right, extreme left).
Less hassle.

Reply

Gus Smith
16th July 2013 at 4:59 am

Just tested it and the code works ne!

Cheers,
Gus

Reply

Jason
15th July 2013 at 5:42 pm

Hello!
I really appreciate your entry and the help it provides!

One note, though in Python, the Print command requires a value set by print(value).

You leave out these parentheses, which will trigger syntax errors if left.

converted by Web2PDFConvert.com
Thanks again!

Reply

Jason
15th July 2013 at 7:52 pm

Actually, it looks like I was wrong. In this case, it can work without the parentheses, although I do think it is more hardy if you
leave them in. This will allow the code to function even if there is a mistype somewhere along the way.

That said, the code printed above DOES WORK (woo!) and the only reason you would need the parentheses is if you did
something dierently.

Reply

Oscar
15th July 2013 at 8:29 pm

thank you for the comment, I am not familiar with Python, so I dont really know if leaving the parentheses would cause any
problem potentially, but it did work like you said. Anyway, what I was trying to achieve with print without any argument is to
create a newline, so if any problem occur because of this, we can just add to it as argument i guess

Piero
14th July 2013 at 10:23 pm

Hello,
thanks for this nice tutorial.

Im trying to make it work, with Rpi REV1 and Arduino 2009/Arduino UNO. Connections are ok (I think), because when I run
i2detect -y 0 I see this (Ihave two MCP23017 also connected to i2c):

$ i2cdetect -y 0
0123456789abcdef
00: 04
10:
20: 20 21
30:
40:
50:
60:

but when I run the python script, I see:

converted by Web2PDFConvert.com
python i2c_arduino.py
Enter 1 9: 1
Traceback (most recent call last):
File i2c_arduino.py, line 24, in
writeNumber(var)
File i2c_arduino.py, line 10, in writeNumber
bus.write_byte(address, value)
IOError: [Errno 5] Input/output error

any suggestion? I missed something?


Thank in advance for you help

Reply

Oscar
14th July 2013 at 10:41 pm

sorry I dont have a Rev1 Rpi, so I cant replicate your problem. have you tried the commented out function:
bus.write_byte_data(address, 0, value)

Also, make sure the cabling is correct, because the pin arrangement has changed from Rev1 to Rev2.

Reply

Piero
20th July 2013 at 11:14 pm

Hello,
thanks for your answer and sorry for my late reply

It was my NEWBIE and distraction error I have REV 1 Pi, so


bus = smbus.SMBus(0)
and not
bus = smbus.SMBus(1)

:-)

now all seems to be working ne, thanks again

Oscar
21st July 2013 at 2:35 am

converted by Web2PDFConvert.com
oops~ :-D
Thats so nice of you letting me know!
Grazie tanto!

Clayton Lambert
1st July 2013 at 8:22 pm

Hey, thanks for the great walkthrough! I got it working no problems with continuous servos and leds for a robot. Im looking for
another guide to help me make a web gui which can interface with this setup (and can also do video) any suggestions?

Reply

Oscar
1st July 2013 at 9:03 pm

Hi, I think thats a very interesting idea to create a web GUI to enhance this project! I might actually do some work and write a
post on this (just a thought)

If I was going to do it
1. I will setup a web server on my laptop/PC, maybe using Apache.
2. Build the web GUI in HTML/PHP/Javascript, you will be using this GUI on your client (laptop/PC)
3. We can send data from the Pi to the web server using GET or POST in Python, which can be interpreted in PHP on the server.
4. That data will be sent to the web GUI client from the web server.

does that make sense? Any better idea?

Reply

Clayton Lambert
15th July 2013 at 2:17 pm

That makes perfect sense. Im just a bit of a novice when it comes to programming especially when it comes down to
multiplatform interfacing. If you could create a guide I would greatly appreciate it. Using your modied code I was able to
remotely drive a arduino-pi robot around my room over wi from the inputs into python while my laptop was vncd into the
raspberry pi. It works ne but a web based gui would be much slicker. Thanks in advance!

Jon
30th June 2013 at 3:04 pm

Thanks for the tutorial. Im having a bit of trouble, though. My pi is recognizing my arduino when I type i2cdetect -y 1, but when

converted by Web2PDFConvert.com
I run the python script, nothing seems to be sent or returned. In order to get the py script to work properly, I had to tab over
lines 25 33. I dont know python, but I dont see how that could have aected the I2C the script ran and asked for a digit, but
the Arduino doesnt show anything. Id appreciate any help. Thanks!

Reply

Oscar
1st July 2013 at 9:09 pm

by tab over you mean create indentation? I dont know Python very well either, but I do know that Python is very strict about
line indentation. Because it doesnt use the semi colon ; like C or C++, wrong indentation could make your code get executed
completely dierently.

Reply

fm3391
3rd June 2013 at 5:05 pm

I followed this tutorial but I have a problem where no matter what integer I put in, I get the integer 9 back.
Example:
RPI: Hi Arduino, I sent you 1
Arduino: Hey RPI, I received a digit 9
or
RPI: Hi Arduino, I sent you 7
Arduino: Hey RPI, I received a digit 9

Reply

Oscar
3rd June 2013 at 5:28 pm

really did you check on your arduino terminal? what number do you get there?

Reply

Goe
3rd June 2013 at 9:19 pm

I have the same exact problem. No matter what integer I put in, I get integer 9 back. Im on Rev. 1 of Rasperry Pi, and Im using
I2C Bus 0.

Reply

converted by Web2PDFConvert.com
Goe
3rd June 2013 at 9:33 pm

On the Arduino Serial terminal, this is what I see if I send a 6:


Ready!
data received: 0
data received: 6
data received: 1

For some reason, 2 additional bytes are always sent a 0 in front, and a 1 behind the byte that I select.

Goe
3rd June 2013 at 9:46 pm

Figured it out for some reason, the python code was not working properly.

Had to replace the write_byte_data() with write_byte() and the read_byte_data() with a read_byte() for things to nally work. Not
sure why Im new to i2c

Oscar
4th June 2013 at 1:21 am

you are absolutely right, the write_byte_data() has a cmd parameter, its part of the data transferred, thats why you are getting
the extra byte zero.

This is entirely my fault, I made a change in the codes, updated this post a couple of days after it was posted. I think I must have
forgotten to update the Python code. I will do so now. The reason for the change is that I am still not condent with the
write_byte_data() function (couldnt nd any good documentation about it), thats why I used write_byte() as well at the end.

Thank you very much for pointing that out!

Leave a Reply

Your email address will not be published. Required elds are marked *
Comment

converted by Web2PDFConvert.com
Name *

Email *

Are you Robot? *

1 = ve

Post Comment

I don't look at blog comments very often (maybe once or twice a week), so if you have any questions related to multirotor
please post it on this forum IntoFPV.com... You're likely to get a response from me faster on there.

MULTIROTOR FPV TUTORIALS

SPONSOR

converted by Web2PDFConvert.com
SPONSOR

JOIN ME !!!

RECENT POSTS

Frsky XM+ Plus Receiver The best Frsky SBUS RX for micro builds?
The XM+ radio receiver is a tiny SBUS diversity RX from

Realacc HUBOSD PDB Overview


Just bought myself a PDB that has integrated OSD with current

DYS 4in1 F20A ESC Overview


DYS is releasing a new 4in1 ESC, the F20A. In this

Top 5 Best Mini Quad ESCs in March 2017 #1


We get many requests to recommend ESCs for mini quad, so

Forum Highlights #1 Soft Mounts, Realacc X210 Pro, Chameleon, FuriousFPV new products
In this IntoFPV forum highlights, were featuring a discussion about soft

REVIEW AND NEWS

FlyingMachines Indestructible Antenna 5.8Ghz for FPV Review


In this post we are testing some high quality, hand made antennas from

Connex Prosight HD FPV System


Connex Prosight is one of the first HD solutions for FPV

Review and Build: Hibernagen Menel X 3 Mini Quad Frame


We reviewed the 5 inch Menel Mini Quad frame not long

Review: AWESOME Youbi XV 130 FPV Racing Drone


The Awesome Youbi XV-130 is a BNF 3 inch brushless micro

converted by Web2PDFConvert.com
FX796T Video Transmitter VTX 5.8GHz 40CH
Not really a review, just wanted to show you my new

More Reviews

DIY AND HACKS

ATTiny Analog Comparator Checking Voltage Level


To read a voltage we usually need analogue input. Unfortunately, the ATtiny4313

DIY PSU for LiPo Charger and Workbench


Some modern LiPo chargers are able to charge multiple battery packs

Build an Arduino shield for Quadcopter Arduino Adapter


I have been searching for ideas of making a Quadcopter Arduino

Different Lens Options for Runcam Swift FPV Camera


I have seen some lens comparison for the HS1177, so I

Replace GoPro LayerLens From GetFPV


Got the Layerlens protection for my Gopro Hero 3 Silver from

More DIY and Hacks

TUTORIALS

RC Radio Receiver Protocols: PWM, PPM, SBus, DSM2, DSMX, SUMD


When it comes to radio receiver protocols, acronyms are often used:

What FC Looptime should I use?


This article explains what FC looptime is and whether faster looptime is

3D Inverted Flying with a Quadcopter


Have you seen 3D RC Helicopter flying? Do you know that

Motor Timing
I came across some discussion on motor timing and thought I

Info about Angled Motor Mounts for Multicopters


Angled motor mounts allows the motors on a quadcopter to tilt

More Tutorials
Follow 775 Follow me on Google+

ONLINE VISITORS

converted by Web2PDFConvert.com
globe can't be displayed
Live Stats

SUBSCRIBE MY BLOG RSS FEED

RSS - Posts

Oscar Liang 2013-2017

We use cookies to ensure that we give you the best experience on our website. If you continue to use this site we will assume that you are happy with it.
Ok

converted by Web2PDFConvert.com