Raspberry Pi – RPi als Arduino HDMI Shield

arduino 2 raspberrypi

Bron @ codeandlife.com

Wat heb je nodig?
1) PyGame bibliotheek

Informatie (ENG):

Merry Christmas to everyone! Today’s hack is something that I’ve been planning to try out for a while: Using the Raspberry Pi as a (relatively inexpensive) “HDMI shield” for the Arduino microcontroller. While the Pi can easily do most things that the Arduino can and usually much more, one might have an otherwise complete project (for example, something related to home theater automation) that would benefit from HDMI output.

Arduino display shields are not the least expensive, so why not use a RaspPi instead? There have been hacks for using RaspPi as network shield, too, and this project is very much like it (actually, you could change the Pi-side code just a bit and have some network-related commands available for your Arduino in no time).

The basic hardware premise for this hack is very straightforward – wire the Pi and Arduino together using the serial interface available on both. Because Pi is 3.3V and Arduino 5V, a level converter is needed – I used one from Adafruit this time, as it’s dead simple to use and doesn’t pose the dangers of overloading Pi like my simple resistor option does (you might, however, check that link out as it contains the pinouts for RaspPi serial pins in the GPIO header).

On software side, the Pi acts as a “server”, taking simple display commands via serial link. You could even start the Pi server script and connect to the serial port with Putty, and the session could look a bit like the following:

The python server uses pyserial for serial communications, currently at 9600 bps, but the Pi and Arduino should be able to do 115 200 as well. For graphics, pygame framework is used. Current version of code initializes a 500×500 pixel graphics viewport, but one could use the parameters given by “init” command from Arduino side to define that, too. The code should be rather straightforward to understand: there are only two supported commands, “draw” with four parameters, and “quit” to exit the otherwise infinite loop waiting for draw commands (I named the file ar2pi.py):

Note that as “rect” and “quit” are only codewords recognized and rest are silently ignored, the “#” used for comments in the earlier example don’t cause any harm. To run the Python script, you’ll need to install python-serial and pygame packages using sudo apt-get install pygame python-serial, and then either give the script execution privileges with chmod and use ./ar2pi.py, or just use python ar2pi.py.

Important note: By default, the /dev/ttyAMA0 is bound to a serial terminal on the Pi, so you’ll need to disable that from/etc/inittab and reboot the Pi to free up the serial device (just locate the line that has ttyAMA0 in it and comment it out). See myprevious Pi-Arduino post for details.

Arduino-side software to send display commands to Pi

On Arduino side, only a simple sketch is needed then to open the serial line to Pi and send some drawing commands. Note that you cannot upload a sketch to the Arduino while RX pin is connected to the Pi, so you should always remove the jumper wires from TX/RX pins on the Arduino before uploading:

Pi HDMI shield in action

Below you can see the short piece of code in action. You can see me pressing enter to start the Python script on Raspberry Pi, and once the display is initialized by pygame (screen goes blank), I push the reset button on Arduino to start running the sketch, which then draws the rectangles. Once the screen is more or less filled, Arduino sends “exit” command to Pi and the Python script terminates, returning us back to terminal:

[FILPMJE TODO]

In its current form, you’ll need to manually start the Python script every time you want to try it out. A more advanced version would be a “display server” that runs continuously and uses the “init” commands to reset the viewport to the wanted size. The commands might also return some status codes. You could even make the server start upon Pi startup, so you wouldn’t need to run it manually at all.

Closing remarks

In this post, I’ve outlined a simple “HDMI server” for the Raspberry Pi that uses pyserial to receive commands over Pi’s serial interface, and pygame to display graphics primitives according to those commands. Furthermore, an Arduino client was written to send these commands to the Pi, drawing a string of blue rectangles to the screen.

For future development, additional commands to include new primitives could be added (circles, lines, pixels, bitmaps), as well as commands to set the drawing color and other parameters. Communication from Pi to Arduino could be added, for example to send display content (“getpixel x y” command) or even mouse events to the Arduino. The commands need not to be limited to display only – the server could as well fetch data from URLs, play sounds, and whatever can be achieved with the Pi (which is quite a lot).

Current framework uses text-based commands, which introduce some lag even with 115 200 baud serial line – an improved version of the framework might offer a binary protocol. The Arduino side code could be encapsulated in a simple-to-use library form, hiding the implementation details from the user. I may add these ones later, but anyone is free to continue from the current codebase – all the above code is hereby put into public domain.