Strobe

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

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();
   }
   
}

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();
   }
   }
   
}

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
}

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

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.

I knew what the command did, i just dont see how this minor modification fixed such a major issue

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.

Well I only have 3 chips at the moment, but I have 9 more coming. Should it work with all 12?

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();
 
   } 

 
 
 }

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();
   }
  
 
   }

Does anyone know why the code posted above only works with 4 or less rgb LEDs?

Can you define "doesn't work", do the other three LEDs work and the fourth no or does nothing do anything or what?

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

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.

No I have it set to 3, the number of chips I have. And even if that was wrong and it was still set to 1 chip shouldnt I still be able to get to 5 rgb Leds since 5*3 = 15 and that is still less than the chips 16 outputs? How many bits can serial send at a time?

How many bits can serial send at a time?

The serial port sends one byte at a time, do you mean that? Is your power supply up to the current? Have you got good decoupling on each chip. What happens if you remove the first LED and have the last one on. Does it still fall over?

So the text box can hold any amount and there isnt any limiting factor in the serial? Yes they are decoupled, Yes I can set it to any pins I want as long as I dont use more than 4

I think it is time to put some debug output in the code to see if the values are being set like you think they are.

Ok, I will try that and post results