Connecting an Arduino and Raspberry Pi

The use case of the GPIO pins on the Raspberry Pi are rather limited and since I have an Arduino Mega 2560 lying around I can easily connect the two. In the next couple of weeks I’ll explain my process of connecting the Arduino with the Raspberry Pi and creating some sort of Library so the Arduino can be controlled from a web browser using a Raspberry Pi.

Connection options for and Arduino to Raspberry Pi connection

There are a couple of options for connecting an Arduino with a Raspberry Pi. The first and obvious one is of course plugging the USB port in the Raspberry Pi. As easy as it sound there are some disadvantages. First you sacrifice a precious USB port and second you now need to do your Arduino development on your Raspberry Pi. Not that easy or handy after all.

There are also bridge boards like Ponte (most popular one) that allow to connect Arduino shields with a Raspberry Pi. There are also extension board for the Raspberry Pi that actually include an Arduino chip (forgot the name).

Say hello to my little friend UART

The Raspberry Pi has a UART port and the Arduino has a Serial port, match made in heaven! My Arduino works with 5V logic and the Raspberry Pi with 3.3V, whatever you do, never and never connect the two without a logic level conversion circuit!

I decided to build a circuit (its more fun!), Sparkfun Logic Level Converter is another option. I used a Bi-Directional MOSFET Level Converter, based on the 2N7000. The schematics are really easy. Edit: thanks Scott for pointing out that R3 should be 10k instead of 10.

The level converter for the Raspberry Pi

When the low side (3.3V) transmits a logic one the MOSFET is tied high (off) and the high side sees 5V through the pull-up resistor. When the low side transmits a logic zero the MOSFET source pin is grounded and the MOSFET is switched on and the high side is pulled down to 0V.

When the high side (5V) transmits a logic one the MOSFET substrate diode conducts pulling the low side down 0.7V, which in turns the MOSFET on. And so on. This circuit can also be used with I2C. We need two level converting circuits, one for RX and the other for TX.

Configuring the Raspberry Pi

When I started my Pi and loaded the pass through script in my Arduino, nothing happened. Normally the Raspberry Pi sends all the terminal output over the UART at a baud of 115200, but I didn’t receive anything on my serial monitor of my Arduino. I found out that my connection diagram was lacking one important connection. The Raspberry Pi ground pin also needs to be connected to the Arduino ground.

After connecting the Arduino Ground with the Raspberry Pi ground I got the following output on my Serial console.

The output of my Raspberri Pi UART

Great, the Raspberry Pi uses the UART to send out all the console information, let’s change that.

First in /etc/inittab comment out (near the end) the following line (adding # before it)

Now the terminal stops listening on the UART pins but the debug information is still send, to change this we change /boot/cmdline.txt and remove the following line:

Now save and reboot and no debugging information should be send. I now can send some text from my Raspberry Pi to my Arduino by using the following command:

The /dev/ttyAMA0 is the UART device of the Raspberry Pi. My setup is quite complicated since I use SSH to use my Raspberry Pi and the Arduino sends the information from the Raspberry Pi to my serial port.

Next time I talk about different ways to send data from the Raspberry Pi to the Arduino. Possible solutions, PHP, node.js, Python,…

23 thoughts on “Connecting an Arduino and Raspberry Pi

    • You can use a resistor divider circuit if you only send data from Arduino to the Raspberry Pi. It’s possible that the Arduino will recognize the 3.3V HIGH from the Raspberry Pi as a logic High but its also possible it wont understand it. Also if you are using a 3.3V based micro controller (like some Arduino Uno’s) then you don’t need the converter. The circuit is fairly easy and you can buy the mosfet on Ebay. Try it and let me know if it works (as long as you make sure you use the right resistor values your Pi wont be damaged).

  1. Thanks for the tutorial!

    I just have one question: after I remove “console=ttyAMA0,115200 kgdboc=ttyAMA0,115200″ from /boot/cmdline.txt and reboot, the serial connection seems to be broken.

    Before the reboot I can send text from the Pi to the Arduino, but after the reboot I just get the ø character each time I try to send text.

    Is this expected behavior?

    • Make sure you also edit the inittab file. Also check that you change:
      dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 $

      to:
      dwc_otg.lpm_enable=0 console=tty1 $

      After a reboot no debug information will be send over the UART. If you find that changing the line in cmdline.txt fails then keep it in there. Let me know if this resolved your problem.

      • Thanks for your reply!

        I had edited both of those files correctly. The problem was in the passthrough script I wrote for my Arduino. I have switched to your version and now it works perfectly.

        Thanks!

  2. Pingback: very useful things | Pearltrees

  3. Why use a bi-directional logic level shifter for UART? RX and TX are bot uni-directional. I can understand the buffered level shifter on the TX side, but you could probably get away with a diode and pull-up resistor on the Pi’s RX (although I believe there is an internal pull-up on that pin already).

    • Because the Raspberry Pi also has an SPI. I wanted an universal bi-directional logic level shifter, but you could (like you said) make a very easy circuit to connect the Raspberry Pi and the Arduino. Let me know if your circuit also worked!

  4. Pingback: Raspberry pi | Pearltrees

  5. Pingback: Wounderful Blog | Pearltrees

  6. Running the Uno at 3.3V seems to work fine (attach 3.3V output of Pi GPIO to 5V on the Uno – NOTE: *WARNING* Making sure there’s no other 5V source – USB, Battery etc – connected to the Uno */WARNING*). No level shift is then necessary. The Uno runs fine at 3.3V though at 16MHz it’s considered to be overclocking. Note also that the Uno draws about the limit that the Pi 3.3V pin can support, so don’t go trying to attach a ton of things to the Uno.

  7. “When the high side (5V) transmits a logic one the MOSFET substrate diode conducts pulling the low side down 0.7V” 5-0,7=4,3V not 3,3? Am I missed something?

    • The MOSFET is used as a “switch” so you have to look at the voltage divider (4.7k and 10k) calculate them and you see you have a voltage of 3.4V

  8. Hi Fritz,
    Love the site but I have an issue with the cmdline.txt
    I have the same issue as Robert above when I remove:

    console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

    My original looks like this:
    wc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

    Which has a lot more in it than your example above. Can you advise?

    I’m new (ish) to Linux & Programming in general so am on a steep learning curve and apologize if its a dumb issue..

    Many thanks

    • Just remove the part like I told. I didn’t copy my full cmdline.txt file so it’s normal that yours contains other information.

      • Thanks Fritz,

        But I didn’t have any success.
        I use your pass through script from bluetooth page with the cmdline.txt change.
        I just get the ø character moving across the line in arduino serial monitor with each send of : echo -e “text \r\n” > /dev/ttyAMA0

        With the lines back in I get this:
        øThis is the text I want to display on my Arduino

        Phil

  9. Hello Fritz,
    thank you for sharing this! Great idea!
    Can you give us please a hint on how to connect the Sparkfun Logic Level Converter? I would like to avoid mistakes… :s
    I think than I can connect the 5v of RPi to the Vin of my arduino uno… and ground as well..right?
    Thank you,
    dk

Leave a Reply