Offline
Full Member
Karma: 0
Posts: 189
|
 |
« on: April 28, 2012, 04:41:32 pm » |
I am looking to create a program that will flash up to 16 outputs at individually variable rates. The rates will eventually be set by DMX via a shield but can be set by serial for now. I am using a TLC5940 to control these outputs, but I understand coding for that and serial. I would assume that this would be timer and interrupt based? I just need an example for 2 outputs with individual rate control if anyone is willing to help
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #1 on: April 28, 2012, 05:48:42 pm » |
I have this code working, but it blinks not strobes. I need 10-20 ms pulses, not blinking #include <Tlc5940.h> #include <tlc_animations.h> #include <tlc_config.h> #include <tlc_fades.h> #include <tlc_progmem_utils.h> #include <tlc_servos.h> #include <tlc_shifts.h>
/* Blink Multiple LEDs without Delay * * Turns on and off several light emitting diode(LED) connected to a digital * pin, without using the delay() function. This means that other code * can run at the same time without being interrupted by the LED code. */ const int NUMLEDS = 8; byte pin[NUMLEDS] = {40,41,42,43,44,45,46,47}; long state[NUMLEDS] = {0,0,0,0,0,0,0,0}; unsigned long interval[NUMLEDS] = {100, 200, 300, 400, 500, 600, 700, 800}; unsigned long time[NUMLEDS];
void setup() { Tlc.init(); }
void loop() { unsigned long m = millis();
for (int i=0; i<NUMLEDS; ++i)
if (m - time[i] > interval[i]) { time[i] = m; state[i] = state[i] == 0 ? 4095 : 0; Tlc.set(pin[i], state[i]); Tlc.update(); } }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #2 on: April 28, 2012, 08:18:50 pm » |
Ok, I have a sketch written, works great **EDIT** If I set them all to the same interval, the first channel acts as expected, and the others act in reverse? Why would this happen? #include <Tlc5940.h>
/* Blink Multiple LEDs without Delay * * Turns on and off several light emitting diode(LED) connected to a digital * pin, without using the delay() function. This means that other code * can run at the same time without being interrupted by the LED code. */ const int NUMLEDS = 8; byte pin[NUMLEDS] = {40,41,42,43,44,45,46,47}; long state[NUMLEDS] = {0,0,0,0,0,0,0,0}; unsigned long interval[NUMLEDS] = {200, 1000, 300, 400, 250, 1500, 700, 2000}; unsigned long time[NUMLEDS];
void setup() {
Tlc.init(); }
void loop() { unsigned long m = millis();
for (int i=0; i<NUMLEDS; ++i) if (state[i] == 4095){ if (m - time[i] > 15) { time[i] = m; state[i] = state[i] == 0 ? 4095 : 0; Tlc.set(pin[i], state[i]); Tlc.update(); }} else{ if (m - time[i] > interval[i]) { time[i] = m; state[i] = state[i] == 0 ? 4095 : 0; Tlc.set(pin[i], state[i]); Tlc.update(); } } }
|
|
|
|
« Last Edit: April 28, 2012, 08:31:52 pm by ematson5897 »
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25522
Solder is electric glue
|
 |
