Pages: 1 [2] 3 4 ... 18   Go Down
Author Topic: Library for TLC5940 16-channel PWM chip  (Read 33413 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay...I finally had a chance to play around with this today, and I'm getting a whole lot of nothing....

Are the only pins that need anything connected to them the ones listed in _pins.h? (not including VCC and GND, and whatever output pins that are in use) I'm connected to the +5V rail, though I've seen elsewhere that you should use 3.3V. If I read the spec sheet correctly, this really only effects the output amperage.

Also, on the Playground page, you (or whoever wrote it) said to tie DCPRG high, and to use a pull-up resistor on BLANK (I have a 1K resistor going to +5V; correct?). The only other pin I don't have anything documented is VPRG. THe Playground implies that it's used for something, but I don't see where/how. In the init() function, it's assigned -1 (which also mentions dot-correction, but I have no idea what purpose it serves).

So, all of that to say...what am I missing?  :-[
Logged


Seattle, WA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 81
Arduino rocks my socks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Using the v003 library from a few days ago (without changing the pins) the pin config is
  • TLC pin 28 -> LED (channel 1) short leg (cathode) -> LED1 long leg (anode) -> +5V
  • TLC pin 1 -> LED (channel 2)  cathode - anode -> +5V
  • ...
  • TLC pin 15 (lower right pin if the u is on top) - > LED (channel 16)
  • TLC pin 16 (XERR) -> nothing
  • TLC pin 17 (SOUT) -> nothing
  • TLC pin 18 (GSCLK) -> Arduino pin 3
  • TLC pin 19 (DCPRG) -> +5V
  • TLC pin 20 (IREF) - > 2.2Kohm resistor to GND (this determines max current through each output, Riref value = 39.06 / (desired current in A))
  • TLC pin 21 -> +5V
  • TLC pin 22 -> GND
  • TLC pin 23 (BLANK) -> Arduino pin 10
  • TLC pin 24 (XLAT) -> Arduino pin 9
  • TLC pin 25 (SCLK) -> Arduino pin 6
  • TLC pin 26 (SIN) -> Arduino pin 4
  • TLC pin 27 (VPRG) -> GND

Make sure you have a resistor (see above) between Iref (pin 20) and ground, and also that VPRG (pin 27) is grounded.  Hope this helps!  I'll put this at the top of all the examples.
« Last Edit: September 01, 2008, 04:05:25 pm by acleone » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bingo! Thanks, AC! I now have a glowing LED smiley-grin
Logged


New Jersey
Offline Offline
Full Member
***
Karma: 0
Posts: 193
Ard at work
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Samples in the mail, yippee!
Logged

----------
Mathieu

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Okay...I should have posted this last night, while I had my code in front of me...but I didn't.

I'm trying to get my LEDs to pseudo-randomly fade (intensity, length of fade, and delay until fade). After 2-3 loops, it's as if the timer breaks down. Rather than a series of slow, (sort of) subtle changes, it's a horrendous seizure-inducing strobe effect.

I added some serial output to see the values getting passed, and the values are all a-ok, and the time between loops (checking millis() at the beginning of each) is appropriately spaced. Yet, everything is running at super-speed.

I originally had 6 LEDs running this, but I dropped down to one, just to see what was going on.

my code (as best as I can remember it), without the serial output.
Code:
void setup()
{
    Tlc.init();
    Tlc.resetTimers();
}
void loop()
{
    aLast = a; //our previous intensity
    a = random(0, 4095); //grab our new intensity

    fadeDuration = random(500, 1500); //duration of fade between .5 and 1.5 seconds
    fadeDelay = random(5000, 15000); //delay before fading between 5 and 15 seconds

    Tlc.newFade(3, fadeDuration, aLast, a, fadeDelay);
    while(Tlc.updateFades());
}

So, with that, I get about 2-3 "appropriately" timed fades, before it clicks into strobe mode. I should note, too, that the "strobe mode" appears to be following the code correctly, except that it's almost as if the changes are occurring at 1/100th of the time (i.e. 15000ms becomes 150ms). It's a high-intensity red LED, so I can't stand to look at it for very long, even from the side, especially when it's flickering.
Logged


Seattle, WA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 81
Arduino rocks my socks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

[size=12]Updates: TLC5940LEDv004.zip[/size]

For people who want to use the TLC5940 to drive motors, use the old library from the first post for now.  The PWM period for the TLC5940LED library is fixed at 488Hz, which might be too fast for driving a DC motor.

Just as a note, the TLC should act as GND for whatever you're using with it (voltage should flow from +5V, through whatever, and into the TLC pin).  If you want to use RGB LEDs, make sure the LED is common anode (meaning each color shares the same +5V pin)

nphillips:
Code:
(unsigned long)      fadeDelay = millis() + random(5000, 15000);
The last parameter of Tlc.newFade is the start time in millis.  v004 has proper commenting in the examples (sorry)!

Also, if you need to run more than 5 fades at once (if you call newFade more than 5 times before while(Tlc.updateFades())smiley-wink, you need to add more parameters to Tlc.init.  For say 10 fades at once, use Tlc.init(1 tlc, 10 fades).  Tlc.newFade(...) will return false if you have too many fades running at once.
« Last Edit: September 02, 2008, 04:32:54 pm by acleone » Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
nphillips:
Code:
(unsigned long)      fadeDelay = millis() + random(5000, 15000);
The last parameter of Tlc.newFade is the start time in millis.  v004 has proper commenting in the examples (sorry)!
Ah hah! I suppose if I paid closer attention to your example, too, it would have been obvious. (testfades002 is what I used to help construct my code)

Quote
Also, if you need to run more than 5 fades at once (if you call newFade more than 5 times before while(Tlc.updateFades())smiley-wink, you need to add more parameters to Tlc.init.  For say 10 fades at once, use Tlc.init(1 tlc, 10 fades).  Tlc.newFade(...) will return false if you have too many fades running at once.
Is there an upper bound to this? Rather, will it break if I try to have it run a boat-load of fades? (I may end up looking at 32+ LEDs for one project....)
Logged


Seattle, WA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 81
Arduino rocks my socks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Is there an upper bound to this? Rather, will it break if I try to have it run a boat-load of fades? (I may end up looking at 32+ LEDs for one project....)
Each fade takes up 12 bytes of the 1024 byte SRAM.  I don't know how much SRAM is used normally, but I'm guessing you could have like 64 fades (768 bytes) at once.  Just keep trying higher values until something breaks!

But that's only running at once; if some finish and you want to start more, you could do something like
Code:
// create a bunch of fades
Tlc.newFade(...);
Tlc.newFade(...);
Tlc.newFade(...);
...
while (Tlc.updateFades()) {
  if(Tlc.newFade(...)) {
    // added successfully!
  } else {
    // too many fades right now
  }
}
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That worked perfectly, acleone!

Once again, thanks for the amazing library, and quick, helpful responses!

Now, I just need to buy more LEDs...  :o
Logged


New Jersey
Offline Offline
Full Member
***
Karma: 0
Posts: 193
Ard at work
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
For people who want to use the TLC5940 to drive motors, use the old library from the first post for now.  The PWM period for the TLC5940LED library is fixed at 488Hz, which might be too fast for driving a DC motor.

As far as those 3V/80mA Sparkfun vibration motors are concerned, they seem to run fine at 500Hz, ramping up and down smoothly, based on prior experience. Alas, I won't be able to confirm with the TLC5940 for at least two weeks (vacation).

Quote
Just as a note, the TLC should act as GND for whatever you're using with it (voltage should flow from +5V, through whatever, and into the TLC pin).  

Thanks for the pointer. Turns out that's how I had it wired in the old setup (PWM pins on the low side) but now I'll make sure to carry it over to the TLC5940 setup.
Logged

----------
Mathieu

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Yet another question, acleone smiley-grin

Is there a way to get the immediate grayscale value of a particular channel?

In your last response, you had mentioned running additional newFade() functions inside the updateFades() while loop. I'd like to experiment with "interactions" between LEDs during the fading process and being able to grab the current value of an LED would be perfect.

Minor Example:
Code:
while(updateFades())
{
    if(getGreyscaleValue(3) > 2048)
    {
        newFade(4, 1000, 1024, 4095);
    }
}

I'll admit, I haven't delved too deeply into the code, so there may be something available I could use, without the need of anything additional. (/me goes off to skim the code as best he can)

EDIT:
Line 243 of TLC5940LED.cpp:
Code:
Tlc.set(fp->channel, fp->endValue - ((((int32_t)(fp->stopMillis - currentMillis)) * fp->dValue) / fp->duration));
That looks like it has what I'd need. Unfortunately, I don't know enough c++ to figure out whether or not I could pull that information from within the sketch itself, or if I would need to write a function for it.

I'm not 100% sure how to use structs, but it does appear that you're incrementing it, as if it's an array of data. If that's the case, it should be pretty easy to build a simple array of integers containing the current values of all active LEDs. Though, for larger numbers of LEDs, this would get fairly memory-intensive.

EDIT 2:
Would something like this work:
Code:
int TLC5940LED::getGreyscaleValue(uint8_t channel)
{
      struct fade *fp = channel;
      return (fp->endValue - ((((int32_t)(fp->stopMillis - currentMillis)) * fp->dValue) / fp->duration));
}
Again, I'm operating at Ignorance Level 10 (of 10). And I know I'm missing error-checking.
« Last Edit: September 03, 2008, 12:37:09 pm by nphillips » Logged


Seattle, WA
Offline Offline
Jr. Member
**
Karma: 1
Posts: 81
Arduino rocks my socks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Major points for delving into my horrible code!  You're kind of close; all the current LED states are stored in the _GSData array.  The problem is the array packs all the data together to save space.

I don't have my Arduino at the moment, but try this version.  I added Tlc.get(channel(1-16));, eg
Code:
int value = Tlc.get(1);
Logged

0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Awesome. I don't have my Ardy around either...but I'll certainly give it a whirl tonight!

And, your code isn't horrible, by any means. I once had to debug an entire patchwork content manager written by a 16 year old from the Ukraine. Now, I'm not making fun of the Ukranian Language...but the kid used nothing more than 2-character variable/function/class names, and had maybe 6 comments for 2000+ lines of code. Maybe it made sense in his native tongue, but it didn't make a lick of sense to me. THAT was deserving of points for delving into horrible code!  ;D
Logged


0
Offline Offline
Jr. Member
**
Karma: 0
Posts: 70
Slowly Developing
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hmm...finally got around to trying out the Tlc.get() function, but it doesn't compile.

the line of code with the error:
Code:
j = Tlc.get(ledPins[5]);

the error returned:
Code:
o: In function `loop':
undefined reference to `TLC5940LED::get(unsigned char)'
Logged


Austin, TX USA
Offline Offline
God Member
*****
Karma: 5
Posts: 997
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

That usually means that your library's .o file is not available in the expected place.  See by comparison the EEPROM library, which is in hardware/libraries/EEPROM/EEPROM.o.

Mikal
Logged

Pages: 1 [2] 3 4 ... 18   Go Up
Jump to: