LED-strips are awesome things, and they aren’t hard to use if you know how to use them, but only íf you know how to use them. While there may be many guides to connecting it to an Arduino, guides on using it with the Raspberry Pi are quite sparse, and not everything might be as straightforward as it seems. We’ll be using C++ and the wiringPi library to drive an APA102 led strip.
Connecting the strip to the Pi
The APA102 requires 5V, while the raspberry pi uses 3.3V logic, so we’ll have to shift the voltage with a level shifter. Luckily, these are extremely cheap, and in china they go for as little as €0,76. You’ll have to supply it with 3.3V from the pi on the low voltage (
LV) side, and with 5V from your power supply on the high voltage (
HV) side. Then use either two of the four level shifting pins to connect the strip to your Pi’s SPI interface:
|Strip||Raspberry Pi||Power Supply|
To enable SPI, open an SSH connection to the Raspberry:
advanced options, and then
SPI. Enable the SPI interface and reboot the pi. To check whether the SPI module is enabled, run the following command:
A list of enabled modules should appear, look for
spi-bcm2708. If it appears in the list, SPI should be working properly.
How the APA102 works
The APA102 works by sending bytes through the SPI interface. It is started by sending 32 bits containing
0, then a 32-bit frame for every LED in the strip, and then 32 bits containing
1. Every LED frame contains a constant part (binary
111), 5 bits containing the brightness of the LED, and 3 8-bit integers containing the blue, green and red components respectively.
|bits 1-3||bits 4-8||bits 9-16||bits 17-24||bits 25-32|
Using WiringPi to control the APA102
First, we’ll need to initialize wiringPi and the SPI extension:
After that, we send the opening bits and closing bits:
So, in between those two statements we’ll need to send the data to the LEDs. For this example, we’ll just make everything red. But before that, there is one very important to note (it took me about an hour to find out why my code didn’t work), namely the fact that we’re setting the
buf variable in each iteration of the for-loop. This is because
wiringPiSPIDataRW writes the incoming data to the supplied
uint8_t array, so if you want to write the same data multiple times without creating a huge array, you’ll have to reset the value after each call to
Creating a LED frame
So, as we saw before, every LED frame contains a constant part, a brightness part, and a color part. The easiest way of creating a frame is just using an
uint8_t array and writing the blue, green and red components to the second, third and fourth element respectively. To obtain the first element, we bitwise or
0b111000000 with the brightness we want to use, where the brightness is a number from 0 and 31:
Of course, you don’t need to put this in a function and you can just reuse the same buffer for every frame, but do remember to reset the frame every iteration.
With this LED strip you can create some quite awesome effects, and that is something I’ll cover sometime later. Until then, the complete code can be found in this github gist