Wednesday, 12 March 2014

Connecting Raspberry Pi to Arduino using the Serial Port

This is certainly not the first Article explaining how to connect a Raspberry Pi to an Arduino using serial communications, but I wanted to share with you my experiences on this subject....

As my previous work with the Arduino has centered around serial communications, I wanted to use the hardware serial port on the Rapsberry Pi instead of using any USB ports.  I already have my keyboard & mouse plugged into these ports!


Starting with the Hardware


To safely connect the Raspberry Pi to an Arduino (or any native 5-Volt based microcontroller) using serial communications, you really should incorporate a logic-level shifter to ensure  the +5V will not harm the rather delicate Raspberry Pi, which of course is an unprotected, native +3.3V device:


Logic converter - Raspberry Pi feeds the low voltage (+3.3V) side, Arduino feeds into the higher (+5V) side:


These logic converters are generally bi-directional devices, and really do simplify voltage translations.  The one used here was produced by HobbyTronics in the UK, but Adafruit also manufacture an equivalent.

Both TX and RX lines are crossed over here - swapping the TX line from one, becomes the RX signal for the other device.

A close up of the Raspberry Pi serial connections - GPIO header pin 8 UART TX (yellow), GPIO header pin 10 UART RX (green), power 3.3V (red) and GND (black):


Arduino wiring - Digital Pin 0 RX (green), Digital Pin 1 TX (yellow) and power.  All other digital I/O pin connections are for the Armdroid 8-bit parallel interface:


I'll follow up with a schematic for the above, later, but I'm afraid, I simply don't have time at the moment as I'm trying to get everything ready for the Raspberry Jam on Saturday.


Software Configuration


With the hardware now sorted, you need to configure your Raspberry Pi to use the Serial Port in your own applications.

The reason for this is because by default, the serial port is used for Console Input/Output, and the kernel also sends diagnostic information to this port when booting the system.

To enable the serial port for your own use, you need to disable this by editing  /etc/inittab

Simply comment out (adding a # character to the beginning of the line):
T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

To look like:
#T0:23:respawn:/sbin/getty -L ttyAMA0 115200 vt100

Save the file.  The next step is optional, but i would recommend you do this otherwise the device connected to the other end of the serial port will receive startup information.

Edit the file  /boot/cmdline.txt

Locate the following line:
dwc_otg.lpm_enable=0 console=ttyAMA0,115200 kgdboc=ttyAMA0,115200 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

And remove all references to ttyAMA0 (which is the name of the serial port device) to look like this:
dwc_otg.lpm_enable=0 console=tty1 root=/dev/mmcblk0p2 rootfstype=ext4 elevator=deadline rootwait

Save the changes, and reboot the system.


Testing


Normally, testing with minicom at this stage should result in your Raspberry Pi communicating with your connected serial device....  but this wasn't happening for me....  I checked the baud rate (9600) and all the other connection settings, but nothing made any difference.   Then, after carefully checking the wiring, which appeared to be good, I was well 'n truly stumped.

To install minicom if you don't already have it installed, its as simple as typing:
sudo apt-get install minicom

This can then be executed by the following command:
minicom -b 9600 -o -D /dev/ttyAMA0

All characters type will be transmitted to the serial port, and all characters received will be displayed on the terminal, type Ctrl+A and Q to finish.


So, after a couple of hours of probing with my logic probe and multimeter, I was really struggling to explain why my Arduino wasn't responding.   On one hand, I had an Arduino connected to my laptop, and that was working perfectly, and on the other, a Raspberry Pi which wasn't working.

I then started doubting my Raspberry Pi was functioning properly, so after convincing myself that I've blown up the GPIO port by earlier experiments, and without having a spare Pi at hand to test....   I Google'd  local suppliers from which I might be able to quickly purchase another Raspberry Pi.

My travels lead me to Cyntech Components, based locally in Milton Keynes:


Normally, they operate from an online store - if these guys didn't accept visitors, I was willing to beg, plead, do anything, to get my hands on another Raspberry Pi.   Fortunately, when I called them up, Dave (the proprietor) said no problems.... so off I jumped in the car and made a visit...

I purchased another Raspberry Pi Model B, and was also tempted into a few other accessories whilst I was there...


The packet in static sensitive bag is an add-on relay module, this will actually come very useful for something I have planned for later in the year - you will have to wait and see what that will be....   Anyway, Dave was very welcoming, so do give these guys a call if your needing accessories.

Once back home, I quickly swapped the Pis over, and guess what happened... still nothing!

I was now scratching my head....  Before giving up, and just heading down to the local boozer for the rest of the afternoon (I had the day off work you see)....  I suddenly ended up finding something on Arduino's website about the board I'm using, the Ardunio Leonardo

Arduino Leonardo - Product Overview

which says (see Input/Output section)  "Note that on the Leonardo, the Serial class refers to USB (CDC) communication; for TTL serial on pins 0 and 1, use the Serial1 class."

I then suddenly realized why transmitting over USB resulted in nothing being transmitted through the hardware serial port pins.   This Leonardo board must be slightly different to other models, and the USB port is treated completely differently to the hardware based serial port.   Doh !!!

Changing my program code on the Arduino to talk to Serial1 instead of Serial, and that resolved the problem....   So, there you go, moral of the story....  RTFM !!!   :-)


Finally, a photograph of the completed, and very much working Raspberry Pi / Arduino based Armdroid interface circuitry: