PWM Shift Register needed

Hi everyone,

I’m interested in creating an RGBLED cube (8x8x8). I need a shift register to control the RGB channels of the LEDs (common cathode). What I think I need is a shift register that holds 8 bits (1 byte) per output. Can anybody make some recommendations?

Best regards,
Jeff

Tlc5940 is the usual choice. However, it is better suited for common anode RGB LEDs. Most led driver chips are better suited to common anode.

With careful design of your cube, you can still use common cathode LEDs, although it will require a different multiplexing strategy and won't be as bright as if you used common anode. Instead of lighting one of the 8 layers at a time, you would need to light one colour of one layer at a time, giving a 1/24 duty cycle instead of 1/8 duty cycle. On the plus side, you will only need 4 tlc chips instead of 12.

Thanks for the reply! I guess I’ll change to common anode leds. Funny thing is I just discovered the TLC5940 accidentally right before I saw your reply, lol.

Sooo, apparently controlling a TLC 5940 with a NodeMCU 12e is more difficult than i thought. Any tips? I just don't understand all the inputs of the TLC5940 and all libraries i've found are for arduino boards.

Oooor possibly modifyinf the pins for the TLC5940.h library?

all libraries i've found are for arduino boards.

That is because this is an Arduino forum.

Just off the cuff, I would presume the libraries should work just fine, most do unless they are tied to the specific SPI pins or use some obscure functions (and have not been updated for the ESP8266 as the "parola" libraries have).

The labels for the ESP8266 generally have a "D" prefix rather than a plain number.

There does not seem to be a published tlc5940 library adapted to the esp8266. But as Paul__B said and the OP has suggested, for the most part it's just a matter of configuring the pins in one of the existing libraries.
I would recommend the pjrc library as a starting point, and using hardware SPI because you need the speed for an 8x8x8 cube which will require 12 tlc chips and layer multiplexing.

There will be (at least) one more problem to be overcome. The tlc chips need to be provided with a clock signal for pwm. This needs to be quite a high frequency, ideally several KHz. You will be updating the tlc chips at several hundred Hz, so the pwm clock needs to be at least 10 times higher. On AVR based Arduino, this is produced using an ATmega timer, and the code to do that is AVR specific. On Teensy 3.x boards, an ARM timer is used, using ARM specific code. Some new code will be needed to replace this for the ESP. Perhaps this could be done using

analogWriteFreq(5000UL);
analogWrite(tlc_gsclk_pin, 512);

This should in theory achieve a 5KHz signal, which might be enough.

The problem with the TLC5940 is that it needs not only a clock but it needs feeding data with an SPI like protocol every clock cycle. This requires the use of an interrupt fired off the clock and the ISR feeds in the data. So it is not so simple to modify the libiary when timers and interrupts are involved.

However the PCA9685 chip is set and forget which makes it simpler to run , it is a much better chip, uses I2C interface and can run off 3V3.

Hmmm... I was looking at the library code and trying to figure out why timer interrupts were being used for the XLAT pin and thinking "why is this being made so complicated?". I guess that must be why. What exactly is going on with that, Mike?

There are some disadvantages to the PCA9685 chip, though. No constant current outputs, so led series resistors will be needed. I2c bus is slower than SPI. Not sure how fast the i2c bus can go on esp. It is software, not hardware. I think it can go to 400KHz. Do we think that will be fast enough for the OP?

There is another approach the OP could take. Use a non-pwm driver and do the pwm in code. This is not easy, but not as hard as it sounds. A technique called "bit-angle modulation" (BAM) can be used. This makes it significantly more efficient than you might think, although still quite demanding on the MCU.

To achieve 8 bit pwm (256 levels) with the conventional approach, your code would need to update the led drivers 256 times more often than with pwm-capable drivers. That's pretty demanding and could take up nearly all the mcu's time. But with BAM, only 8 updates would be required. The timing of those updates is critical, and the MCU needs to be fast, but the MCU would be busy for far less of the time than with the conventional approach.

What exactly is going on with that, Mike?

It is all in the data sheet, but basically the chip does not retain the bytes you sent it for one cycle of PWM, so you need to send it those values every cycle.

As to I2C not being fast it it true, but because it is a simple set and forget chip it doesn’t matter, it is fast enough.

But yes if you are driving more than 20mA or need a constant current or higher voltage output then each LED output needs a driver.

Grumpy_Mike:
the chip does not retain the bytes you sent it for one cycle of PWM, so you need to send it those values every cycle.

What? What a crazy way to design the chip! Why would they do that?

@OP: here is another suggestion. Tlc59711. This seems to have a simpler interface than tlc5940, so any libraries (AdaFruit have one) might be simpler to translate for esp8266. Each chip has only 12 channels, so you would need 16 chips instead of 12. Each channel has 16 bit pwm precision instead of the 12 bit, which may be useful, and constant current outputs.

What a crazy way to design the chip! Why would they do that?

Well they did so that is it.

I suspect that these chips were designed for outdoor LED TV displays where every frame demands a new set of data. Therefore it is a waste to retain the values from the previous frame, making the chip cheaper to make, but more importantly having a lower power dissipation.