The Raspberry Pi and the Arduino are both amazing, and each has its particular strengths. There are lots of projects that use one or the other, but there’s growing interest in solutions that combine the strengths of the two platforms.

We use both on C3Pi (our experimental robot). At present we use I2C to link the two, and today we found a way to simplify the way they are connected. Since there seems to be a lot of interest in this topic, I thought we’d share our approach and explain why the solution is a little simpler that we thought!

c3pi-direct-connection-427x285

The I2C software is easy

We’ve been using our Python library on C3Pi to drive the I2C bus that we currently use to connect the Pi to the Arduino. We’ve also adapted the Arduino I2C slave code which is one of the Arduino  examples.

Both programs are very simple. You can find the current versions on github. (Warning: expect the code to change rapidly as we are experimenting with new ideas!)

Linking the Pi and Arduino hardware is easier than we thought

Until today, we were using a sparkfun level shifter to connect the 3v3 I2C bus used by the Pi to the 5v I2C bus on the Arduino.

It turns out that we don’t need to, because the pull-up resistors on the Pi keep the SDA and SCL lines close enough to 3v3 to be safe, even if they are directly connected.

Until today I thought that wasn’t the case. I dimly remembered that the Arduino has pull-up resistors that are enabled by default when you use the Wire library. However, it turns out that these are weak (high-resistance) pull-ups; the Pi has strong pull-ups which dominate those on the Arduino, making direct connection safe.

This only applies to I2C. If you want to connect the serial port on the Pi to the serial port on the Arduino, you will need some protective circuitry between them. That’s why we have a level shifter on our interface board.

But for I2C, just connect the Pi and Arduino as shown below and everything will be fine!

.————-.           .————.
|  Pi         |           | Arduino    |
|          SDA|———–|SDA         |
|          SCL|———–|SCL         |
|          Gnd|———–|Gnd         |
|             |           |            |
.————-.           .————.

9 Comments

  1. Trouble is: ATmega specifies an input High voltage to be at least 0.7Vcc (ie >3.5V if Vcc is Arduino standard 5V). Consequently a RasPi I2C bus operating at 3.3V does not satisfy this. It may well work some or most of the time but will probably not be reliable at full speed across wide temperature range due to inadequate noise margins.

    Reply

    • The datasheet for the ATmega specifies a requirement of at least 0.6Vcc if Vcc (for the ATMega) is over 2.4 volts, so it’s OK.

      See http://www.atmel.com/Images/doc8161.pdf page 313.

      Reply

    • It’s not quite as bad as I thought. Apologies, I misread the Atmel spec (8161D–AVR–10/09). For a 5V (e.g. Arduino) system, the required input High voltage is NOT 0.7Vcc but 0.6Vcc (i.e. 3.0V) so the 3.3V I2C bus has 0.3V noise margin if everything is good. On the other hand, if the 5V rail is a little high, 5.2V say and the temperature is not “typical”, the noise margin will be eroded. Not a very comfortable position, in my view.

      Reply

      • You’re right, the approach is not ideal, and I would hesitate to use it in an industrial product. IMO it’s a reasonable approach for hobbyist projects.

        Reply

        • Yes, Romilly. Hobbyists should not have to pay for “mission-critical” engineering standards. In the end it’s a judgement call. I don’t remember ever being accused of conservatism by my work peers but, alas, I’m older today than ever I have been in my life (cue violins) and I can’t reasonably deny the possibility that I’ve reached the point of being stalked by conservatism. Sigh …

          Reply

  2. Reddy Kilowatt

    The Rpi has 3.3V I/O lines.

    Aren’t you concerned that the Arduino uses 5V levels on it’s I/O lines?

    We’re not talking about misinterpreting logic levels.
    It’s more of a concern that you will blow the I/O lines onthe Rpi

    Reply

    • As we explain in the post, we only connect the SDA/SCL lines. These have weak (10K ohm) 5v pull-ups on the Arduino and much stronger (1.5k ohm) 3.3v pull-ups on the Raspberry Pi. That means there is no risk of damaging the Pi.

      You are right that there is a problem with directly connecting other I/O lines; that’s why we have a level shifter on our interface board.

      Reply

  3. What type of level shifter did you have to use to get this to work?

    Reply

Leave a Reply

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

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>