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.

Level Converter Circuit

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.

Successful Communication
Successful Communication

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)

T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

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:

console=ttyAMA0,115200 kgdboc=ttyAMA0,115200

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:

echo -e "This is the text I want to display on my Arduino \r\n" > /dev/ttyAMA0

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,…

Configuring a Raspberry Pi

So I created a new image on the SD (my old one was messed up) and used the script, everything goes fine, I reboot (as instructed) and nothing. Only the OK led flickers 6 times every 5 seconds… great!

After googling I found out that start.elf could not be loaded. The entire process is as follows (combined from a couple of forum posts at Raspberry Pi forums):

  1. When the Pi is turned on the ARM core is off and the GPU core is on. The SDRAM is disabled
  2. The GPU loads the first boot loader which is stored in ROM on the SoC. The first boot loader reads the SD card and loads the second boot loader (bootcode.bin) into the L2 cahce and then runs it.
  3. bootcode.bin enables the SDRAM and then reads the third boot loader (loader.bin) from the SD card into the RAM and runs it.
  4. loader.bin reads the GPU firmware (this is start.elf).
  5. start.elf is loaded and read config.txt (the file used to overclock the RaspPi), cmdline.txt and kernel.img
  6. After kernel.img (a binary image of ARM memory starting at physical address 0 from the ARM’s perspective) and sends a reset on the ARM
  7. The kernel is loaded and the rest of the boot process is handled by init or systemd.

The script works perfectly but it also goes another mile by updating the firmware, using rpi-update. This program allows updating the rpi firmware easily using a simple command. Problem found, the rpi-update fails to write the start.elf file on the SD card (or writes it in a wrong way for some reason). I fixed the problem by just removing the rpi-update command, and everything works!

MOTD Eyecandy

I also changed the welcome message of the Raspberry Pi. SSH users now are greeted by a fancy logo and cool ANSI art eyecandy.


Just edit the following file:

[email protected]:/home/pi# nano /etc/motd.tail

And type the greeting text, when using nano it’s also possible to add color (like I did). First press ALT+V and then press ESC. This inserts and escaping character (it looks like ^[ but typing this yourself wont work). After that add the color code, example:

^[[0;32m This is green!

A full list of color codes is available here, and an ansii generator can also be used. Mine has the following:


Linux raspberrypi 3.1.9+ #168 PREEMPT Sat Jul 14 18:56:31 BST 2012 armv6l
                         .~~.   .~~.
                        '. \ ' ' / .'^[[0;31m
                        : .~.'~'.~. :
                       ~ (   ) (   ) ~
                      ( : '~'.~.'~' : )
                       ~ .~ (   ) ~. ~
                        (  : '~' :  )
                         '~ .~~~. ~'
 _____                 _                            _____ _
|  __ \               | |                          |  __ (_)
| |__) |__ _ ___ _ __ | |__   ___ _ __ _ __ _   _  | |__) |
|  _  // _` / __| '_ \| '_ \ / _ \ '__| '__| | | | |  ___/ |
| | \ \ (_| \__ \ |_) | |_) |  __/ |  | |  | |_| | | |   | |
|_|  \_\__,_|___/ .__/|_.__/ \___|_|  |_|   \__, | |_|   |_|
                | |                          __/ |
                |_|                         |___/

Now I’m ready to install some services (HTTP, FTP, PHP, MYSQL,…) I’m still looking for a lightweight server. Maybe nginx, monkey or lighthttp, apache is a bit to heavy.