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:
- Understanding SPI on the Raspberry Pi from Gordon's projects
- Instructions on downloading and installing Wiring Pi also from Gordon's projects
- An article from Brian Hensley about getting SPI working on Raspberry Pi
- and the details of Gordon's Wiring Pi SPI API
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
./build
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 |
---|---|
MOSI / GPIO10 | DIN |
SCLK / GPIO11 | CLK |
3V3 | Vcc |
GND | GND |
and one of | |
CE0 | CS |
CE1 | CS |
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
#include
#include
#include
#include
#include
#include
#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));
exit(errno);
}
for (;;) {
memcpy(buf, on, 2);
wiringPiSPIDataRW(CHANNEL, buf, 2);
sleep(1);
memcpy(buf, off, 2);
wiringPiSPIDataRW(CHANNEL, buf, 2);
sleep(1);
}
}
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.
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