Pages: 1 ... 9 10 [11] 12 13 ... 18   Go Down
Author Topic: Library for TLC5940 16-channel PWM chip  (Read 32128 times)
0 Members and 1 Guest are viewing this topic.
Varese, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 121
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi very instresting lib and chip! Someone had tried to connect 2 or more TLC5940 in series? i mean Arduino -> |SIN ->SOUT| -> |SIN ...
this could be very useful to drive long chain on LED
Logged


Varese, Italy
Offline Offline
Full Member
***
Karma: 0
Posts: 121
Arduino rocks
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

sorry i must pay more attention on old post... so yes it is possible, i read that could be problem if we conncect more than 10 TLC is this still true or you are found a work around?
« Last Edit: February 08, 2009, 03:50:37 pm by ale914 » Logged


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

As far as I know, you can definitely daisy-chain more than 10 5940s.

acleone has a few pics up where he's using 3 of them to drive 16 RGB LEDs (48 total!).

FWIW, I seem to recall seeing that the upper limit was 32 chained chips. Don't quote me on that, though. (I skimmed the thread, but didn't immediately see anything about it)
Logged


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

I might be popping this into the wrong thread, but since it's related to the library, I'll start here.

My project has two states - manual & automatic. In order to switch between the two, I have a mini pushbutton. Unfortunately, it's cheap, and bounces like a kid on a trampoline -- usually 3-6 times, depending on how I push it.

The mode is "monitored" by a boolean - 1 or 0, and an interrupt changes the value of it.

Unfortunately, when you trigger the interrupt, it runs it's code, then goes right back to where the program was last running. If it's in the middle of the automatic function, it could take up to 30 seconds before the state change is put into effect (LEDs fade between colors, with a delay(30000) between each fade).

As a "fix" I moved the button from an interrupt to the reset pin, and save the state variable into EEPROM. Then, everytime the arduino is powered off or reset, it switches modes. Personally, I think this method is horribly kludgy, if not "inappropriate."

I suppose I could simply break down the delay segments into 10ms increments, and lump them together in a small loop that watches for a change in the state. But that still doesn't fix the bouncing issue.

My "Perfect Case Scenario" would be that if a user pushes the button, the state is switched, and the main loop() would restart, regardless of where the program currently is.

So, to summarize all of this:
  • How can I debounce an interrupt? (I'm low on physical space, so proper hardware debouncing (using a schmitt trigger) isn't a great option)
  • How can I get the interrupt to literally stop everything and start back at the beginning of the main loop()?

Thanks!
Logged


SF Bay Area
Offline Offline
Edison Member
*
Karma: 11
Posts: 1244
Arduino Ninja
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

1. Debounce an interrupt pin by disabling the interrupt as soon as you see it, waiting a debounce interval (typically 10 to 30 ms) and recheck the input to make sure it's the same state. Enable the interrupt again after you've done what you wanted to do.

2. Break the delay into smaller chunks and exit the loop when necessary.
Logged

Unique RGB LED Modules and Arduino shields: http://www.macetech.com/store

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

1. Aha! I should have thought of that. I merely added a 10ms delay into the interrupt function, but for whatever reason, it locked everything up (even going as low as 1ms, too!)

2. I figured as much.


Also, is there any sort of "limit" to the interrupts? For whatever reason, I could only push the button 3-4 times before the entire system locked up. It was almost like the Arduino was getting angry someone "ringing the doorbell" all the time. Initially, it seemed like I could hit it 30-40 times without a problem, but then it only allowed me to do it a tiny handful of times. This is between resets and reprogrammings, too.

Could it be that I'm pushing too much information into memory? I have a quite a few ints and integer arrays

16 ints for pin mappings
3 1x7 integer arrays for color maps
4 1x3 integer arrays for color settings
4 longs for millis()

plus a few more for random other things, but those above are global (they're used in quite a few functions; I'm not just lazy). Should I use #define for them instead? The pin maps and color arrays are static.

Edit: the final size of the sketch burned is about 6k, if that helps at all.
« Last Edit: February 09, 2009, 02:23:46 pm by nphillips » Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I ran across this thread while searching to resolve a problem I'm having using attachInterrupt(). According to the reference page:

