Raspberry Pi - Arduino - Link the two via the I2C bus

Warning : This article has been automatically translated by Bing Translate


Danger : This article has been automatically translated by Bing Translate


Caveat : This article has been automatically translated by Bing Translate

Some say that it not dogs with sausages but sometimes why not binding. Then Raspberry Pi and the Arduino are not necessarily also opposed, with even points in common but each benefits that can be good to combine.

RaspArduinoI2CWith Raspberry Pi you can via ports GPIO control external components and of the hack in electronics. But I imagine that some already have mastered their Arduino, they have the equipment, etc. Et puis ça fait un tuto en plus 😀

To bind the two, We will pass by the I2C Protocol. Several reasons for this : do not use the USB port, Raspberry Pi is limited (If you want to do it anyway there is an article in the MagPi #15 and I will make a myself later). And do not use the serial port. Here it's a little more personal, because I have a card Slice Of Pi on a Raspberry for the weather station and it uses the serial port for wireless sensors.

The I2C Protocol, created by Philips with a home orientation, allows several components to interact between them in a bidirectional way but half-duplex only. As usual, more info at Wikipedia.

There is a principle of master and slave. Here so we will use Raspberry Pi as master and the Arduino as a slave.

Primarily to connect two devices need to know what pins to use !
For the raspberry is on the GPIO 2 and 3 (for maps from model B revision 2, those with the mounting holes in the map)

raspberry-i2c

For the Arduino, It happens on the A4 and A5 pins for the Arduino Uno type cards. For other cards, You can find more information on the official Arduino site.

arduino-i2c-2Need to add a connection to the mass between the two. So you need three wires.

Before connecting our two devices, It must be ensured that they will be able to communicate. All the information is on the site of adafruit but wholesale, Here's what to do.

Define the Arduino as a slave

It is relatively simple by including the Wire module in the program. I took the address 0 x 12 but you can choose 0 x 0 x 77 03 (in hex) :

#include <Wire.h>
#define SLAVE_ADDRESS 0 x 12 int dataReceived = 0;
void setup() {
    Serial.begin(9600);
    Wire.begin(SLAVE_ADDRESS);
    Wire.onReceive(receiveData);
    Wire.onRequest(sendData);
}
void loop() {
    delay(100);
}
void receiveData(int byteCount){
    While(Wire.available()) {
        dataReceived = Wire.read();
        Serial.print("Data received : ");
        Serial.println(dataReceived);
    }
}
void sendData(){
    int send = dataReceived + 1;
    Wire.write(sending);
}

You'll understand, the program Initializes the Arduino with address 0 x 12, defines the method of receiving data, the method of sending data and go to send it to the card with the interface.

Enable management I2C on Raspberry Pi

By default, distributions of type Raspbian disable I2C management to save the memory used by the module. To re-enable, It's easy and it is in the file /etc/modprobe.d/raspi-blacklist.conf. Need to be commented out with a # the line :

blacklist i2c-bcm2708

Rest to enable the module each time you start. It is in the file /etc/modules, by adding at the end a new line :

I2C - dev

Then you install the suite of management I2C tools

apt-get install i2c-tools

You will have to restart the Raspberry to appear two files :

1._ssh-2
Thanks to them you will be able to communicate on the I2C bus !

You can list devices with the command :

i2cdetect y 1

For 256 MB models (as one that I used for my tests) :

i2cdetect y 0

Voilà. Next step : connect the Arduino and talk to him !

Communicate with the Arduino

You can now connect the Arduino to the Raspberry and turn all this small world !

Attention, on the schema, SDA and SCL connection is reversed ! Le rouge en A5 et le balnc va en A4 😉

ArduinoRaspberry

Once done, you log on to the Raspberry Pi and you restart the command i2cdetect with the proper parameter :

1._ssh-2

The setting in the sketch to the Arduino, 0x 12, appears in the detected devices. It progresses !

We now need to implement the script on Raspberry Pi who will send/receive with the Arduino. For this, the simplest is to install the support of I2C in Python scripts. This is what will make python-smbus

apt - get install python-smbus

We are now equipped to speak to our Arduino. For this a small program everything simple. Send a digit between 0 and 8 and return us this number plus one :

smbus import time import
# Replace 0 by 1 so new bus Raspberry = smbus.SMBus(0)
address = 0 x 12 print "The value sent 3"
bus.write_byte(address, 3)
# Break 1 second to allow time for the treatment to be time.sleep(1)
response = bus.read_byte(address)
print "The response of the arduino : ", response

The result of the execution :

1._ssh-2

Let talk your imagination to now lead the Arduino by sending applications a little more complex depending on what you plugged it !

Source and inspiration : a section d’Oscar

You may also like...

  • ubik75

    Hello,

    After reading the article, I wonder if should be added between the raspberry and the arduino a logical to protect 3, 3V-5V arduino Pi ?

    • I asked myself the question if I not spend the Arduino in 3.3 but it seems that it is not necessary. May be that experts will confirm (or not)

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

      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, it’s 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.

  • Actually : si l’Arduino est en maître, il enverra du 5V et là le RPI va avoir très mal.
    Dans le sketch de l’Arduino, il manque le +1 pour le tuto. Toujours sur l’Arduino, il est formellement déconseillé de faire un Serial.print dans une interruption : ce qui est le cas (être dans une interruption) dans receiveData et dans sendData => It can completely enfoirer the program and “plant” the Arduino. The I2C connectors are also available on the other side the Arduino, just after GND and AREF (It is written below the Arduino Uno).
    Why not also manage interruption side RPI ? (rather the sleep of a second which is just ugly) This is python which does not ?

    • Tutorial corrected, Thank you.
      Thanks for all these tips. I do not quite know the Arduino to control everything. The purpose of the tutorial is to connect the two and use it as basis for further. Thanks much for the Info, je vais regarder comment remplacer le sleep tout moche 🙂
      La prochaine étape sera d’avoir une liaison sans fil donc au revoir I2C 😉

  • Julien

    Attention, on the schema, SDA and SCL connection is reversed !

  • Paul

    Hello,
    I'm in class Terminal sti2D and we have a project for the tray that is to manufacture a CCTV camera can be controlled remotely (System android for example) and that can make a TILT/PAN.
    We thought so connect Arduino and Raspberry via I2C following your method.
    The problem is that we do not know how to order the 2 actuators to move the camera….
    Une aide de votre part ne serait pas de refus 😉
    Thank you

    • Hello,
      Need you an H-bridge if I am not mistaken : L293D
      There is a tutorial here : http://myrobotlab.net/tutorial-control-a-dc-motor-with-raspberry-pi/

      • Kelias

        The L293D is useful for a DC motor that will run continuously, which is not normally the case for an actuator.

        Personally I have been following this article and it worked very well
        http://forum.pcinpact.com/topic/165594-raspberry-pi-fabriquons-des-trucs/page-3#entry2750001

  • Raspbian

    Hello ,
    Premierement super tuto merci 🙂

    I have a small question,
    I receive multiple values on my arduino is make it possible to send the 2 values at the same time on the i2c bus ?
    Thank you

  • Thibault

    Hello, According to some site should use a converter between the arduino and the raspberry because l’ one would work in 5v and 3v.
    Is this the case ?

  • Thibault

    Sorry I had not read the previous comments. Apparently no need.

    However when I do an i2cdetect I not have a digit in the “table” but I have all that is filled. And the arduino pe returns 0 and the arduino displays as data received -1

    • It will come either a wiring problem or a bug in the module if the 1-wire protocol modules are loaded (W1-gpio, W1-xxxx)

  • Jody

    Hello,

    Thank you very much it works !

    For info if you get like me :

    root@raspberrypi:/home/pi# python testI2c.py
    Envoi de la valeur 3
    Traceback (most recent call last):
      File "testI2c.py", line 9, in 
        bus.write_byte(address, 3)
    IOError: [Errno 5] Input/output error
    

    Consider switching :

    bus = smbus.SMBus(0)

    en

    bus = smbus.SMBus(1)
    • Yes the 0 is for the model A and B revision 1. The 1 is for the model revision B 2

  • I'laam

    Hello,
    Merci pour le tuto 🙂
    I would like to connect an RPI to another electronic plate (non-marketed) in I2C with the RPI in slave mode. I also that the RPI communicates with the master each time with a different address as the address that asked the master. Is it possible to assign multiple addresses to the RPI?
    Thank you

    • On the principle of the I2C device cannot have 2 addresses. Dans la programmation i2c je suis pas expert 😉

      • I'laam

        D’accord merci pour votre réponse 🙂

  • I'laam

    Hello,
    I turn to you again.
    Voilà, I read on a tutorial that the RPi can communicate only in master mode because the linux kernel does not allow communication in slave mode (It is not yet implemented). Could you confirm if this is true ? Thank you.

    • Yes this is what seems to be the case. The kernel in him even does not support the slave mode. And even a driver should not be able to resolve the problem because the chipset used on the Raspberry (BCM 2835)

      • I'laam

        Ah it's a shame ! I think that I will use instead of an Arduino in this case. Merci bien 🙂

  • Hello friends how are,I need a program to connect an Arduino with raspberry pi which through port serial manadar 2 different signs that measure temp and another measuring Ph, How-to???? could you please help me urgent. is a project of the U I'm confused on how to do.

    • Hello,
      You have an example in the post. You can use it to define your own protocol to communicate to a data structure. Up to you to know how to get values from the Arduino sensors.

  • Pingback: C’est pour bientôt | La caverne de Zragg()

Handpicked links

disk Page Caching using disk: enhanced Database Caching 195/564 queries in 0.284 seconds using disk Served from: pihomeserver.fr @ 2017-10-09 22:51:41 by W3 Total Cache -->