How to Control a Ton of RGB LEDs with Arduino & TLC5940

This video explains how to use the 16 channel PWM controller TLC5940


//Texas Instruments TLC 5940 with Arduino
#include <SPI.h>//Serial Peripheral Interface Library
byte ch=0, chbit=0, spibit=0, spibyte=0;// variables used by tlc sub routine
int SINData;//variable used to shift data to the TLC
byte transferbyte[48];// bytes that are sent out to the tlc5940 via SPI
// 48 because 16 channels @ 12bits gives 384bits, 384/8 = 48 bytes, 12 bit to 8 bit conversion
byte DCvalue[32];//0-63, 6 bit DOT Correction Bytes
int i, j, k, l,m,n; //misc variables
int green, oldgreen= 2048;//for random animation
int red, oldred = 2048;//for random animation
int blue, oldblue = 2048;//for random animation
int comeback=0, pick_color=0;//for random animation
pinMode(2, OUTPUT);//XLAT
pinMode(3, OUTPUT);//OSC2B GSCLK
pinMode(4, OUTPUT);//VPRG
pinMode(11, OUTPUT);//MOSI DATA
pinMode(13, OUTPUT);//SPI Clock
//Set up the SPI
SPI.setBitOrder(MSBFIRST);//Most Significant Bit First
SPI.setDataMode(SPI_MODE0);// Mode 0 Rising edge of data, keep clock low
SPI.setClockDivider(SPI_CLOCK_DIV4);//Run the data in at 16MHz/4 - 4MHz
for(i=0; i<48; i++)//clear out Gray Scale Data
for(i=0; i<32; i++)//set Dot Correction data to max (63 decimal for 6 bit)
//set up DOT Correction
DotCorrection();// sub routine helps 
noInterrupts();// set up the counters, so don't go into interrupts
TCCR2A=B00010010;//Timer 2 set to Compare Mode Toggling pin 5 @ 8MHz, Arduino Digital 3
//Timer 2 prescaler set to 1, 16/1=16 MHz, but toggles pin 5 every other cycle, 8MHz
TCCR1A=B00000000;//Timer 1 doesn't toggle anything, used for counting
//Timer 1 prescaler set to Fclk/256
//Why? We need to count 4096 pulses out of Timer 2 - pin 5
//8 MHz = 1 pulse every 125ns - - 4096 pulses would need 512us
//Timer 1 runs at 16MHz/256=62.5kHz, we need a match at every 512us
//Basically, I can get an interrupt to get called every 512us, so...
// I need to run Timer 2 @ 8MHz for 512us to get 4096 pulses
// I can't count those pulses directy (too fast) , so
// I'll count using Timer 1, which makes a count every 16us
// The counter starts at 0, so we'll set it to 31 to get an interrupt after 512us
TCCR1B=B00001100;//Mode=CTC with OSCR1A = TOP and 256 as the prescaler
// Mask set up, will call ISR (Inerrupt Service Routine) for Compare match on A
//These are the match values for the counters
// 0 here means it will match on one cycle of the clock/prescaler
OCR1A= 31;//to get our 512us Interrupt
interrupts();// kick off the timers!
for(i=0; i<32; i++)//wipe out the data in tlc
tlc(i, 0);// This is how you update the LEDs, tlc is a subroutine with two inputs
// tlc(Channel, Value)  Channel in this case is 0-32 and value is 0-4095 duty cycle
//4095 is 100% ON
pinMode(5, OUTPUT);//BLANK  We set this pin up here, so it remains in a high impedance
// state throughout the setup, otherwise the LEDs go crazy!  even if you write this HIGH


For more detail: How to Control a Ton of RGB LEDs with Arduino & TLC5940

This Post / Project can also be found using search terms:

  • arduino tlc5940 rgb led code
  • tlc5940nt arduino rgb
  • esp32 tlc5940
  • how make a lot of rgb led with a tlc5940 work

Leave a Comment

= 3 + 3

(Spamcheck Enabled)

Read previous post:
Forget Me Not- Remote Flower Watering
Forget Me Not- Remote Flower Watering

Hi everyone, Lucy Matchett, Nicole Yi Messier, and Joselyn McDonald (Snax_and_Macs) made a remote flower-watering device so you can water...

Scroll to top