Help With Milli() Timing Code

I'm trying to use the blink without delay example in my code. Reading through the example I thought I understood how it worked but cannot apply it (so maybe not!). I wanted to change colors of an LED at a specific time while moving a servo arm so I cannot use the delay() command. I know the code to turn my Led's on works, but cannot get it to work with my current code. Below is a function I'm trying to get it to work with. Any advice appreciated.

void Scene_14()                                  //The name of my function
{
  
  unsigned long previousMillis = 0;  
  unsigned long currentMillis = millis();
  const long interval = 9200;                         //I want to LED's to turn on after 9200 mS
  

   if(currentMillis - previousMillis >= interval) {  //This is the part that's not working
    // save the last time you blinked the LED 
    previousMillis = currentMillis;   

    for (int i = 0; i < NUM_LEDS; ++i)         //This turns the LED's 0 to 14 on
    {
      leds[i] = CRGB::Red;                     
    }
    FastLED.show();                    
   }
   
  delay(2700);
  
  FastLED.clear ();                                     //TURN LED's off
  FastLED.show();
  
  
  delay(1000);  
  SWITCH_SLOW();                                //This function moves a servo
  
  delay(12000);
  
  FastLED.clear ();                               //TURN LED's off
  FastLED.show();
 
}

You need to give a better description of what goes wrong. What do you expect it to do? And what does it do.

You still have delays; they will seriously interfere with the millis() based timing :wink: When you call Scene_14 again, those 9200 ms are long gone.

The main problem currently is that previousMillis is not a static variable and hence every time that you enter Scene_14, it's value is set to 0. Change unsigned long previousMillis = 0; to static unsigned long previousMillis = 0; for starters

If I understand the code correctly, you want the leds to be on after 9200 ms for a duration of 2700 ms? If so, I suggest that you keep a variable that holds the state of the leds. You also need to change the interval variable so it's not a const but a static variable.

The first part of your code

void Scene_14()                                  //The name of my function
{
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();

  // remember the interval
  // initial value 9200 ms
  static unsigned long interval = 9200;                         //I want to LED's to turn on after 9200 mS

  // keep track of the state of the leds
  // initial value false so first time a timeout occurs leds will be switched on
  static bool fLedOn = false;

  if (currentMillis - previousMillis >= interval)   //This is the part that's not working
  {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if leds are off
    if (fLedOn == false)
    {
      for (int i = 0; i < NUM_LEDS; ++i)         //This turns the LED's 0 to 14 on
      {
        leds[i] = CRGB::Red;
      }
      FastLED.show();
      // indicate leds are on
      fLedOn = true;
      // set ON duration
      interval = 2700;
    }
    // if leds are on
    else
    {
      FastLED.clear ();                                     //TURN LED's off
      FastLED.show();
      // indicate leds are off
      fLedOn = false;
      // set OFF duration
      interval = 9200;
    }
  }

  // other stuff here
  ...
  ...
}

Test this without the other stuff tiill you are confident that it works. Next I suggest that you place the blink part in a separate function, e.g. led_14 and call that from Scene_14.

/*
  non-blocking blink 14 leds
*/
void led_14()
{
  static unsigned long previousMillis = 0;
  unsigned long currentMillis = millis();

  // remember the interval
  // initial value 9200 ms
  static unsigned long interval = 9200;                         //I want to LED's to turn on after 9200 mS

  // keep track of the state of the leds
  // initial value false so first time a timeout occurs leds will be switched on
  static bool fLedOn = false;

  if (currentMillis - previousMillis >= interval)   //This is the part that's not working
  {
    // save the last time you blinked the LED
    previousMillis = currentMillis;

    // if leds are off
    if (fLedOn == false)
    {
      for (int i = 0; i < NUM_LEDS; ++i)         //This turns the LED's 0 to 14 on
      {
        leds[i] = CRGB::Red;
      }
      FastLED.show();
      // indicate leds are on
      fLedOn = true;
      // set ON duration
      interval = 2700;
    }
    // if leds are on
    else
    {
      FastLED.clear ();                                     //TURN LED's off
      FastLED.show();
      // indicate leds are off
      fLedOn = false;
      // set OFF duration
      interval = 9200;
    }
  }
}

Your Scene_14 could now look like

void Scene_14()
{
  // blink the leds
  led_14();
  // run the servo
  servo_14();
}

I hope this gets you on track.

PS: I'm not familiar with the FastLed library so had to base that part on what you gave.

The demo Several Things at a Time is an extended example of BWoD and may help with understanding the technique.

...R