I have found the TLC5940 chip, which I thought would solve my problems. It didn’t, not all of them, or at least there are a few downsides to it.
The main one being the timing requirements.
The 5940 kind of does PWM. It doesn’t have an internal clock, so it relies on an external clock signal. Generating that signal is tricky in my case, because I was planning to do Pi -> TLC chips -> LED, with the added complexity of multiplexing being thrown into the mix. These chips are designed for stuff like driving LED displays – single layer stuff, not 8 layers deep. And I’m switching between layers, not doing one layer completely then moving on. So the benefit of the chip doing PWM is lost, because I need to update the information in the chip each time I move to the next layer.
In terms of timing, the Pi can only do a max of 2Mhz, and that was measured in a infinite loop that just switched a single signal on and off. To get smooth motion, I’d need to do at least 24Hz refresh rate (guesstimate, based on movies). Because I have 8 layers, that becomes 192Hz. The chips take a 12 bit brightness value for each LED, and it’s serial in, so I’d need at least 192 clock cycles to get all the information in, not counting blanking/starting signals. So that gets us to ~37kHz.
My worry is that the Pi’s setting of pin output levels is synchronous, so I have to wait for 1 pin to go high/low before moving on. If the Pi can endlessly do one complete cycle at 2Mhz, I now have 16 outputs I need to cycle. Which isn’t too bad, that gets me ~167kHz cycles, not counting the clock signal generation. To make the math nice, I shall assume I have a round 20 outputs each cycle (I’ll have at least 1 – the clock signal for the chips), so it becomes 2000kHz/20 = 100kHz. However, a quick bit of calculation shows that I could do 60Hz refresh rate, and that’d need a ~92kHz data transfer rate, so I’m still within boundaries. It would just take an extra bit of complexity in the code.
But why is this a concern? The timing requirements are a lot tighter than if I was using a basic shift register. That generally takes in 8 bits at a time (serially), and outputs in parallel – so the requirements of 192 clock cycles to put in all the information would drop to 1/24th. While it’s only 8 bits/chip, chips can be chained to get the 16 bits. But the timing requirements would still be only 1/12th of what using the 5940 needs. And there’s known to be kernel glitches that affect the output – where the pins lock for ~500 microseconds periodically, presumably because of background processing. I’d be nice-ing the program running on the Pi, clearly.
Also, the fast timing requirements may give me the chance to implement 192 level fading – or 7.5 bits of brightness control, because I could hook up the PWM counter/clock to the same line that drives the input clock, so every input cycle is one PWM cycle, which would get me the 192 levels of brightness. Bitmasking and other bit-level screwery would be required though – though that’s more experimenting than anything else.
However, the pros of the 5940:
- Built in current limiter – no need for an extra resistor
- Single chip gives you 16 outputs
- Free from TI’s lovely wonderful sample program, thanks to the fact that I’m in uni.
Possible explorations once I finish the cube include looking at driving the cube standalone with an Arduino clone, and other stuff as I think of it…