Blink without delay and LED pattern

Hey all,

Following some research i came across "blink without delay" using millis to prevent my entire code to freeze during the "delay" function. I was able to find an amazing tutorial to optimize the code using functions and class to have a clean code and it works just fine: A classy solution | Multi-tasking the Arduino - Part 1 | Adafruit Learning System

However I want to create specific patterns: for example have one led blink then turn it off, then have a 2nd led blink, and so on, could anyone tell me how to achieve this code using the blink without delay code from the tutorial ?

 digitalWrite(2, HIGH);  
  digitalWrite(3, HIGH);  
     
  delay(300);                      
  digitalWrite(2, LOW);  
  digitalWrite(3, LOW);  
 
  delay(120);   


  
  digitalWrite(6, HIGH);  
  digitalWrite(7, HIGH);  
  
  delay(300);                      
  digitalWrite(6, LOW);  
  digitalWrite(7, LOW);  
   
  delay(120);

Thanks.

If you put the required periods in an array then you can let loop() run freely using millis() for timing and read the periods from the array.

Here is an example that uses this principle to independently blink 4 LEDs each with different ON/OFF periods. Note that each LEDs ON/OFF periods do not have to be equal either.

const byte ledPins[] = {3,5,6,9};
const byte NUMBER_OF_LEDS = sizeof(ledPins);
unsigned long startTimes[NUMBER_OF_LEDS] = {};
byte indexes[NUMBER_OF_LEDS] = {0};
const byte MAX_NUMBER_OF_PERIODS = 10;
unsigned long periods[][MAX_NUMBER_OF_PERIODS] =    //periods for each LED.  zero indicates end of sequence
{
  {1000, 2000, 1500, 2500, 0},  //ON/OFF/ON/OFF periods for LED 0
  {500, 200, 1000, 2000, 3000, 4000, 0},  //same for LED 1
  {400, 1000, 1500, 2000, 0},
  {1100, 2200, 0}
};

void setup()
{
  Serial.begin(115200);
  for (int led = 0; led < NUMBER_OF_LEDS; led++)
  {
    pinMode(ledPins[led], OUTPUT);
  }
}

void loop()
{
  unsigned long currentTime = millis();
  for (int led = 0; led < NUMBER_OF_LEDS; led++)  //iterate through the LEDs
  {
    if (currentTime - startTimes[led] >= periods[led][indexes[led]])  //? time to change ?
    {
      digitalWrite(ledPins[led], !digitalRead(ledPins[led]));  //flip led state
      startTimes[led] = currentTime;  //save start time of state
      indexes[led]++;                    //increment index
    }
    if (periods[led][indexes[led]] == 0)  //if next period is zero (end of sequence)
    {
      indexes[led] = 0;        //reset period index for this LED
    }
  }  //end for loop
}

The code does more than you asked (4 independent LEDs) but illustrates the principle of storing the periods in an array.

UKHeliBob:
If you put the required periods in an array then you can let loop() run freely using millis() for timing and read the periods from the array.

The code does more than you asked (4 independent LEDs) but illustrates the principle of storing the periods in an array.

Thank you very much for your reply !
I still have a few questions based off your code: I said I was using 2 leds to make my problem easier to understand but I'm actually using about 10 LEDS: 4 are blue and 6 are yellow, the idea is to reproduce an ambulance lightbar which uses different pattern.

My questions:
1)I will be handling the different patterns in a SWITCH condition: is it possible to change the period stored in an array for each LED in said SWITCH ?
for instance:

switch(mypattern)
{
case "1":
{1000, 2000, 1500, 2500, 0},  //ON/OFF/ON/OFF periods for LED 0
  {500, 200, 1000, 2000, 3000, 4000, 0},  //same for LED 1
  {400, 1000, 1500, 2000, 0},
  {1100, 2200, 0}
break;

case "2":
{100, 200, 150, 250, 0},  //ON/OFF/ON/OFF periods for LED 0
  {50, 20, 10, 20, 30, 40, 0},  //same for LED 1
  {4, 1, 1, 2, 0},
  {1100, 2200, 0}
break;
}
  1. Blue and orange LEDS will have different and independent patterns (orange is used for traffic advisor and blue for emergency lighting), My current idea is to rename all variable have your code for the blue LEDS then make a copy of the code but rename the variable for the orange LEDs, while it would work, there would be cleaner way to make this ?

I'm a newbie when it comes to programming, I know the basics: conditions, variable, but when it comes to array and code optimization i'm still at my early stages to learn everything, so sorry for the dumb questions.

yours.

My example code was something I wrote in answer to a question here at some time. Now that you have expanded the requirement to say 10 LEDs the multi LED code could be useful.

If you expand the number of rows in the periods array to match the number of LEDs you can control the periods of each LED independently. There is no need to change the periods in the array on the fly and in any case you can't do it the way that you indicate. A better way would be to use a different array for each pattern or to introduce third dimension into the array but I suggest that you don't do this. Also, don't forget that if multiple LEDs are turning ON/OFF at the same time then they don't need their own row in the array as you can turn more than one LED ON/OFF at the end of a timing period

Perhaps it would be better if you described exactly how many LEDs you have, what colour they are and the sequence and timing of their ON/OFF periods. However you write the program you are going to need this information.