5940nt flickering

Hey guys,
I'm using the TLC Library from Alex Leone dated 02/03/09 and I can't seem to get the LEDs to stop flickering during a Tlc.setAll() fade.
What am I missing to get the flickering to stop? Also there is no visible difference in brightness levels between about 1300 and 4095.

#include "Tlc5940.h"
int max=4095;

void setup()
{
  Tlc.init();
  Serial.begin(9600); //check speed
}
void loop()
{
 Tlc.clear();
   // Fade in all outputs
  for(int i=0;i<max;i+=5){
    Tlc.setAll(i);
  Tlc.update();  
  Serial.println(i);
    delay(5);
  }
  // Fade out all outputs
  for(int i=max;i>=0;i-=5){
    Tlc.setAll(i); 
   Tlc.update();
  Serial.println(i);
    delay(5);
  }
//    Tlc.update();
  }

Supply decoupling?

Does commenting out the Serial.print()s do anything to adjust the flicker?

As far as the brightness between 1300 and 4095...that's your eyes. Human eyes don't see brightness in linear steps. Google 'led pwm gamma' for more details, or check out this article from Maxim:

Chris

Yessir, 100uf at source and .1uf between 21 & 22 on tlc.
I was just wondering about the brightness cause with the standard 1024 analog pwm I can see the difference through the entire range.

I had the same problem when using cables longer than a few inches. Try probing all the data lines..
The pwm output seems to interfere with the data lines. I tried shielded twisted pair cable for the serial connection, which helped a bit, but still every once in a while one or more LEDs went crazy for a fraction of a second.

also, try smaller decoupling C values, as the switching frequency is pretty high.

Commenting out the Serial data does not help the flickering. Lowering the frequency helped a bit but not to much and I don't want to lower to much because I will not get the same effect. My data lines are all 18 guage solid core wires with the longest being 2 1/4 inches long with none of the pwm lines near them. I'm trying to get this to work small scale on a bread board so I can eventually scale it up to control around 34Amps worth of LEDs all doing a pulse in and out at the same time. Currently there are just three red leds attached to the setup and they flicker pretty badly.

With the brightness issue I think I could just use the inverse square law to make it linear.
I have the formula but not entirely sure how to implement it. PWM=range/sqrt(2)^domain*sqrt(2)^x
The only value I know is range which would be 4095 but I have no idea what ^ means (unless that mean to the power of since we can't type the little exponent up there?) and what would I use for domain and ^x?

Solved the flickering issue, it seems the breadboard I got from adafruit is worthless... No matter what circuit setup I use on that breadboard I get problems.

Still would like to know about more about how I can implement the inverse square law equation or any other that would help with a linear fade from around 10-4095

Glad you got the flickering issue resolved, that sucks about the breadboard.

I use the same formula for computing PWM steps, but simplified & rewritten as

range * 2 ^ ((x-domain) / 2)

yes, "^" means exponent.

Range is the bounds you want to cover, in this case it's 4095 because you want values from 0-4095.

Domain is one less than how many discrete steps you want to take to cover the range. For example say you want 20 levels of brightness, use 19 for the domain.

X=0, brightness = 0
X=1, brightness = 8
X=2, brightness = 11.31
...
X=18, brightness = 2895
X=19, brightness = 4095

Chris

Thanks for the explanation of that formula Chris, I will see if I can get that working in my sketchs.

I contacted Adafruit about the breadboard and they are replacing it for me, actually they have already shipped one out to me within a couple hours of my email to them. They are great over there and I would recommend them to anyone.

Ok, about that formula... How would I go about using it in my current code? would I just set my max value to that formula? Such as max = 4095 * 2 ^ ((x-20) / 2) the just let it increment through as it does currently?
Or should this be used as a function which is called? Lost here.

I usually precompute the values in Excel and store them in an array, I do this because the numbers aren't going to change and doing the math over and over just burns CPU.

Here's an example that turns the 255 steps of an Arduino pin PWM into 64 steps that look smoother:

#define NUM_DELTAS  64

byte deltaTable[NUM_DELTAS] = {
  0,1,2,2,3,4,4,5,6,7,8,9,10,11,12,13,14,16,17,18,20,21,23,25,27,29,31,33,35,37,40,42,45,48,51,54,58,61,65,69,73,77,82,86,91,97,102,108,
  114,121,127,134,142,150,158,167,176,186,196,206,217,229,242,255};

If you want to do the math on the Arduino I think something like this would work

word ComputePWMValue(word step) {
     return(int(RANGE * pow(2, (step-DOMAIN)/2)));
     }

Sorry for the stupid questions but how do you compute the values in Excel? Do you set the equation as stated earlier than just change x to the step value? I don't fully understand. I know if I got this down it would help tremendously in all future projects.

No problem.

Attached is a spreadsheet showing how I did this.

You need two numbers to start. The range (4095 in the case of the TLC5940) and the domain (or number of steps, 20 in my example).

Now you have Excel do all the math. For example for step 1 we'll get the formula:

4095 * 2 ^ ((1 - 20) / 2)

which works out to a value of about 6.

Similarly step 2 will give us 8, step 3 = 11, and so on.

To change the number of steps: change the value in cell B2, lengthen / shorten the column of numbers in A5...A24, and copy & paste (or delete) the function in any of the cells B5...B24.

Now that you have your numbers you can paste them into the Arduino IDE, and wrap that into an array declaration:

#define NUM_DELTAS 20

word pwmArray[NUM_DELTAS] = {6, 8, 11, 16, 23, 32, 45, 64, 90, 128, 181, 256, 362, 512, 724, 1024, 1448, 2048, 2896, 4095};

Then you can use a function like this to fade the lights up and down:

for (int i=0; i<NUM_DELTAS; i++) {
     FadeLight(pwmArray[i]);
     delay(100);
}
for (int i=NUM_DELTAS-1; i>=0; i--) {
    FadeLight(pwmArray[i]);
     delay(100);
}

PWM.xls (13.5 KB)

Thank You for that. Now its clear as day.