Library for TLC5940 16-channel PWM chip

Thanks AC great library.

Is it possible to control the brightness of each channel?
If yes can someone please provide a sample of where they have done it?

Or

Would it be easier to have another chip controlling a say mosfet to control each intensity.

Right now my setup is 3 TLC -> (3)Mosfets -> (1)RGB_LED

I thought about adding in a 4th TLC to control the common for intensity.

Let me know,
Ram

Oh yes one more question.

Is it possible to bitshift or do something to turn 0 into 4096 and 4096 into 0 for n channel fets?

int i = 2000;
int inverse = abs(i-4096); //subtracting 4096 makes it inverse, but negative, abs converts negative to positive, making the conversion complete

Hope that helps =)

Hi I noticed this interface in your initial email and wondered if it was by design ?
Tlc.setPWMperiod(PWM period (0 - n) milliseconds);

I read in the data sheet that the chip can have a max clock of 30MHz/ which works out at about 1/7th msec per 4096 clock pulses.

I guess that means the arduino has order of 2k instructions per cycle...

is that feasible?

Thanks on the code for inverse.
I was actually thinking about adding a !buffer chip to invert the outputs to drive the mosfets off when the signal is off / lost.
As for the pwm output i was wondering that myself I havnt seen it in there I think it had to be fixed when it changed to spi mode instead of bitbang.

Ram

=== code
int i = 2000 ;
int inverse = abs(i-4096) ;
=== or
int i = 2000;
int inverse = 4096 - i ;

below is a little smaller and simpler.

when would
int inverse = (4096-i)
be negative if you are inputting 0 and 4096? Unless you are going to put in values larger than 4096, I agree with dafid and you don't need abs().

I realise that now I was in the middle of a game when I posted :P.

Has anyone tested the Library from AC with the TLC5940 in the TSSOP packages? I have a big problem with more than one TLC. Maybe you can watch my thread here:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1268821919/0

Hi,
I'm using the TLC5941 and it's working great except for the fading function for the arduino to control 5 RBG LEDs (15 channels).

so I have a function with this

  tlc_addFade(channel, Tlc.get(channel), green, millis(), millis()+(duration*60) );
  tlc_addFade(channel+1, Tlc.get(channel+1), red, millis(), millis()+(duration*60) );
  tlc_addFade(channel+2, Tlc.get(channel+2), blue, millis(), millis()+(duration*60) );

I would send in 'duration' to being like 300, making the transition to take place over hours. But the transitions occurs within seconds. Do you know what the issue could be?

Thanks.

Sorry, but I have not yet used fading. All I know is that it gives an example in the TLC library to do so.

*** Documentation Bug Alert ***

Alex,

Thanks for the library - works great for me!

There is a small documentation bug on the page for VPRG_ENABLED:

It says

"You will also have to connect Arduino digital pin 6 to TLC pin 27"

Actually, the library uses Arduino pin 8, not 6. I stumbled over this
and dug through the pin definitions to find the problem.

Best,
-- Terrence

I think I figured out the length of the fading issue... There isn't enough memory to handle all of the fading.

in tlc_fades.h

#define TLC_FADE_BUFFER_LENGTH 24

I changed it to

#define TLC_FADE_BUFFER_LENGTH 64

and the steps of the fades went up and occurs a few seconds longer but alas I can't pump up the buffer_length any higher without crashing the board. Oh well, it was a nice idea :slight_smile:

could it be used for other uses like driving a transistor that is conected to a motor?

or an lcd display??

I used the library to control an hbridge to run dc motors. The code I used is here. HTHSRobotics0809/bottom.pde at master · compuwizard123/HTHSRobotics0809 · GitHub It contains other stuff for serial communication but primarily controls motors. Documentation for the electronics part of the project is here. http://sites.google.com/site/hthsrobotics/components/electronics It was used to compete in the MATE ROV competition last year.

ACleone
Im studying your library version "mux" , and I would like to know the kind of modifications I should take into account in order to use it on a generic non-arduino board.
Any advice will be appreciated.
thank you

Im using the TLC5940 in conjuction with an arduino to fade pairs of leds down a line in a wearables project. I have come across a bizarre problem that occurs after 12 cycles of the LED's fading. After the 12th cycle the sketch seems to crash as all the LED's power on permanently unless you hard reset the arduino. I do not know how to rectify this and have tried many things. Is the buffer becoming full? if so how do i reset it? Here is my code:

 #include "Tlc5940.h"
#include "tlc_fades.h"

TLC_CHANNEL_TYPE channel;
boolean resetFades = true;
void setup (){

  /* Call Tlc.init() to setup the tlc.
     You can optionally pass an initial PWM value (0 - 4095) for all channels.*/
  Tlc.init();
  Serial.begin(9600);
}

void loop () {
  // Tlc.clear();
   channel = 0;
   
   
   
   
     if (resetFades == true ) {
       resetFades = false;
      uint16_t duration = 900;                                               //fade length
      
      // Change these for pairs of LEDS
      
      uint32_t startMillis = millis() + 50;                                 
      uint32_t endMillis = startMillis + duration;
      fadePairs(0,  startMillis, endMillis, duration, 100, 100); //Adjust Brightnesses of the Individual LED's in a pair.
      
      startMillis = millis() + 300;
      endMillis = startMillis + duration;
      fadePairs(2,  startMillis, endMillis, duration, 200, 200);
      
      startMillis = millis() + 600;
      endMillis = startMillis + duration;
      fadePairs(4,  startMillis, endMillis, duration, 300, 300);
      
      // Fade in twos
      //LED 0
      //tlc_addFade(channel, 0, maxValueB, startMillis, endMillis); //fade in
      //tlc_addFade(channel, maxValueB, 0, endMillis, endMillis + duration);// fade out
      //tlc_addFade(channel+1, 0, maxValueR, startMillis, endMillis); //fade in
      //tlc_addFade(channel+1, maxValueR, 0, endMillis, endMillis + duration);// fade out
     
    
     
     
      Serial.println("resetting");
     }
     
     
     int fadesRemaining = tlc_updateFades();
     
     if (!fadesRemaining){
       // all fades are done
       resetFades = true;
     }
     
     
     delay(25);
      Tlc.update();
      
      
      
}
//Our LED fading function
void fadePairs(TLC_CHANNEL_TYPE channel, int startMillis, int endMillis, int duration, int maxValueR, int maxValueB){
   tlc_addFade(channel, 0, maxValueB, startMillis, endMillis); //fade in
   tlc_addFade(channel, maxValueB, 0, endMillis, endMillis + duration);// fade out
   tlc_addFade(channel+1, 0, maxValueR, startMillis, endMillis); //fade in
   tlc_addFade(channel+1, maxValueR, 0, endMillis, endMillis + duration);// fade out
}

/////
any help would be appreciated . Thanks.

ok first of all, a quick THANK YOU to whomever wrote this wonderful TLC library.

and now, regarding the TLC_FADE_BUFFER_LENGTH issue -
mistergreen: i took your advice and changed the value of that variable to 64 which gave me some more tlc_addfadez, but after ~45 this would stop working. Has anyone solved this issue or worked-around it or hacked something i could use?

thanks!

hello, i take it all back. all is fine and dandy when changing buffer size.

thank you anyways.

Hello

I am new to arduinos and any type of programming but I've been working on a project requiring me to fade 4x16 LEDs off of one arduino (atmega 328). I've played around with the tlc fade code and everything works well unless multiple sets of LEDs are triggered simultaneously. Each "pod" of LEDs goes through two waves of fade up and a fade down after the sensor has been triggered with an exception to stop an existing wave if the sensor is triggered during a previous pulse. I have included my code which I've tried to comment to the best of my abilities. Any advice on coding or my specific problem would be much appreciated. Thanks.

PS. This code shows only two tlcs but i will ultimately be using four.

#include "Tlc5940.h"                                                     //TLC library general
#include "tlc_fades.h"                                                   //TLC library fades

int calibrationTime = 10;                                                //time in seconds for PIR to calibrate
int counter1 = 0;                                                        //counter is the variable for the specific pin on the TLC5940
int counter2 = 0;                                                        //counter is the variable for the specific pin on the TLC5940

uint16_t LEDSpeed1 = 200;                                                //time between each LED
uint16_t LEDSpeed2 = 1000;                                               //time between each LED
uint16_t duration1 = 1600;                                               //duration
uint16_t duration2 = 30000;                                              //duration
uint16_t maxValue = 1000;   
uint16_t midValue = 10;                                                   //as counter gets higher max brightness decreases

boolean isFading1 = LOW;
boolean isFading2 = LOW;

const int irInput1 = 6;                                                  //pin for PIR 1
int irState1 = 0;
const int irInput2 = 4;                                                  //pin for PIR 2
int irState2 = 0;   

const int sensorDelay = 8000;                                            //time in milliseconds after sensor is toggled high before it will take another reading
uint32_t currentTime1 = 0;                                               //time of the last PIR toggled HIGH
uint32_t currentTime2 = 0;                                               //time of the last PIR toggled HIGH

TLC_CHANNEL_TYPE channel;                                                //TLC code for defining channel

void setup()
{
  Serial.begin(9600);
  Tlc.clear();
  Tlc.init();
  pinMode(irInput1, INPUT);  
  pinMode(irInput2, INPUT); 
  for(int i = 0; i < calibrationTime; i++){
    delay(1000);
  }
}

void loop()
{
  Tlc.clear();                                                            //clear pins
  isFading1 = LOW;                                                                        //set channel to zero
  isFading2 = LOW;

  //sample sensor

  if (millis()>(currentTime1+sensorDelay)){                               //confirm it has been a long enough wait for PIR to take another reading
    irState1 = digitalRead(irInput1);                                     //read PIR
  }
  if (millis()>(currentTime2+sensorDelay)){                               //confirm it has been a long enough wait for PIR to take another reading
    irState2 = digitalRead(irInput2);                                     //read PIR
  }

  // fadeout

  if (tlc_fadeBufferSize < TLC_FADE_BUFFER_LENGTH - 2) {
    if (irState1 == HIGH){                                                  //if pin is high stop the fades and fade all LEDs out before starting waves

      counter1 = 0;
      currentTime1 = millis();
      Tlc.clear();
      tlc_updateFades();

      for (int i = 0; i < 16; i++){                                                 //cycles through channels 0 - 15

        uint16_t stopValue = Tlc.get(i);                              //find the current channel value
        tlc_removeFades(i);                                           //take fade off of that channel
        tlc_updateFades();                                                  //update
        Tlc.set(i, stopValue);                                        //set the channel to previous stop value
        uint16_t duration = (stopValue + 1)*2;                                //set fade duration to stop value plus one so there are no zero duration fades
        uint32_t startMillis = millis();                                    //start fade at current time
        uint32_t endMillis = startMillis + (duration);                      //end fade at current time plus duration
        tlc_addFade(i, stopValue, 0, startMillis, endMillis);         //take fade from previous stop value to zero for the specified duration
        tlc_updateFades();                                                  //update
        irState1 = LOW;                                                     //reset irState1 LOW
      }
      counter1++;
    }
  }

  if (tlc_fadeBufferSize < TLC_FADE_BUFFER_LENGTH - 2) {
    if (irState2 == HIGH){                                                  //if pin is high stop the fades and fade all LEDs out before starting waves

      counter2 = 0;
      currentTime2 = millis();
      Tlc.clear();
      tlc_updateFades();

      for (int i = 16; i < 32; i++){                                                

        uint16_t stopValue = Tlc.get(i);                        
        tlc_removeFades(i);                                   
        tlc_updateFades();                                             
        Tlc.set(i, stopValue);                                      
        uint16_t duration = (stopValue + 1)*2;                             
        uint32_t startMillis = millis();                                    
        uint32_t endMillis = startMillis + (duration);                     
        tlc_addFade(i, stopValue, 0, startMillis, endMillis);         
        tlc_updateFades();                                                 
        irState2 = LOW;                                                  
      }
      counter2++;
    }
  }
  // i s F a d i n g 
  for (int i = 0; i < 16; i++){

    if (tlc_isFading(i) == 1){
      isFading1 = HIGH;
      break;
    }
  }
  for (int i = 16; i < 32; i++){

    if (tlc_isFading(i) == 1){
      isFading2 = HIGH;
      break;
    }
  }
  // w a v e 1 

  if (tlc_fadeBufferSize < TLC_FADE_BUFFER_LENGTH - 2) {
    if ((counter1 == 1)&&(irState1 == LOW)&&(isFading1 == LOW)){     
      Tlc.clear();
      for (int i = 0; i < 16; i++){                                                //from channel 0 - 15
        uint32_t startMillis1 = millis() + ((LEDSpeed1*(i+1)));               //start time is a function of LEDspeed constant, channel and how many waves have occured
        uint32_t endMillis1 = startMillis1 + (duration1);                       //end time is start time plus duration
        tlc_addFade(i, 0, maxValue, startMillis1, endMillis1);                         //add Fade up
        tlc_addFade(i, maxValue, midValue, endMillis1, endMillis1 + (duration1*4));    //add fade down
        tlc_addFade(i, midValue, (maxValue*.5), endMillis1 + (duration1*4), (endMillis1 + (duration1*4))+duration1);                         //add Fade up
        tlc_addFade(i, (maxValue*.5), 0, (endMillis1 + (duration1*4))+duration1, (endMillis1 + (duration1*4))+duration1 + (duration2));    //add fade down
        tlc_updateFades();                                                     //update
        irState1 = LOW;                                                        //set IRstate low
      }
      Tlc.clear();
      tlc_updateFades(); 
      counter1++; 
    }
  }
  if (tlc_fadeBufferSize < TLC_FADE_BUFFER_LENGTH - 2) {
    if ((counter2 == 1)&&(irState2 == LOW)&&(isFading2 == LOW)){     
      // Tlc.clear();
      for (int i = 16; i < 32; i++){                                                

        uint32_t startMillis1 = millis() + ((LEDSpeed1*(i-15)));               
        uint32_t endMillis1 = startMillis1 + (duration1);                       
        tlc_addFade(i, 0, maxValue, startMillis1, endMillis1);                         
        tlc_addFade(i, maxValue, midValue, endMillis1, endMillis1 + (duration1*4));    
        tlc_addFade(i, midValue, (maxValue*.5), endMillis1 + (duration1*4), (endMillis1 + (duration1*4))+duration1);                         
        tlc_addFade(i, (maxValue*.5), 0, (endMillis1 + (duration1*4))+duration1, (endMillis1 + (duration1*4))+duration1 + (duration2));  
        tlc_updateFades();                                                     
        irState2 = LOW;                                                        
      }
      Tlc.clear();
      tlc_updateFades();
      counter2++;   
    }
  }
  Tlc.clear();
  tlc_updateFades();  
}