Quote
Inside the attached function, delay() won't work and the value returned by millis() will not increment. Serial data received while in the function may be lost. You should declare as volatile any variables that you modify within the attached function.

I thought of using a debounce delay in the interrupt function until I remembered reading this...
Logged

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

Okay...this is crazy...

either I'm doing something horribly wrong, or....I'm doing something horribly wrong.

Here's my interrupt code:

Code:
void changeMode(void)
{
  detachInterrupt(0);
  debounce = 1;
  Serial.println(repeater++);
  setMode = !setMode;
}
...and the middle of the delays where my issue was...
Code:
while(tlc_updateFades()) {
      if (setMode == 0) { return 0; }
    }
    for(int i=0;i<delayTime/10;i++)
    {
      if (setMode == 0) { return 0; }
      delay(10);
    }
...and then back at the beginning of loop() once it all starts back up again
Code:
if(debounce == 0)
  {
      //do nothing
  }
  else
  {
    delay(50);
    attachInterrupt(0, changeMode, FALLING);
    debounce = 0;
  }
So, what it should be doing is
  • triggering the interrupt
  • turning off the interrupt
  • changing setMode to 0 and making debouncer = 1
  • returning to the current function
  • catch setMode being switched back to 0
  • return to the beginning of loop()
  • reactivate the interrupt after 50ms
But somehow, I still see 2-3 bounces, and it still locks up after a couple of button presses.

EDIT:
Never mind...I found a couple of good examples of how folks were debouncing their interrupts, and I'll give them a whirl tonight.
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1223543716/
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1216607685/1#1
« Last Edit: February 10, 2009, 09:28:37 am by nphillips » Logged


0
Offline Offline
Newbie
*
Karma: 0
Posts: 3
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I followed the links and above and implemented the check for time between interrupts in my interrupt function. It works for me. However, I believe the documentation for attachInterrupt() http://www.arduino.cc/en/Reference/AttachInterrupt is either incorrect or possibly just needs to be worded more clearly as it states
Quote
...the value returned by millis() will not increment.
I jumped to the conclusion don't use millis() within the interrupt service routine but one could take it to mean that although millis() can be checked within the ISR subsequent invocations of millis() within the ISR will return the same value. I'll have to test to see if this is the case.

Cheers!
Logged

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

I think that's exactly the case -- millis() will always return the same value. As a result, delay() doesn't work, because the timer has stopped.
Logged


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

You can turn on interrupts, etc (so millis and serial will work) in an interrupt vector with
Code:
sei();

I updated the playground page to point to the Google Code project, thanks for the heads-up.
Logged

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

Quote
You can turn on interrupts, etc (so millis and serial will work) in an interrupt vector with
Code:
sei();

Is that run inside the interrupt? I'm trying to search around for more info on how it's used, but the most I can find is sei() enables interrupts (already there by default) and cli() disables them.

They apparently work at a deeper level than the attach/detachInterrupt() functions.
« Last Edit: February 10, 2009, 10:19:17 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

yes, that will work inside the interrupt.  See http://www.nongnu.org/avr-libc/user-manual/group__avr__interrupts.html
Logged

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

so, something like...
Code:
void myInterruptFunction(void)
{
    sei();
    delay(debounceDelay);
    //make state changes
}
...would work? I'm still not 100% sure how exactly it's supposed to work.

Or, should I just keep it simple:
Code:
void myInterruptFunction(void)
{
    if(lastInterrupt + 10 > millis())
    {
        //make state changes
        lastInterrupt = millis();
    }
    else
    {
        //do nothing
    }
}
Logged


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

Any time you want to use millis(), delay(), or Serial.xxx() inside an interrupt, you have call sei(); first.

This should work, but it might freeze the arduino if the interrupt is called repeatedly because it would keep getting called in the middle of the delay and would never return from the function.  You could lock it like so:
Code:
volatile char isRunning;
void myInterruptFunction(void)
{
  if (!isRunning) {
    isRunning = 1;
    sei();
    delay(debounceDelay);
    //make state changes
    isRunning = 0;
  }
}
Logged

Pages: 1 ... 9 10 [11] 12 13 ... 18   Go Up
Jump to: