[SOLVED] Arduino Uno & TLC5940

I have an arduino connected to a TLC5940 currently controlling a row of 4 rbg leds. I'm utilizing the TLC5940 library found at Arduino Playground - HomePage. I'm trying to program a running pattern through the 4 leds. I'm finding though that it skips the first iteration of the void loop. I left a serial output in the code to monitor the counter steps and a delay of 5000ms to give enough time to confirm with the serial and the lit led. The variable counter should initialize at 0 (the serial output confirms this) and then step up by 1 after each loop. Even though counter outputs 0 it isn't tripping the if statement to trigger the led until the next time around. I could really use some help with this one cause I'm really stumped. Thank you to all in advance.

int counter;
#include "Tlc5940.h"

void setup()
{
  Tlc.init();
  Serial.begin(9600);
}
     
void loop()
{  
  Serial.println(counter);
  
  if (counter == 0)
  {
    setLedColor1(4095, 0, 0);
  }
  else
  {
    setLedColor1(0, 0, 0);
  }
  
  if (counter == 1)
  {
    setLedColor2(4095, 0, 0);
  }
  else
  {
    setLedColor2(0, 0, 0);
  }
  
  if (counter == 2)
  {
    setLedColor3(4095, 0, 0);
  }
  else
  {
    setLedColor3(0, 0, 0);
  }
  
  if (counter == 3)
  {
    setLedColor4(4095, 0, 0);
  }
  else
  {
    setLedColor4(0, 0, 0);
  }
  
  Tlc.update();
  delay(5000);
  
  if (counter == 3)
  {
    counter = 0;
  }
  else
  {
    counter = counter + 1;
  }
}

void setLedColor1(int redPin1, int greenPin1, int bluePin1)
{
  Tlc.set(0, redPin1);
  Tlc.set(1, greenPin1);
  Tlc.set(2, bluePin1);
}

void setLedColor2(int redPin2, int greenPin2, int bluePin2)
{
  Tlc.set(3, redPin2);
  Tlc.set(4, greenPin2);
  Tlc.set(5, bluePin2);
}

void setLedColor3(int redPin3, int greenPin3, int bluePin3)
{
  Tlc.set(6, redPin3);
  Tlc.set(7, greenPin3);
  Tlc.set(8, bluePin3);
}

void setLedColor4(int redPin4, int greenPin4, int bluePin4)
{
  Tlc.set(9, redPin4);
  Tlc.set(10, greenPin4);
  Tlc.set(11, bluePin4);
}
if (counter == 0)
  {
    setLedColor1(4095, 0, 0);
    Serial.println ("setLedColor1(4095, 0, 0)");
  }
  else
  {
    setLedColor1(0, 0, 0);
    Serial.println ("setLedColor1(0, 0, 0)");
  }

And now?

Thanks for taking the time to reply but there was no change. It still won't light the first led on the first loop when the variable counter is initialized at 0. I did try to utilize a for statement but I had the same results.

but there was no change

But what about the serial output?

Yes the serial output did change. Below is a copy of the serial output

0
setLedColor1(4095, 0, 0)
1
setLedColor1(0, 0, 0)
2
setLedColor1(0, 0, 0)
3
setLedColor1(0, 0, 0)
0
setLedColor1(4095, 0, 0)
1
setLedColor1(0, 0, 0)
2
setLedColor1(0, 0, 0)
3
setLedColor1(0, 0, 0)

So, how do you explain your earlier statement

Even though counter outputs 0 it isn't tripping the if statement to trigger the led

?

Grew01 - you are missing the point. You don't need those else clauses in the if statements. They are screwing your code up. The else gets done in every if statement except one of them.

AWOL - Point well taken... I did not connect those dots. Any idea then why it would not trigger the setLedColor1 function on the first iteration of the loop but it will on the 5th.

Grumpy_Mike - Without the else clauses the lit led will not be turned off after the next led is selected. I did remove the else clauses for the sake of it and the first led will still not turn on until the second led is lit.

Grumpy_Mike:
Grew01 - you are missing the point. You don't need those else clauses in the if statements. They are screwing your code up. The else gets done in every if statement except one of them.

Yes, but they wouldn't stop it working.

I can't see anything wrong in the code, it must be something weird in the TLC library. Try adding a "TLC.update()" inside setup().

fungus:
Try adding a "TLC.update()" inside setup().

I tried this and still have the same results.

I opened a new thread on Sparkfun's forum to gather some more input on this problem. I figured I'd post a link to this discussion for anyone else who is encountering this problem. Hopefully between these two great websites there will be plenty of information available to generate an answer.

https://forum.sparkfun.com/viewtopic.php?f=32&t=35866

Well it took awhile but I have found a solution to the problem. I can't believe how simple the answer was this whole time. It would seem that the TLC5940 library needs a second to initialize. By simply adding a delay of 1ms to the beginning of the loop() solves everything. Here is a copy of the corrected code for those who need it.

#include "Tlc5940.h"
#include "tlc_config.h"
int counter;

void setup()
{
  Tlc.init();
}
     
void loop()
{  
  delay(1);
  
  if (counter == 0)
  {
    setLedColor1(4095, 0, 0);
  }
  else
  {
    setLedColor1(0, 0, 0);
  }
  
  if (counter == 1)
  {
    setLedColor2(4095, 0, 0);
  }
  else
  {
    setLedColor2(0, 0, 0);
  }
  
  if (counter == 2)
  {
    setLedColor3(4095, 0, 0);
  }
  else
  {
    setLedColor3(0, 0, 0);
  }
  
  if (counter == 3)
  {
    setLedColor4(4095, 0, 0);
  }
  else
  {
    setLedColor4(0, 0, 0);
  }
  
  Tlc.update();
  delay(100);
  
  if (counter == 3)
  {
    counter = 0;
  }
  else
  {
    counter = counter + 1;
  }
}

void setLedColor1(int redPin1, int greenPin1, int bluePin1)
{
  Tlc.set(0, redPin1);
  Tlc.set(1, greenPin1);
  Tlc.set(2, bluePin1);
}

void setLedColor2(int redPin2, int greenPin2, int bluePin2)
{
  Tlc.set(3, redPin2);
  Tlc.set(4, greenPin2);
  Tlc.set(5, bluePin2);
}

void setLedColor3(int redPin3, int greenPin3, int bluePin3)
{
  Tlc.set(6, redPin3);
  Tlc.set(7, greenPin3);
  Tlc.set(8, bluePin3);
}

void setLedColor4(int redPin4, int greenPin4, int bluePin4)
{
  Tlc.set(9, redPin4);
  Tlc.set(10, greenPin4);
  Tlc.set(11, bluePin4);
}

I hope this will help any others who are currently fighting this problem now or in the future. Thank you again to everyone who took the time to review this problem and suggest solutions.

That delay isn't a one second delay, it is a one millisecond delay that is done continuously for each iteration of the loop(). Initialization implies it only has to done once, which I would expect in the setup(). This delay seems to be needed to allow the TLC to update itself and perform its duty before it is ready to start over.

Or is this wrong?

You are correct that the delay isn't one second but one millisecond (ms). I did state this in my previous post, and was merely using the term second as a figure of speech.

Grew01:
By simply adding a delay of 1ms to the beginning of the loop() solves everything.

You are again correct that the delay does not need to be in the loop(). The delay works just fine when placed in the setup(). This error was my fault. Once I had the code working I left it alone, and did not bother to try the delay in the setup(). Here is the revision of that code.

#include "Tlc5940.h"
#include "tlc_config.h"
int counter;

void setup()
{
  Tlc.init();
  delay(1);
}
     
void loop()
{
  if (counter == 0)
  {
    setLedColor1(4095, 0, 0);
  }
  else
  {
    setLedColor1(0, 0, 0);
  }
  
  if (counter == 1)
  {
    setLedColor2(4095, 0, 0);
  }
  else
  {
    setLedColor2(0, 0, 0);
  }
  
  if (counter == 2)
  {
    setLedColor3(4095, 0, 0);
  }
  else
  {
    setLedColor3(0, 0, 0);
  }
  
  if (counter == 3)
  {
    setLedColor4(4095, 0, 0);
  }
  else
  {
    setLedColor4(0, 0, 0);
  }
  
  Tlc.update();
  delay(100);
  
  if (counter == 3)
  {
    counter = 0;
  }
  else
  {
    counter = counter + 1;
  }
}

void setLedColor1(int redPin1, int greenPin1, int bluePin1)
{
  Tlc.set(0, redPin1);
  Tlc.set(1, greenPin1);
  Tlc.set(2, bluePin1);
}

void setLedColor2(int redPin2, int greenPin2, int bluePin2)
{
  Tlc.set(3, redPin2);
  Tlc.set(4, greenPin2);
  Tlc.set(5, bluePin2);
}

void setLedColor3(int redPin3, int greenPin3, int bluePin3)
{
  Tlc.set(6, redPin3);
  Tlc.set(7, greenPin3);
  Tlc.set(8, bluePin3);
}

void setLedColor4(int redPin4, int greenPin4, int bluePin4)
{
  Tlc.set(9, redPin4);
  Tlc.set(10, greenPin4);
  Tlc.set(11, bluePin4);
}

I'm still unsure why the delay is even needed for this program to work. I had successful programmed a series of 8 leds in a 2x4 grid to randomly light up different colors before I tried programming the running light code. It never skipped the first iteration of the loop() like the running light program. Here is a copy of that program for review.

#include "Tlc5940.h"
#include "tlc_config.h"
int randomLedColor1;
int randomLedColor2;
int randomLedColor3;
int randomLedColor4;
int randomLedColor5;
int randomLedColor6;
int randomLedColor7;
int randomLedColor8;
int lastRandomLedColor1;
int lastRandomLedColor2;
int lastRandomLedColor3;
int lastRandomLedColor4;
int lastRandomLedColor5;
int lastRandomLedColor6;
int lastRandomLedColor7;
int lastRandomLedColor8;

void setup()
{
  Tlc.init();
}
     
void loop()
{
  do
  {
    randomLedColor1 = random(7);
    randomLedColor2 = random(7);
    randomLedColor3 = random(7);
    randomLedColor4 = random(7);
  } while(randomLedColor1 == randomLedColor2 || randomLedColor1 == randomLedColor3 || randomLedColor1 == randomLedColor4 || randomLedColor2 == randomLedColor3 || randomLedColor2 == randomLedColor4 || randomLedColor3 == randomLedColor4 || randomLedColor1 == lastRandomLedColor1 || randomLedColor2 == lastRandomLedColor2 || randomLedColor3 == lastRandomLedColor3 || randomLedColor4 == lastRandomLedColor4);
  
  do
  {
    randomLedColor5 = random(7);
    randomLedColor6 = random(7);
    randomLedColor7 = random(7);
    randomLedColor8 = random(7);
  } while(randomLedColor5 == randomLedColor6 || randomLedColor5 == randomLedColor7 || randomLedColor5 == randomLedColor8 || randomLedColor5 == randomLedColor1 || randomLedColor5 == randomLedColor2 || randomLedColor6 == randomLedColor7 || randomLedColor6 == randomLedColor8 || randomLedColor6 == randomLedColor1 || randomLedColor6 == randomLedColor2 || randomLedColor6 == randomLedColor3 || randomLedColor7 == randomLedColor8 || randomLedColor7 == randomLedColor2 || randomLedColor7 == randomLedColor3 || randomLedColor7 == randomLedColor4 || randomLedColor8 == randomLedColor3 || randomLedColor8 == randomLedColor4 || randomLedColor5 == lastRandomLedColor5 || randomLedColor6 == lastRandomLedColor6 || randomLedColor7 == lastRandomLedColor7 || randomLedColor8 == lastRandomLedColor8);
  
  lastRandomLedColor1 = randomLedColor1;
  lastRandomLedColor2 = randomLedColor2;
  lastRandomLedColor3 = randomLedColor3;
  lastRandomLedColor4 = randomLedColor4;
  lastRandomLedColor5 = randomLedColor5;
  lastRandomLedColor6 = randomLedColor6;
  lastRandomLedColor7 = randomLedColor7;
  lastRandomLedColor8 = randomLedColor8;
  
  switch (randomLedColor1)
  {
    case 0: //red
      setLedColor1(4095, 0, 0);
      break;
    case 1: //green
      setLedColor1(0, 4095, 0);
      break;
    case 2: //blue
      setLedColor1(0, 0, 4095);
      break;
    case 3: //yellow
      setLedColor1(4095, 4095, 0);
      break;
    case 4: //cyan
      setLedColor1(0, 4095, 4095);
      break;
    case 5: //magenta
      setLedColor1(4095, 0, 4095);
      break;
    case 6: //orange
      setLedColor1(4095, 1023, 0);
  }
  
  switch (randomLedColor2)
  {
    case 0: //red
      setLedColor2(4095, 0, 0);
      break;
    case 1: //green
      setLedColor2(0, 4095, 0);
      break;
    case 2: //blue
      setLedColor2(0, 0, 4095);
      break;
    case 3: //yellow
      setLedColor2(4095, 4095, 0);
      break;
    case 4: //cyan
      setLedColor2(0, 4095, 4095);
      break;
    case 5: //magenta
      setLedColor2(4095, 0, 4095);
      break;
    case 6: //orange
      setLedColor2(4095, 1023, 0);
  }
  
  switch (randomLedColor3)
  {
    case 0: //red
      setLedColor3(4095, 0, 0);
      break;
    case 1: //green
      setLedColor3(0, 4095, 0);
      break;
    case 2: //blue
      setLedColor3(0, 0, 4095);
      break;
    case 3: //yellow
      setLedColor3(4095, 4095, 0);
      break;
    case 4: //cyan
      setLedColor3(0, 4095, 4095);
      break;
    case 5: //magenta
      setLedColor3(4095, 0, 4095);
      break;
    case 6: //orange
      setLedColor3(4095, 1023, 0);
  }
  
  switch (randomLedColor4)
  {
    case 0: //red
      setLedColor4(4095, 0, 0);
      break;
    case 1: //green
      setLedColor4(0, 4095, 0);
      break;
    case 2: //blue
      setLedColor4(0, 0, 4095);
      break;
    case 3: //yellow
      setLedColor4(4095, 4095, 0);
      break;
    case 4: //cyan
      setLedColor4(0, 4095, 4095);
      break;
    case 5: //magenta
      setLedColor4(4095, 0, 4095);
      break;
    case 6: //orange
      setLedColor4(4095, 1023, 0);
  }
  
  switch (randomLedColor5)
  {
    case 0: //red
      setLedColor5(4095, 0, 0);
      break;
    case 1: //green
      setLedColor5(0, 4095, 0);
      break;
    case 2: //blue
      setLedColor5(0, 0, 4095);
      break;
    case 3: //yellow
      setLedColor5(4095, 4095, 0);
      break;
    case 4: //cyan
      setLedColor5(0, 4095, 4095);
      break;
    case 5: //magenta
      setLedColor5(4095, 0, 4095);
      break;
    case 6: //orange
      setLedColor5(4095, 1023, 0);
  }
  
  switch (randomLedColor6)
  {
    case 0: //red
      setLedColor6(4095, 0, 0);
      break;
    case 1: //green
      setLedColor6(0, 4095, 0);
      break;
    case 2: //blue
      setLedColor6(0, 0, 4095);
      break;
    case 3: //yellow
      setLedColor6(4095, 4095, 0);
      break;
    case 4: //cyan
      setLedColor6(0, 4095, 4095);
      break;
    case 5: //magenta
      setLedColor6(4095, 0, 4095);
      break;
    case 6: //orange
      setLedColor6(4095, 1023, 0);
  }
  
  switch (randomLedColor7)
  {
    case 0: //red
      setLedColor7(4095, 0, 0);
      break;
    case 1: //green
      setLedColor7(0, 4095, 0);
      break;
    case 2: //blue
      setLedColor7(0, 0, 4095);
      break;
    case 3: //yellow
      setLedColor7(4095, 4095, 0);
      break;
    case 4: //cyan
      setLedColor7(0, 4095, 4095);
      break;
    case 5: //magenta
      setLedColor7(4095, 0, 4095);
      break;
    case 6: //orange
      setLedColor7(4095, 1023, 0);
  }
  
  switch (randomLedColor8)
  {
    case 0: //red
      setLedColor8(4095, 0, 0);
      break;
    case 1: //green
      setLedColor8(0, 4095, 0);
      break;
    case 2: //blue
      setLedColor8(0, 0, 4095);
      break;
    case 3: //yellow
      setLedColor8(4095, 4095, 0);
      break;
    case 4: //cyan
      setLedColor8(0, 4095, 4095);
      break;
    case 5: //magenta
      setLedColor8(4095, 0, 4095);
      break;
    case 6: //orange
      setLedColor8(4095, 1023, 0);
  }
  
  Tlc.update();
  delay(200);
}

void setLedColor1(int redPin1, int greenPin1, int bluePin1)
{
  Tlc.set(0, redPin1);
  Tlc.set(1, greenPin1);
  Tlc.set(2, bluePin1);
}

void setLedColor2(int redPin2, int greenPin2, int bluePin2)
{
  Tlc.set(3, redPin2);
  Tlc.set(4, greenPin2);
  Tlc.set(5, bluePin2);
}

void setLedColor3(int redPin3, int greenPin3, int bluePin3)
{
  Tlc.set(6, redPin3);
  Tlc.set(7, greenPin3);
  Tlc.set(8, bluePin3);
}

void setLedColor4(int redPin4, int greenPin4, int bluePin4)
{
  Tlc.set(9, redPin4);
  Tlc.set(10, greenPin4);
  Tlc.set(11, bluePin4);
}

void setLedColor5(int redPin5, int greenPin5, int bluePin5)
{
  Tlc.set(12, redPin5);
  Tlc.set(13, greenPin5);
  Tlc.set(14, bluePin5);
}

void setLedColor6(int redPin6, int greenPin6, int bluePin6)
{
  Tlc.set(15, redPin6);
  Tlc.set(16, greenPin6);
  Tlc.set(17, bluePin6);
}

void setLedColor7(int redPin7, int greenPin7, int bluePin7)
{
  Tlc.set(18, redPin7);
  Tlc.set(19, greenPin7);
  Tlc.set(20, bluePin7);
}

void setLedColor8(int redPin8, int greenPin8, int bluePin8)
{
  Tlc.set(21, redPin8);
  Tlc.set(22, greenPin8);
  Tlc.set(23, bluePin8);
}

I assume it just needs the time after the init call. You should definitely check out the init() method of the TLC library to investigate what it is doing in there. Seems strange though that it needs a ms in the setup only, good find though.

I noticed this:

if (counter == 3)
  {
    counter = 0;
  }
  else
  {
    counter = counter + 1;
  }

Which I would write like this:

counter = ++counter % 3;

Probably not more efficient but it is cleaner :slight_smile: