Issue with running two timers on one led strip.

So I've been learning arduino on the fly (mostly thanks to you guys!) and I've been working on a little led strip timer. Basically it needs to turn off 1 led in the array every 1 minute. But because it is supposed to be like a fire going out, I thought it would be cool to have the leds flicker (blink) like a flame does. So I learned about using millis() instead of delay and got the leds to flicker. I was super excited and after awhile managed to set up another timer in the same loop to turn off one led every minute. But that's where I'm stumped. It is turning off every light in both arrays instead of one light at a time per loop.

So basically I want: Ten leds on the strip to flicker (blink quickly), then one of those ten to turn off every time a minute passes, until ten mins is up. Then I figure I'd end with some leds turning red to show the timer has ended, but I haven't gotten that far, as I've been stumped on the 2nd step for hours.

Is what I'm trying to do possible? I know I could just write out each led with its own 1 minute timer, but that would be pretty huge, and you guys always talk about how if you're repeating the same code over and over you're doing something wrong.

Here's the code, any help is really appreciated. Thanks!

#include <FastLED.h>
#define NUM_LEDS 50
#define DATA_PIN 6
#define BRIGHTNESS 10
#define COLOR_ORDER RGB
CRGB leds[NUM_LEDS];

int color;

int flicker1[] ={2, 8, 17, 20, 26};

int flicker2[] ={5, 11, 14, 23, 29};

void setup() { 

  delay(2000);

   FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);

}

void loop()
{
  for (int i = 0; i < 5; i++) {
    unsigned long startTime;
   unsigned long interval = 6000;
   static unsigned long lastMillis = 0;
   static bool toggle = false;
   if(millis() - lastMillis > 13UL)
   {
     if(toggle)
     {
       //show colorA
       leds[flicker1[i]] = CRGB(255,50,0);
       leds[flicker2[i]] = CRGB(30,10,0);
     }
     else
     {
       leds[flicker1[i]] = CRGB(30,10,0);
       leds[flicker2[i]] = CRGB(255,50,0);
     }
     if (millis() - startTime >= interval)
  {
       leds[flicker1[i]] = CRGB(0,0,0);
       leds[flicker2[i]] = CRGB(0,0,0);
  }
     toggle = !toggle;
     lastMillis = millis();
     FastLED.show();
     
   }
}

}

probably using if/else if/else statements would work. something like this maybe (not tested):

#include <FastLED.h>
#define NUM_LEDS 50
#define DATA_PIN 6
#define BRIGHTNESS 10
#define COLOR_ORDER RGB
CRGB leds[NUM_LEDS];

int color;

int flicker1[] = {2, 8, 17, 20, 26};

int flicker2[] = {5, 11, 14, 23, 29};

void setup() {

  delay(2000);

  FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);

}

void loop()
{
  for (int i = 0; i < 5; i++) {
    unsigned long startTime;
    unsigned long interval = 6000;
    static unsigned long lastMillis = 0;
    static bool toggle = false;
    if (millis() - lastMillis > 13UL)
    {
      if (millis() - startTime >= interval)
      {
        leds[flicker1[i]] = CRGB(0, 0, 0);
        leds[flicker2[i]] = CRGB(0, 0, 0);
        startTime = millis();
      }
      else if (toggle)
      {
        //show colorA
        leds[flicker1[i]] = CRGB(255, 50, 0);
        leds[flicker2[i]] = CRGB(30, 10, 0);
      }
      else
      {
        leds[flicker1[i]] = CRGB(30, 10, 0);
        leds[flicker2[i]] = CRGB(255, 50, 0);
      }

      toggle = !toggle;
      lastMillis = millis();
      FastLED.show();

    }
  }

}

hope that helps

sherzaad:
probably using if/else if/else statements would work. something like this maybe (not tested):

#include <FastLED.h>

#define NUM_LEDS 50
#define DATA_PIN 6
#define BRIGHTNESS 10
#define COLOR_ORDER RGB
CRGB leds[NUM_LEDS];

int color;

int flicker1[] = {2, 8, 17, 20, 26};

int flicker2[] = {5, 11, 14, 23, 29};

void setup() {

delay(2000);

FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);

}

void loop()
{
  for (int i = 0; i < 5; i++) {
    unsigned long startTime;
    unsigned long interval = 6000;
    static unsigned long lastMillis = 0;
    static bool toggle = false;
    if (millis() - lastMillis > 13UL)
    {
      if (millis() - startTime >= interval)
      {
        leds[flicker1[i]] = CRGB(0, 0, 0);
        leds[flicker2[i]] = CRGB(0, 0, 0);
        startTime = millis();
      }
      else if (toggle)
      {
        //show colorA
        leds[flicker1[i]] = CRGB(255, 50, 0);
        leds[flicker2[i]] = CRGB(30, 10, 0);
      }
      else
      {
        leds[flicker1[i]] = CRGB(30, 10, 0);
        leds[flicker2[i]] = CRGB(255, 50, 0);
      }

toggle = !toggle;
      lastMillis = millis();
      FastLED.show();

}
  }

}




hope that helps

Hmm. I tried your code and it seems the off timer isn't functioning. They're all flickering but no count down. Thanks for the attempt though! Any other ideas?

Despereaux:
Hmm. I tried your code and it seems the off timer isn't functioning. They're all flickering but no count down. Thanks for the attempt though! Any other ideas?

Hmm ok.... if possible would you make a timing diagram or table illustrating the sequence you would like to execute please? I'm having trouble understand the sequence you described in your OP

another thought I had is that it probably be better if you move this from the "for" loop to the "main" loop:
unsigned long startTime=millis();
unsigned long interval = 6000;
static unsigned long lastMillis = millis();
static bool toggle = false;

sherzaad:
Hmm ok.... if possible would you make a timing diagram or table illustrating the sequence you would like to execute please? I'm having trouble understand the sequence you described in your OP

another thought I had is that it probably be better if you move this from the "for" loop to the "main" loop:
unsigned long startTime=millis();
unsigned long interval = 6000;
static unsigned long lastMillis = millis();
static bool toggle = false;

Here is a little gif I made showing what should happen. I lowered the timers and number of leds for the example, but hopefully it explains what I'm trying to do. Thanks so much!

Despereaux:
Here is a little gif I made showing what should happen. I lowered the timers and number of leds for the example, but hopefully it explains what I'm trying to do. Thanks so much!

may be something like this then (not tested):

#include <FastLED.h>
#define NUM_LEDS 50
#define DATA_PIN 6
#define BRIGHTNESS 10
#define COLOR_ORDER RGB
CRGB leds[NUM_LEDS];

int color;

int flicker1[] = {2, 8, 17, 20, 26};

int flicker2[] = {5, 11, 14, 23, 29};

unsigned long startTime = millis();
unsigned long interval = 6000;
unsigned long lastMillis = millis();
unit8_t start_num = 0;
bool toggle = false;

void setup() {

  delay(2000);

  FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);

}

void loop()
{
  for (int i = start_num; i < 5; i++) {

    if (millis() - lastMillis > 13UL)
    {
      if (toggle)
      {
        //show colorA
        leds[flicker1[i]] = CRGB(255, 50, 0);
        leds[flicker2[i]] = CRGB(30, 10, 0);
      }
      else
      {
        leds[flicker1[i]] = CRGB(30, 10, 0);
        leds[flicker2[i]] = CRGB(255, 50, 0);
      }
      toggle = !toggle;
      lastMillis = millis();
      FastLED.show();

    }
  }

  if (start_num < 5 && millis() - startTime >= interval)
  {
    leds[flicker1[start_num]] = CRGB(0, 0, 0);
    leds[flicker2[start_num]] = CRGB(0, 0, 0);
    startTime = millis();
    FastLED.show();
    ++start_num;
  }

}

sherzaad:
may be something like this then (not tested):

#include <FastLED.h>

#define NUM_LEDS 50
#define DATA_PIN 6
#define BRIGHTNESS 10
#define COLOR_ORDER RGB
CRGB leds[NUM_LEDS];

int color;

int flicker1[] = {2, 8, 17, 20, 26};

int flicker2[] = {5, 11, 14, 23, 29};

unsigned long startTime = millis();
unsigned long interval = 6000;
unsigned long lastMillis = millis();
unit8_t start_num = 0;
bool toggle = false;

void setup() {

delay(2000);

FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);

}

void loop()
{
  for (int i = start_num; i < 5; i++) {

if (millis() - lastMillis > 13UL)
    {
      if (toggle)
      {
        //show colorA
        leds[flicker1[i]] = CRGB(255, 50, 0);
        leds[flicker2[i]] = CRGB(30, 10, 0);
      }
      else
      {
        leds[flicker1[i]] = CRGB(30, 10, 0);
        leds[flicker2[i]] = CRGB(255, 50, 0);
      }
      toggle = !toggle;
      lastMillis = millis();
      FastLED.show();

}
  }

if (start_num < 5 && millis() - startTime >= interval)
  {
    leds[flicker1[start_num]] = CRGB(0, 0, 0);
    leds[flicker2[start_num]] = CRGB(0, 0, 0);
    startTime = millis();
    FastLED.show();
    ++start_num;
  }

}

Wow! You're brilliant. That worked. The only issue is that as the lights turn off, the blinking gets so fast you can't even see it. I guess that's because it has fewer lights to count through and so the speed increases? Anyway, if you don't want to bother with that it's fine, you've been a huge help as is!

Despereaux:
Wow! You're brilliant. That worked. The only issue is that as the lights turn off, the blinking gets so fast you can't even see it. I guess that's because it has fewer lights to count through and so the speed increases? Anyway, if you don't want to bother with that it's fine, you've been a huge help as is!

Third time lucky (I hope!) :wink:

#include <FastLED.h>
#define NUM_LEDS 50
#define DATA_PIN 6
#define BRIGHTNESS 10
#define COLOR_ORDER RGB
CRGB leds[NUM_LEDS];

int flicker1[] = {2, 8, 17, 20, 26};
int flicker2[] = {5, 11, 14, 23, 29};
int arr_size = 5; //size of your flicker arrays
int flicker_rate = 200; //<------------- use this variable to change the flash rate
int start_num = 0;
unsigned long startTime = millis();
unsigned long interval = 6000;
unsigned long lastMillis = millis();
int color;
bool toggle = false;

void setup() {

  delay(2000);

  FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);

}

void loop()
{
  if (start_num < arr_size && millis() - lastMillis >= flicker_rate)
  {
    if (toggle)
    {
      //show colorA
      leds[flicker1[start_num + i]] = CRGB(255, 50, 0);
      leds[flicker2[start_num + i]] = CRGB(30, 10, 0);
    }
    else
    {
      leds[flicker1[start_num + i]] = CRGB(30, 10, 0);
      leds[flicker2[start_num + i]] = CRGB(255, 50, 0);
    }

    i= (i+1)%(arr_size-start_num);
    toggle = !toggle;
    lastMillis = millis();
    FastLED.show();


  }

  if (start_num < arr_size && millis() - startTime >= interval)
  {
    leds[flicker1[start_num]] = CRGB(0, 0, 0);
    leds[flicker2[start_num]] = CRGB(0, 0, 0);
    startTime = millis();
    FastLED.show();
    ++start_num;
  }

}

sherzaad:
Third time lucky (I hope!) :wink:

#include <FastLED.h>

#define NUM_LEDS 50
#define DATA_PIN 6
#define BRIGHTNESS 10
#define COLOR_ORDER RGB
CRGB leds[NUM_LEDS];

int flicker1[] = {2, 8, 17, 20, 26};
int flicker2[] = {5, 11, 14, 23, 29};
int arr_size = 5; //size of your flicker arrays
int flicker_rate = 200; //<------------- use this variable to change the flash rate
int start_num = 0;
unsigned long startTime = millis();
unsigned long interval = 6000;
unsigned long lastMillis = millis();
int color;
bool toggle = false;

void setup() {

delay(2000);

FastLED.addLeds<WS2811, DATA_PIN, RGB>(leds, NUM_LEDS);

}

void loop()
{
 if (start_num < arr_size && millis() - lastMillis >= flicker_rate)
 {
   if (toggle)
   {
     //show colorA
     leds[flicker1[start_num + i]] = CRGB(255, 50, 0);
     leds[flicker2[start_num + i]] = CRGB(30, 10, 0);
   }
   else
   {
     leds[flicker1[start_num + i]] = CRGB(30, 10, 0);
     leds[flicker2[start_num + i]] = CRGB(255, 50, 0);
   }

i= (i+1)%(arr_size-start_num);
   toggle = !toggle;
   lastMillis = millis();
   FastLED.show();

}

if (start_num < arr_size && millis() - startTime >= interval)
 {
   leds[flicker1[start_num]] = CRGB(0, 0, 0);
   leds[flicker2[start_num]] = CRGB(0, 0, 0);
   startTime = millis();
   FastLED.show();
   ++start_num;
 }

}

Hmm, that one went a bit wonky. It seems to freeze for 6 seconds after every other light is turned off, and the blinking speed still changes depending upon how many lights are left on.

If I do this, all the lights blink at the same speed, no matter how many are on:

void loop()
{
if (millis() - lastMillis > 80UL)
    {
      if (toggle)
      {
        //show colorA
  leds[0] = CRGB(255,50,0);  
  leds[3] = CRGB(255,50,0); 
  leds[6] = CRGB(255,50,0);
  
         
      }
      else
      {
  leds[0] = CRGB(30,50,0);  
  leds[3] = CRGB(30,50,0); 
  leds[6] = CRGB(30,50,0);

        
      }
      
      toggle = !toggle;
      lastMillis = millis();
     FastLED.show();

    }


}

But for some reason, once we use an array like we have been, it seems to count one by one, so the blinking becomes faster as each light shuts off. Is there a way to combine these two ideas? Like, to have it effect all the lights at once, so the blink rate is predictable no matter how many lights are on? Then we could randomize the blink rate ourselves?

I'm sorry if that doesn't make sense. And if I'm wasting your time, like I said, you've been a huge help already, so don't feel bad about walking away. Thanks!