If you want to drive thousands of LED modules with a single Teensy at a decent framerate, you cannot use the Hardware SPI signal. Paul Stoffregen did a fantastic job with his Serial2Parallel Firmware. The idea is simple: send serial data and split it up into eight parallel outputs. This firmware was used to drive this 64×96 pixel led matrix.
How does this firmware work?
Send one byte to the Teensy and it get splited up into eight 1 bit values for each of the eight output ports. This means you need to send 8 bytes to the Teensy to write 1 byte on each output. The WS2801 LED modules need 3 bytes (24 bit) to set a color, thus you would need 24 bytes to set one pixel color on all 8 output ports. Connect the clock lines to Port B and the data lines to Port D.
To make things even more funny, you need to send blocks of 64 bytes to the teensy (USB buffer size). To align the 64 bytes (blocksize) and the 24 bytes (update one pixel on 8 outputs) we send 192 bytes (3 x 64 bytes) out and update 8 pixelmodules on each of the 8 output lines.
Example buffer to send out serial:
11111111 00000000 11111111 00000000 11111111 11111111 11111111 00000000 (8 Bytes)
11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111 (8 Bytes)
00000001 00000011 00000111 00001111 00011111 00111111 01111111 11111111 (8 Bytes)
... (total 64 bytes)
get transfered into (data output):
D0: 10101110 11111111 00000001 ...
D1: 10101110 11111111 00000011
D2: 10101110 11111111 00000111
D3: 10101110 11111111 00001111
D4: 10101110 11111111 00011111
D5: 10101110 11111111 00111111
D6: 10101110 11111111 01111111
D7: 10101110 11111111 11111111
Hint: I used a Teensy 2.0 board for this project, however a Teensy++ 2.0 is about 20% faster.
Attempt to use WS2801 LED Modules
The firmware Paul wrote was inspired by Phillip Burgess’s work for the 21bit LPD8806 LED modules. Those LPD8806 LED modules need a special control byte (0×00) to finish a data transfer (latch the data).
The WS2801 LED modules will finish a data transfer if the clock signal is missing for 500us – and this is a problem if we need to send multiple USB Packets. If the host computer is in IDLE mode everything works fine, if the host computer is busy we’re in trouble. If a transaction is in progress (multiple USB packets) and the delay between two USB packets is longer than 500us the data is latched – and you see a lot of glitches.
You can control a lot of LED modules without buffering the data on the microcontroller. However it’s important to choose the right type!
According to Counterfeiter from the Ledstyles.de forum, it would be possible to use a FIFO buffer to compensate the USB lag.