Driving TLC5940 - 4096-step grayscale PWM LED driver.

Hi all.
For people who loves LEDs, here is a demo of the TLC5940 with PChip.

DESCRIPTIONThe TLC5940 is a 16-channel constant-current sink LED driver. Each channel has an individually adjustable 4096-step grayscale PWM brightness control and a 64-step constant-current sink (dot correction). The dot correction adjusts the brightness variations between LED channels and other LED drivers. The dot correction data is stored in an integratedEEPROM. Both grayscale control and dot correction are accessible via a serial interface. A single external resistor sets the maximum current value of all 16 channels...

This demo is able to control, until 512 LEDs each color RGB, maximun.This demo has not DOT correction and no feedback from the TLC'sThe data is arranged as "longs" but they can be treated as words, since it is enough for the 4096 grayscale levels.The necessary documentation is in the code, but ask me, if you've doubts or if I forget something.I thinks that it is·ideal, for use with 8x8 RGB Sparkfun matrix. (I don't remember, if it comes in common anode )

In fact, I was waiting for your answer, we exchange oppinions in your post about big LED screens.

I'm now, in a similar project here, just began it, I only have what I post at the momment, but I will take a lot of months to finish it.

My target is to get a 128x64 RGB final screen (not a video display), but I'll need to show video same way.

It is a big curtain, about 13 meters wide by 7 meters tall.

I'm starting the project now, by getting some experience with the TLC, I must try with many TLC (When they came here from Digikey), and to get them work in cascade, between distances about 10cm and 20 meters, perhaps I'll use some LVDS like DS90LV011 through DS90LV049, not sure at this time.

After that, we'll assembly the curtain, to get a still image working fine, and just then, I'll begin the·work, to get animations or video,·that could be sending to the curtain.

Areal, take care, I think that 112*64 is not a good resolution for video, I don't know what is your target ??, my is a 128x64 and it 's also not so good, If I don't remember bad, you want· to get a full video display in your post.......

Also, I think that you can't try with xmas lights, they have very different behavior than LEDs.... I think to power the Vcc for LEDs with 5Volt, and with 3.3 Volts the TLC Vcc, perhaps 12V is too much for the Vcc of LEDs, and you'll get excesive dissipation in the TLC's, in the TLC datasheet look at the dissipation calculation, and is better to use one Vcc for the chip and another for the LED's.

Let me know, how do you'll get the data from the FRAM...or the SD card....I don't·make calculus yet, but seems to me that could be, so slow to get the video file, and send it to the screen at 20fps.

The code that I post sends the 512 bytes of data to each color at about 5 mSec or aprox 240 fps total, take in care that you need to add more time "and lost frame rate"·to get the data in-from memory.

When you say "with one chip", do you mean one TLC5940, or one Propeller? To my knowledge, a TLC 5940 can control 16 LED's. These TLC's can be multiplexed, though. From the datasheet:

"Multiple TLC5940 devices can be cascaded by connecting the SOUT pin of one device with the SIN pin of the following device."
"The maximum number of cascading TLC5940 devices depends on the application system and is in the range of 40 devices."

Also from the datasheet: The clock speed for shifting all this data is can be up to 30 MHz.

So seems to me if you have more than 16 x 40 = 640 LED's to control, you'd have to use several sets of TLC5940's but you could drive each set with another cog.

Jamesx said...
Thanks for your example. I have to write a driver for a similar chip: a TLC 5923. Your spin and asm should provide a good place to start.

(Do I have to learn Spanish?!!? )

Your wellcome James !! If it is usefull for you... I'm glad to share it. (I did it very quickly after left, so, no time to English comments, it was easy for me in Spanish....but...it could be a challenge additional to understand· the code...

Graham said...
if you want to control more than 16 LEDs with one chip can you use multiplexing at a rate fast enough not to be noticed?

I think that, it is not possible with this chip, the MAX6974/75 series have this possibility, but it has a special output for multiplex the LEDs, If you charge one set of values for 16 LEDs and get active the common anode with some logic, and then change the values for another 16 LEDs and get active these new common anodes with the logic, instead the last one. you'll get 32 LEDs at different bright, but this will not be the same bright, as if you connect only 16 of them, in each case with the same values of data. (Is this what you ask ?).

crgwbr said...
I'm not super into LED like some people, but I do like motor-control. It seems like these little chips would work great as a 12 bit pwm generater for an h-bridge driver.

I'm not sure of that, let's try, but take in care, that the TLC outputs, drive current with a maximun value that depends of a external resistor.
So I think you'll need to charge all outputs with resistors (each one), and then take the PWM signal out from outputs, or perhaps connecting some optocouplers instead the LED's would work (but warning !! with the GSCLOCK frequency, it· must be slower than I used in the example, to get the opto's working at a safe rate).

Hi all.
I've posted a new, and corrected version of the TLC5940 RGB driver, this has some improvements, one ie. One minus cog, and some omitions errors corrected.
The full code was tested using six TLC's with 32 RGB LED's, so the functionality of the code is guaranteed.
This code is capable to drive modules of large LED screens.
Have fun.

Nice system, quite elegant in its way. I like the way you pushed the hardware to do the hard parts and factored the code down to a zen-like koan -- 'how long is a piece of string'. Thanks for taking the time to translate the top object to English.

I will have to check out the code. I have been sitting on a project for 4 months now that use six of these chips. Thanks BTX for posting your code. When I get around to my code I will surely integrate what you did.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swietertdswieter.com
------------------------------------------------------------
One little spark of imagination is all it takes for an idea to explode

Sure I will keep you posted. My plan is to use the prototype board and add some buttons and switches. The program will have different LED mood light looks such as gentle fade, flash, etc. Each look will have settable parameters. I will be driving RGB LEDs, 32 total (2 chips read, 2 chips green, 2 chips blue). At one point I thought of adding DMX interface, but this is for my living room and I don't really need a DMX source to run mood lighting in my living room.

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Timothy D. Swietertdswieter.com
------------------------------------------------------------
One little spark of imagination is all it takes for an idea to explode

Heres my code for driving the TLC5940. I've finally gotten round to finishing off my LED tile we talked about a few months ago here. I had a bit of an issue with the TLC chips. Because the spec. sheet said that the chip could drive upto 120mA per channel, I assumed that it meant it could drive all channels at that level at once so I would be safe driving four LEDs per channel at 80mA. I over-heated and destroyed several chips before I found the power dissipation equation further down the spec sheet! Now I'm just using three LEDS in parallel per channel, and only driving them at 20mA and it all works perfectly. Its not even as dim as I thought it was going to be, given that three 20mA LEDs in parallel can handle upto 60mA.

Anyway, the code! I've shamelssly 'borowed' your GSClock code BTX. I hope you don't mind. Because I intend to use DMX to drive my tiles, and given that DMX data is 8-bits per channel, my code pads the four least-significant bits for each LED with 0s. So the data packet sent to the TLC chip consists of 16 sets of 8 data bits (MSB first) followed by 4 padding bits. This enables us to pack 4 data values into one long, and this makes hub ram access much quicker than it would have been if the data were 12-bits per LED.

Well done...I will try to understand your code later...here's sunday morning and today we will go to assembly the LED curtain for first time at some TV studies !!..

Let me know something first... do you wrote that you have four bytes in one long to drive 4 LED's ??

In the case of yes... how do you have the grayscale data for the TLC ??? like this ?? "0000xxxxxxxx" ?? or like this "xxxxxxxx0000" ??

I used some shift to get five different bright levels...."shifting" the eight bits from "0000xxxxxxxx" to "xxxxxxxx0000",·obviously in the: seccond choice you will have· more bright than in the first, so I comonly use that way.

Another point ...why do you use three LED's in parallel each output of the TLC ???· please, use the three LED's in serial, then use another and upper Vcc for the LED's, it's more efficiently, and LED's bright will be more similar. But be carrefully, you must recalculate the power didipation again to avoid damage the TLC.

To hopefully make things a bit clearer, heres a psuedocode description of what my code is doing :

Code:

Setup io pins, pointers, etc
Start :
Set data pointer to point to the last of four longs.
Do this 4 times :
Read the long pointed at by data pointer. Store it in GS data.
Do this 4 times :
Do this 8 times :
Shift GS data left one position. Set the C flag.
Send the value of the C flag to the TLC chip.
Do this 4 times :
Send 0 to the TLC chip.
Decrease data pointer by 4 so it points to the previous long.
Toggle the Xlat pin of the TLC chip.
Jump back to Start.

A quick note for those not familiar with the TLC chip. The data needs to be sent one bit at a time, with the highest (most-significant) bit of the last LED sent first. That is why in my code I start with the last of four longs and work backwards. So to answer your question BTX, I send 8 bits of data and then four zeros for each LED. You might think that packing 4 bytes into one long would make working with the data a little tricky, but not so! In my test code the brightness data is actually an array of 16 bytes, not 4 longs. This makes changing any LEDs brightness very simple.

A useful feature of the TLC chip is that it can be cascaded, and it would only take a very simple change in my code to accomodate this. To cascade the chips, all data lines except SIn and SOut are connected in parallel. Then the SOut of the first chip is connect to the SIn of the second chip, and so on for as many chips as one needs. The only changes to my code would be in working out which long to start reading from (which would be data start address + ((no of chips *16)-4) ), and how many times the first loop would run (no of chips * 4).

Edit: Changed the code tags to make the psedocode easier to read, and added a bit about cascading

I'm starting to understand this somewhat. I've been studing the Propeller asm code for the driver.

At the moment I'm trying big_mark's code,
but it really does not matter, as I get the same results with BTX's code also.

I'm probly missing somthing, I have reviewed the Propeller ASM code driver
but no matter what I do, I can't turn on/off any SPECIFIC·led's/channels, there ALL always on and running
the program pattern. e.g

How would I just turn on OUT6 and fade it in and out ? It does not matter what I do, currently
all I can change is just the timing of the rippling effect across ALL the 16 Led's ? Same way on BTX's.

I'm kinda new, but I've really studied All the code and datasheets, What am I missing ?
It's my understanding that I'm filling all the channels with 8 or 12 bits of data msb fifo order.
But, shouldent I be able to turn off all led's except the one thats changing by simply resending
the full 192 bits (all 16 channels) with the 0 (or is it 4096) value that turns off the unwanted led in its array element ?
I've tryed both. I Can't control specific led's only the whole group with a pattern.

I'm going to try to modify the Propeller Asm code, but, Can I select a specific channel via the Propeller ?

I don't think so ? Is it not possiable to work with only one led at a time ?

Ha.. Ha.. I wired yours up again and it seems to be working fine, I think I was confused because
I should have been addressing the IC pin's backwards e.g OUT15 = led 1 (actualy on pin OUT1) etc... in my loop

You ever fix the proplem soon as you post ? Ha.. Ha.. Sorry, I'm just a dumb newbe Ha.. Ha..

Ok, I can now access a single Led with BTX's code. Thanks,

I think I'm now going to try to drive a TI SN74HC595N with the Propeller to multiplex
the anodes. I may also try the M74HC155 ln decoder.

I'll still cannot access a single LED and do a fade with big_Mark's code, HOWEVER, I'm new to all this.