Driving a 7219 LED matrix from a Raspberry Pi

Flushed with my success in getting data displayed on my cheap LED matrix using a Bus Pirate, I decided that the next step was to see if I could get it working with a Raspberry Pi. Looking around for useful resources to get me started I found:

Following the steps to install Wiring Pi, I began with

sudo apt-get update
sudo apt-get upgrade

This took at least a couple of hours (I gave up and left it running while I went to get something to eat). It seems a lot has changed since I last updated the Raspbian on this SD card!

Once this was complete, Gordon's installation page suggested installing the SPI driver using:

sudo modprobe spi_bcm2708
sudo chown `id -u`.`id -g` /dev/spidev0.*

Unfortunately, this didn't work, giving some fairly confusing errors:

pi@raspberrypi:~$ sudo modprobe spi_bcm2708
libkmod: ERROR ../libkmod/libkmod.c:554 kmod_search_moddep: could not open moddep file '/lib/modules/3.2.27+/modules.dep.bin'
pi@raspberrypi:~$ sudo chown `id -u`.`id -g` /dev/spidev0.*
chown: cannot access `/dev/spidev0.*': No such file or directory

So I gave up and went through the installation process for Wiring Pi and its tools:

git clone git://git.drogon.net/wiringPi
cd wiringPi

This worked with no errors. I then tried the suggested gpio load spi. This refused, but so much had changed on the system that I though it was probably due a reboot. After this it worked. Next step was to connect the LED matrix. I could probably have plugged this in with the raspberry Pi still running, but I played it safe and switched it off first.

Pi GPIO header LED board
3V3 Vcc
and one of

In pictures, the SPI pins are sometimes marked as purple. I chose to connect the LED array CS line to CE0, so my code examples will use channel 0.

Once I had plugged it all in and restarted the Raspberry Pi, I quickly put together some code to use the "display test" register to switch all the LEDs on and off. This made sure that I could compile a simple C program using WiringPi and get it to talk to the appropriate SPI device:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <errno.h>

#include <wiringPiSPI.h>

#define CHANNEL 0

void main(int argc, char** argv) {
	uint8_t on[] = { 0xFF, 0xFF };
	uint8_t off[] = { 0xFF, 0x00 };
	uint8_t buf[2];

	if (wiringPiSPISetup(CHANNEL, 1000000) < 0) {
		fprintf (stderr, "SPI Setup failed: %s\n", strerror(errno));

	for (;;) {
		memcpy(buf, on, 2);
		wiringPiSPIDataRW(CHANNEL, buf, 2);
		memcpy(buf, off, 2);
		wiringPiSPIDataRW(CHANNEL, buf, 2);

Most of the above code should be pretty straightforward. It's either boilerplate C or direct calls to Gordon's Wiring Pi SPI APIs. The only oddity is the three two-byte buffers. My first attempt passed the "on" and "off" patterns into the SPI API call directly, but the code did not quite work - it only displayed the full LED pattern once. The reason is that SPI is a bidirectional synchronous protocol and the returned values overwrite the outgoing ones during processing. Once I realised this I was able to fix the problem by re-initialising a single buffer before each SPI call. Still, it would have been nice for the API to also support a function with separate in and out buffers.

My next attempt was to try and write some stereotypical scrolling characters. I knew I would need the bitmap data for the characters, so I searched around for source code for an 8x8 bitmap font in a form that I could use. Eventually I found one in LISP which looked easy enough to reformat into C.

Rotated character on SPI LED Matrix

As I was working through the data making it look like C, I began to see patterns. For example, the last byte of a code is often 0, except on characters with "descenders", which led me to wonder if that might be the gap at the bottom of the character. After the reformatting exercise I hooked up the tidied character set data into some code to display characters. And found that they were rotated round 90 degrees! I had to tip my breadboard on its side to read the characters.

Undeterred, I pressed on and wrote some software to scroll any specified string. However, because of the orientation of the characters and the LED matrix, it was easier to scroll the text up/down rather than left/right. It's not quite what I planned, but it's still a cool effect.

You can find all the software for this demo, including the hand-formatted 8x8 character bitmap data, on the Raspberry Alpha Omega SPI project at GitHub


  1. Pingback: LED matrix with a #RaspberryPi | Raspberry PiPod

  2. I believe your modprobe error was caused by apt-get upgrade installing a newer version of the kernel (and modules), and then you didn’t reboot, so the Pi wasn’t able to switch to the new kernel. And since the modprobe failed, the /dev/spidev files didn’t get created, leading to your chown error.

    https://github.com/quick2wire/quick2wire-python-api apparently also includes SPI support, but I’ve personally only used the I2C features of the API.

    A while ago (maybe a couple of years or so) I was also looking for some low-resolution bitmap fonts for a text-scrolling LED program ;-) (it was surprisingly hard to find non-TTF font files)
    I found that BDF fonts (as used by classic X11) contained a range of styles and sizes, and as they’re text-based they’re fairly easy to convert to other formats.

    • Thanks Andrew. As for the fonts, the odd mix of modern and retro is one of the things that makes playing with Raspberry Pi so much fun. It feels a lot like messing with a 1980s home computer, except that the rest of the world has moved on. When I first started computer stuff 7×5 fonts were what everything used, so they were easy to find. The 8×8 fonts on the BBC micro looked quite glamorous in comparison!

  3. After i run : $ gpio load spi

    The output is „Unable to load/unload modules as this Pi has the device tree enabled. …“
    But the strange thing is that I have already enabled SPI, so it is not commented in /boot/config.txt

    # Uncomment some or all of these to enable the optional hardware interfaces

    Also the blacklist file is completely empty.

    When I run : $ lsmod

    Module Size Used by

    spi_bcm2835 7286 0
    bcm2835_wdt 3225 0
    bcm2835_gpiomem 3040 0
    uio_pdrv_genirq 3164 0
    uio 8000 1 uio_pdrv_genirq

    I can find it there in the list. So my question is :

    Do I have to fully disable the device tree to run $ gpio load spi successfully ?

    • This article was written over 3 years ago. There have been lots of changes to the Raspberry Pi software in that time, so I suspect the ‘gpio load spi’ is no longer needed, if you’ve enabled SPI through DeviceTree.

Leave a Reply

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