Review – Texas Instruments TLC5940 16-channel LED driver IC

Hello readers

Today we are going to examine the Texas Instruments TLC5940 16-channel LED driver IC. My reason for doing this is to demonstrate another, easier way of driving many LEDs as well as LED display modules that are common-anode. If you have a common-cathode display module, you should have a look at the Maxim MAX7219. Moving along, here is the IC:


Another nice big DIP IC. Also available in HTSSOP and QFN packaging. What can this IC do for us? It can control 16 LEDs per IC, and also be cascaded to control more and more, with the display data arriving via a serial line in the same manner as a 74HC595 shift register. Furthermore, another benefit of this IC is that you don’t need matching current-limiting resistors for your LEDs, as this IC is a current sink, in that the current flows from the 5V rail, through the LED, then into the IC. However, it can control the brightness of the LEDs using pulse-width modulation over 4096 steps via software, or using a single resistor.

What is pulse-width modulation? Normally an LED might be on, or off. But if you switch it on and off very quickly, it does not look as bright (as it is not on 100% of the time). If you alter the period of time between on and off, you can alter the perceived brightness of the LED. Here is an example, compare the brightness of the LED bars against the display of the CRO – as the brightness increases, the voltage (amplitude [vertical thickness]) spreads across the entire time period (horizontal axis); as the brightness decreases, the voltage spread across time retreats:

Using the IC is very easy on the hardware front. Here is the data sheet: TLC5940.pdf. The pinout diagram is quite self-explanatory:

Pins OUT0~OUT15 are the current-sink pins for each LED. When one is selected they allow current to flow into the IC from the 5V rail, with the LED in between – turning it on. However it is easier to understand with a practical example, such as this:


If you are using an Arduino Mega-style board, the wiring is a little different, please see here for the instructions.

Here we have our Arduino board or compatible sending serial data to the TLC5940 to control sixteen LEDs. The 2k ohm resistor is required to set the maximum current available to flow through the LEDs, thereby adjusting their brightness. Using software you can adjust the brightness with PWM for each LED by itself. Very important: this circuit will need external power into the Arduino or a separate 5V power supply. The circuitry on the breadboard draws up to ~318 mA by itself – running the Arduino from USB only made it somewhat flaky in operation. Here is the circuit in action with an ammeter between the breadboard and 5V out on the Arduino:

Anyhow, let’s get moving once more – here is the assembled demonstration circuit:


For our example, we will be using the Arduino way of doing things. Thankfully (once more) there is a library to make controlling the IC exponentially easier. The library page and download files are available from here.  If you need guidance on installing a library, please visit here. However the commands to control the IC are quite simple with the Arduino library.

First of all, include the TLC5940 library, as such:

#include "Tlc5940.h"

Then in void setup(); you create the object using the function:


You can insert a number between 0 and 4095 to set the starting PWM (LED brightness) value, however this is optional. Setting an output for display requires two functions, first Tlc.set(l, p); where l is the output (0~15) and p is the PWM brightness level – then execute Tlc.update(); which sends the command to the IC to be executed. The sketch below is easy to follow and understand the process involved.

Moving forward with the demonstration, here is the sketch  – TLC5940demo.pdf, and the video clip of operation:

When the LEDs are glowing from dim to bright and return, we are altering the PWM value of the LEDs to adjust their brightness. This also occurs during the last operation where the LEDs are operating like the bonnet of KITT.

Below is an example of TLC5940 use by JM – he has made an awesome RGB LED cube:

Well once again that’s enough blinkiness for now, again this is another useful IC that helps simplify things and be creative. As always, avoid the risk of counterfeit ICs  – so please avoid disappointment, support your local teams and buy from a reputable distributor. Living in Australia, mine came from element-14 (part number 1226306). So have fun! High resolution photos are available from flickr.

Remember, if you have any questions at all please leave a comment (below). We also have a Google Group dedicated to the projects and related items on the website – please sign up, it’s free and we can all learn something.


  1. As an author of an alternative Arduino library, I just thought I’d plug my work here 😀

    The ’41 and ’40 should be pin-for-pin compatible, despite the different names assigned to a couple of pins (and despite the fact that the ’41 doesn’t come in a DIP package: SMD only).

    Anyway, my approach is more object oriented, permits indefinite daisy-chaining without a recompile, makes setting the dot-correction per-channel dead-simple, and puts an emphasis on easily achieving special effects. FWIW

  2. Is it possible to change the brightness of each individual LED using PWM, or just all of them together as a whole?

  3. hello.

    i wonder what frequency the pwm is set at?

    It would be nice to control motors ( using h-bridges) instead of leds, I can’t see the answer in the pdf.

    thanks for any info.

    peace : )

  4. I just want to use the TLC5941
    like a normal shift register that limits
    the currnet to the leds with one resistor.
    I know every body is using
    arduino these days but I’m still using
    a PICAXE 20 pin, I’d just like to bitbang the GS and DC values and just use the TLC5941
    to drive My 7 segment led number displays.
    Do I have to set the GS and DC
    values every time I want to send
    16 bits just to turn on leds?
    Or is there an easy way to
    just wire like the MODE and BLANK
    and GSCLK to high or low or some
    Or can I just set the GS and DC
    once in the beginning and just use
    the TLC5941 to run My 7 segment
    There it is, three concise
    questions, Thank You Very Much for
    a reply.
    Take Care. KYLE

  5. Hi John, love your work, and this IC.
    I am wondering though if you can use the MAX7219 in the same way as the TLC5940. For example, can you control RGB leds as freely as is possible with the TLC5940? It doesnt seem the MAX2719 has PWM so Im not sure how this would be possible without some other external control.
    Any info would be appreciated.

  6. Hi John,

    I’m trying to use your circuit with an arduino mega 2560. I followed the pins but did not get anything to work. Do you have any ideas what could be wrong?


      • HI John,

        I checked everything but it doesn’t work. There is output at the LEDs only with 2.1V (anything higher there’s too much current and nothing works). I also can’t seem to set each LED by itself (i.e. using commands like tlc.set (channel, PWM value). Any ideas how I can fix?

        Thanks again.

      • It’s very hard for me to know without being there. Sometimes when I make things and they just don’t work, I completely pull it apart and start all over again reviewing everything. Might be worth a shot.

  7. Maybe i missed it, but i didn’t read it anyware, by checking the dayasheet i saw the pin 17 is the serial out of the ic, so if i want to connect several ic’s i would connect pin 17 of the first into pin 26 of the second and etc with all the other pins connected as shown right? and in that case if i write for example Tlc.set(16, p) would it be pin 0 of the second ic? thanks

Comments are closed.