« Reply #3 on: April 28, 2012, 10:13:26 pm » |
This code does a very similar thing but uses the built in pins and has a randomly assigned blink / strobe time. /* Random blinking lights for use on a christmas tree By Mike Cook */
#define numberOfLights 16
byte pins[] = {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18}; byte pinState[numberOfLights]; long int changeTime[numberOfLights]; int flashRate[numberOfLights]; long flashChange; // how often to change the flashing patterns
void setup() { for(int i = 0; i< numberOfLights; i++) { pinMode(pins[i], OUTPUT); changeTime[i] = millis() + random(1000, 200); pinState[i] = LOW; } setFlashTime(); }
void loop() { for(int i = 0; i < numberOfLights; i++) { if(changeTime[i] <= millis()) { pinState[i] = ~pinState[i]; digitalWrite(pins[i], pinState[i]); changeTime[i] = millis() + flashRate[i]; } } if(flashChange <= millis()) setFlashTime(); }
void setFlashTime(){ for(int i=0; i<numberOfLights; i++){ flashRate[i] = random(200, 1500); } flashChange = millis() + 100000; // next time to change pattern }
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #4 on: April 28, 2012, 10:20:25 pm » |
I got it to work. I moved the tlc.update(); command to after all the outputs are set. How this fixed it, i dont know. But it did
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25522
Solder is electric glue
|
 |
« Reply #5 on: April 28, 2012, 10:23:26 pm » |
I moved the tlc.update(); command to after all the outputs are set. Well the update command shifts the memory in the processor into the TLC chip. There is little point in doing this before you set the bits. The set bits just do that, set bits in the processor's memory that will be used to shift out to the TLC chip.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #6 on: April 28, 2012, 10:27:03 pm » |
I knew what the command did, i just dont see how this minor modification fixed such a major issue
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25522
Solder is electric glue
|
 |
« Reply #7 on: April 28, 2012, 10:30:13 pm » |
i just dont see how this minor modification fixed such a major issue Because your update was being done after each setting of the bit. The update involves a lot of processor work and adds a considerable delay. By only doing it once all the bits were set it was a lot more efficient.
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #8 on: April 28, 2012, 10:34:09 pm » |
Well I only have 3 chips at the moment, but I have 9 more coming. Should it work with all 12?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #9 on: April 29, 2012, 05:52:11 pm » |
Ok, I have a sketch working with an RGB strip. You send serial commands to it to change parameters. You send 15 bits via serial, every 3 control one parameter. The first set of 3 control red, second set is green, third is blue, fourth is dimmer(dims whole strip), and fifth is strobe speed. So 255255255255255 is 100% red, 100%green, 100% blue, 100% dimmer, and slowest strobe rate. 000255000 127000 is 0% red, 100%green, 0% blue, 50% dimmer, and no strobe. Here is the code: #include <Tlc5940.h>
/* Blink Multiple LEDs without Delay * * Turns on and off several light emitting diode(LED) connected to a digital * pin, without using the delay() function. This means that other code * can run at the same time without being interrupted by the LED code. */ const int NUMCHANNELS = 5; byte pin[NUMCHANNELS/5] = {37}; byte state[NUMCHANNELS/5] = {0}; unsigned int RedVal[NUMCHANNELS/5] = {0}; unsigned int GreenVal[NUMCHANNELS/5] = {0}; unsigned int BlueVal[NUMCHANNELS/5] = {0}; unsigned int Value[NUMCHANNELS] = {0,0,0,0,0}; unsigned long time[NUMCHANNELS/5];
void setup() { Serial.begin(115200); Serial.println('Initializing...'); Tlc.init(); Serial.println('Ready'); }
void loop() { if (Serial.available() == (NUMCHANNELS * 3)) { for (int i=0; i < NUMCHANNELS; ++i){ Value[i] = (Serial.read() - '0') * 100; Value[i] = Value[i] + (Serial.read() - '0') * 10; Value[i] = Value[i] + (Serial.read() - '0'); }} for (int i=0; i<NUMCHANNELS/5; ++i){ RedVal[i] = Value[0] * Value[3] / 255; GreenVal[i] = Value[1] * Value[3] / 255; BlueVal[i] = Value[2] * Value[3] / 255; }
if (Value[4] > 0){ unsigned long m = millis();
for (int i=0; i<(NUMCHANNELS/5); ++i){ if (state[i] == 1){ if (m - time[i] > 15) { time[i] = m; state[i] = 0; Tlc.set(pin[i], 0); Tlc.set(pin[i] + 1, 0); Tlc.set(pin[i] + 2, 0);
}} else{ if (m - time[i] > Value[4] - 15) { time[i] = m; state[i] = 1; Tlc.set(pin[i], map(RedVal[i], 0,255,0,4095)); Tlc.set(pin[i] + 1, map(GreenVal[i], 0,255,0,4095)); Tlc.set(pin[i] + 2, map(BlueVal[i], 0,255,0,4095)); } } } Tlc.update(); } else{ for (int i=0; i<NUMCHANNELS/5; ++i){ Tlc.set(pin[i], (map(RedVal[i], 0,255,0,4095))); Tlc.set(pin[i] + 1, (map(GreenVal[i], 0,255,0,4095))); Tlc.set(pin[i] + 2, (map(BlueVal[i], 0,255,0,4095))); } Tlc.update(); }
}
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #10 on: April 30, 2012, 05:20:31 pm » |
So I tried to make this modular where you can add more rgb leds, and it doesnt work past 4 LED's.I added a function that returns the sent value as a debug tool, and past 4 LED's I don't receive it. Is there a limitation I'm missing or something? #include <Tlc5940.h>
/* Blink Multiple LEDs without Delay * * Turns on and off several light emitting diode(LED) connected to a digital * pin, without using the delay() function. This means that other code * can run at the same time without being interrupted by the LED code. */
const int NUMRGBLEDS = 5; //number of rgb leds const int pin[NUMRGBLEDS] = {0,3,6,9,12}; // first tlc5940 pin of every rgb led const int NUMCHANNELS = 25; //# of rgb led's times 5
byte state[NUMRGBLEDS]; // Leave this alone unsigned int RedVal[NUMRGBLEDS]; // Leave this alone unsigned int GreenVal[NUMRGBLEDS]; // Leave this alone unsigned int BlueVal[NUMRGBLEDS]; // Leave this alone unsigned int Value[NUMCHANNELS]; // Leave this alone unsigned long time[NUMRGBLEDS]; // Leave this alone
void setup() { Serial.begin(115200); Serial.println("Initializing..."); Tlc.init(); Serial.println("Ready"); }
void loop() { if (Serial.available() == (NUMCHANNELS * 3)) { for (unsigned int i=0; i < NUMCHANNELS; ++i){ Value[i] = (Serial.read() - '0') * 100; Value[i] = Value[i] + (Serial.read() - '0') * 10; Value[i] = Value[i] + (Serial.read() - '0'); } Serial.print("You Sent: "); for (unsigned int i=0; i < NUMCHANNELS; ++i){ Serial.print(Value[i] , DEC); Serial.print("-");
} Serial.println(); } for (unsigned int i=0; i<NUMRGBLEDS; ++i){ RedVal[i] = Value[i*5] * Value[i*5 + 3] / 255; GreenVal[i] = Value[(i*5) + 1] * Value[(i*5) + 3] / 255; BlueVal[i] = Value[(i*5) + 2] * Value[(i*5) + 3] / 255; }
for (unsigned int i=0; i<NUMRGBLEDS; ++i){ if (Value[((i*5)+4)] > 0){ unsigned long m = millis(); if (state[i] == 1){ if (m - time[i] > 15) { time[i] = m; state[i] = 0; Tlc.set(pin[i], 0); Tlc.set(pin[i] + 1, 0); Tlc.set(pin[i] + 2, 0);
}} else{ if (m - time[i] > (Value[((i*5)+4)] * 8) - 15) { time[i] = m; state[i] = 1; Tlc.set(pin[i], map(RedVal[i], 0,255,0,4095)); Tlc.set(pin[i] + 1, map(GreenVal[i], 0,255,0,4095)); Tlc.set(pin[i] + 2, map(BlueVal[i], 0,255,0,4095)); } } } else{ for (unsigned int i=0; i<NUMRGBLEDS; ++i){ Tlc.set(pin[i], (map(RedVal[i], 0,255,0,4095))); Tlc.set(pin[i] + 1, (map(GreenVal[i], 0,255,0,4095))); Tlc.set(pin[i] + 2, (map(BlueVal[i], 0,255,0,4095))); } } Tlc.update(); } }
|
|
|
|
« Last Edit: April 30, 2012, 05:41:28 pm by ematson5897 »
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #11 on: May 03, 2012, 05:24:32 pm » |
Does anyone know why the code posted above only works with 4 or less rgb LEDs?
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25522
Solder is electric glue
|
 |
« Reply #12 on: May 03, 2012, 05:27:39 pm » |
Can you define "doesn't work", do the other three LEDs work and the fourth no or does nothing do anything or what?
|
|
|
|
|
Logged
|
|
|
|
|
Offline
Full Member
Karma: 0
Posts: 189
|
 |
« Reply #13 on: May 03, 2012, 05:29:49 pm » |
Well Basicly it works with 4, but If I add 5 or more the LED's stay off when I send a serial command. The arduino also should echo the command back to me, and that doesnt happen either when I have 5 or more
|
|
|
|
|
Logged
|
|
|
|
|
Manchester (England England)
Offline
Brattain Member
Karma: 277
Posts: 25522
Solder is electric glue
|
 |
« Reply #14 on: May 03, 2012, 05:37:09 pm » |
So do you have two TLC9540s? Do you not have to alter a number in the library to tell it how many chips you have. It looks like the Tlc.set() function is thinking it has only one chip and has only allocated an array for that many. They you go and write past the end of the array, screwing up some other variable.
|
|
|
|
|
Logged
|
|
|
|
|
|