For the past few days I have been tinkering with an addressable LED light strip, and discovered a distinct lack of information online on how to control it using a Raspberry Pi board. There are tutorials and such for using the SPI interface, but that is more complicated than most users want to deal with. And if, like me, your Raspberry Pi is already being used for other projects you may not want to alter the SPI controls and risk causing other problems with the board.
And so for that reason, I decided to write a very basic introduction and overview of the code required to control an LED strip. I hope you find it useful.
The first issue that needs to be addressed is the connection speed. My LED strip is based on a series of 32 separate WS2801 microchips, which work by reading 24 bits of colour data from a serial input line. Each time the clock signal goes high, another bit is read off of the serial data line. When 24 bits have been read, the next clock signal shifts the first bit in to the serial input of the second LED in the strip. This continues until a total of 768 bits have been transmitted.
However those bits must be sent very quickly, and each must be syncronized with the clock signal. According to the technical specifications for the WS2801 chips, the ideal clock rate is around 25MHz or 40 ns per pulse. And ideally it should be consistent as well, with each pulse lasting the same length of time.
And so the first step in this project will be to install a C-compiler on the Raspberry Pi board. I quite like the Geany program, and since we will be directly controlling the GPIO pins on the board you will also need to install the WiringPi library.
The second step is to connect the LED strip to the Raspberry Pi. One of the great things about the WS2801 chip is that it can run off of either 5V or 3.3V, and although many websites have stated that a separate power supply is required to operate the LED strip, my experience has been that the 3.3V supply from the RasPi board itself is more than enough to run a 1m length of LEDs. And so the first connections are from the voltage supply line to the 3.3V pin on the board, and then connect ground on the LEDs to ground on the board. Next you will connect the clock line and the serial data line on the LED strip to two GPIO pins on the board, and make note of which pin each one is connected to. (And note that the WiringPi library numbers the pins differently than either BCM or Board numbering)
At this point the connections are completed, and it is time to boot-up the Raspberry Pi, load the Geany IDE and set the compiler to use the WiringPi library, and begin the actual programming.
And there lies the problem with using a Raspberry Pi board. While an Arduino or similar dedicated micocontroller has a single task, the Pi is a full computer system and the CPU must multitask between several jobs at any given time. So while it will produce some quick clock cycles, it might get distracted checking the WiFi adapter or a mouse input or any of a number of other tasks. It is not consistent in its timing unless you use PWM or SPI, both of which require more complicated programming.
The second problem is that users usually are encouraged to program Raspberry Pi with Python interpreters. Many distributions already include Python in them. But Python is just too slow for this task. In my own tests of Python, a single clock pulse averaged about 80 microseconds, rather than the required 40 nanoseconds required. The WS2801 chips reset themselves after approximately one hundred microseconds, and so the next clock pulse is interpreted as the start of a new 768 bit colour signal rather than completing the previous one.
NOTE: While the LED strips I used are safe for Raspberry Pi boards, there are some other models and configurations which draw too much current and can cause damage to the fragile circuitry of the Raspberry Pi. Please check the specifications for your own particular LED strips before connecting them.