LED blink patterns with multiple LEDs with millis() not using Delay()

I want to make LED blink patterns with multiple LEDs with millis() function. I researched about it but not get any perfect solution. I found one blog the blog link but it is using LED pin number's array. I need without array. any help will be appreciated. it's urgent.

This is my code which i have write.

    const int Button_code_1 = 2;
    const int Button_code_2 = 3;
    const int Button_code_stop = 4;
    
    const int LED_one = 6;
    const int LED_two = 8;
    const int LED_three = 10;
    const int LED_four = 12;
    
    int buttonState_code_1 = 0;
    int buttonState_code_2 = 0;
    int buttonState_code_stop = 0;
    
    void setup() {
      // put your setup code here, to run once:
    
      Serial.begin(9600);
    
      pinMode(Button_code_1,INPUT);
      pinMode(Button_code_2,INPUT);
      pinMode(Button_code_stop,INPUT);
    
      pinMode(LED_Button_one,INPUT);
      pinMode(LED_Button_two,INPUT);
      pinMode(LED_Button_three,INPUT);
      pinMode(LED_Button_four,INPUT);
      
      pinMode(LED_one, OUTPUT);
      pinMode(LED_two, OUTPUT);
      pinMode(LED_three, OUTPUT);
      pinMode(LED_four, OUTPUT);
    }
    
    void loop() {
      // put your main code here, to run repeatedly:
    
      buttonState_code_1 = digitalRead(Button_code_1);
      Serial.println(buttonState_code_1);
      buttonState_code_2 = digitalRead(Button_code_2);
      Serial.println(buttonState_code_2);
      delay(1000);
      buttonState_code_stop = digitalRead(Button_code_stop);
      
      if(buttonState_code_1==1)
      {
        pattern_one();
      }
      if(buttonState_code_2==1)
      {
        pattern_two();
      }
    
    }
    
    void pattern_one()
    {
      digitalWrite(LED_one, LOW);
      digitalWrite(LED_two, HIGH);
      digitalWrite(LED_three, LOW);
      digitalWrite(LED_four, LOW);
      delay(3000);
      digitalWrite(LED_one, LOW);
      digitalWrite(LED_two, LOW);
      digitalWrite(LED_three, LOW);
      digitalWrite(LED_four, HIGH);
      delay(3000);
      digitalWrite(LED_one, HIGH);
      digitalWrite(LED_two, LOW);
      digitalWrite(LED_three, LOW);
      digitalWrite(LED_four, LOW);
      delay(3000);
      digitalWrite(LED_one, LOW);
      digitalWrite(LED_two, LOW);
      digitalWrite(LED_three, HIGH);
      digitalWrite(LED_four, LOW);
      delay(3000);
    }
    
    void pattern_two()
    {
      digitalWrite(LED_one, HIGH);
      digitalWrite(LED_two, LOW);
      digitalWrite(LED_three, LOW);
      digitalWrite(LED_four, LOW);
      delay(3000);
      digitalWrite(LED_one, LOW);
      digitalWrite(LED_two, LOW);
      digitalWrite(LED_three, HIGH);
      digitalWrite(LED_four, LOW);
      delay(3000);
      digitalWrite(LED_one, LOW);
      digitalWrite(LED_two, HIGH);
      digitalWrite(LED_three, LOW);
      digitalWrite(LED_four, LOW);
      delay(3000);
      digitalWrite(LED_one, LOW);
      digitalWrite(LED_two, LOW);
      digitalWrite(LED_three, LOW);
      digitalWrite(LED_four, HIGH);
      delay(3000);
    }

This is my sample code with four LEDs.I have written this code with delay. so when I want to change the pattern so pattern cannot change because of delay is blocking the code. I research about it and find the millis function as the solution. but how can I implement this code using millis function.

We'll get right on it.

In my book, the solution using an array would be the perfect one. (Though I'd use a constant array)

Just remove the array and for loops.

It :

for (int x=0; x < 6; x++)
		pinMode(LEDpins[x], OUTPUT);

Could be:

  pinMode(ledPin0, OUTPUT);
  pinMode(ledPin1, OUTPUT);
  pinMode(ledPin2, OUTPUT);
  pinMode(ledPin3, OUTPUT);
  pinMode(ledPin4, OUTPUT);
  pinMode(ledPin5, OUTPUT);

why?

Hello devliya
Post your sketch, well formated, with comments and in so called code tags "</>" and a none-Fritzing schematic to see how we can help.
Have a nice day and enjoy programming in C++ and learning.

I have 9 LEDs and i need to blink one after another with delay of 3s and i have 2 different blink patterns and two buttons to select the pattern and one button to stop the program. so for using different patterns i want that it should not be array otherwise if i will get more patterns then i should take more array one for each pattern.Hope it clears the query.

i have 9 LEDs and i need to blink one after another with delay of 3s and i have 2 different blink patterns and two buttons to select the pattern and one button to stop the program. so for using different patterns i want that it should not be array otherwise if i will get more patterns then i should take more array one for each pattern.Hope it clears the query.

No.
Not really. Not even when you repeated it.

But good luck.

1 Like

No cigar :slight_smile:

an array is just a way to store multiple variables of the same type together. nothing prevents you from using ledPin[0] where you want to use the first one or ledPin[1] when you want to use the second one. declare them as const and the optimiser will get rid of the array and replace the values directly in the code.

you could create also 9 constants like suggested in post 4 but it will just make your life more difficult for a number of operations (like setting them all as output)

I have post my sketch in question.

1 Like

Hello
In this case I´m out.

create an array of structures. The structure will hold the PIN number, the state of the LED, the last time it was flipped and the half period when you need to flip it and possibly more information if there are more patterns to remember

Have any example ?

something like this would be a blink without delay but with multiple LEDs and different half periods

struct {
  const byte ledPin;
  const unsigned long halfPeriod;
  unsigned long lastFlip;
  byte state;
}
myLeds[] = {
  {2, 1000, 0,  LOW},
  {3, 2000, 0, HIGH},
  {4,  500, 0, HIGH},
};


void setup() {
  for (auto& l : myLeds) {
    pinMode(l.ledPin, OUTPUT);
    digitalWrite(l.ledPin, l.state);
    l.lastFlip = millis();
  }
}

void loop() {
  for (auto& l : myLeds) {
    if (millis() - l.lastFlip >= l.halfPeriod) {
      // time to flip
      l.state = (l.state == HIGH) ? LOW : HIGH; // remember the new state
      digitalWrite(l.ledPin, l.state);            // set the new state
      l.lastFlip = millis();                      // remember when we did it
    }
  }
}

typed here, so totally untested

that fits perfect in arrays.
If you need to blink up to 9 LEDs in any specific pattern, use a two byte variable and mark each LED which should be on.

based on your first pattern (with 4 LEDs) ... this pattern array could look like:

const uint16_t pattern[] {
//  FEDCBA9876543210    // the LED pattern to be displayed, each bit defines one LED state, "paint" your pattern/sequence
  0b0000000000000010,   
  0b0000000000001000,  
  0b0000000000000001,
  0b0000000000000100,
}

so why do you not want to use arrays?

b)
how have you wired the "buttons"? have you used external pull down resistors?
please show a schematic of your circuit.

c)
what kind of "buttons" have you used? momentary buttons which release the contact if you release the finger from the button, or switches which hold contact until next press?

edit:

example how to switch between two different patterns (or switch it of) by serial:
0 --> OFF
a --> pattern A
b --> pattern B

// Light LEDs in a specific order/pattern
// 2018-09-26 "Thermometer" Style LED Blinking  http://forum.arduino.cc/index.php?topic=570493.msg0#new
// 2018-07-19 Lauflicht in zwei Richtungen rund um den  http://forum.arduino.cc/index.php?topic=558863.0
// Ähnlich dem Muster von http://forum.arduino.cc/index.php?topic=518131.0
// https://forum.arduino.cc/index.php?topic=711402.0
// 2021-09-20 Multiple led sequence over time https://forum.arduino.cc/t/multiple-led-sequence-over-time/907021/67
// 2022-07-04 more patterns: https://forum.arduino.cc/t/led-blink-patterns-with-multiple-leds-with-millis-not-using-delay/1008941
// by noiasca

/* ***************************
    Configuration/Konfiguraton
 * ************************* */

//                              5432109876543210           // the LED pattern to be displayed, each bit defines one LED state, "paint" your pattern/sequence
const uint16_t patternA[] = { 0b0000000000000010,
                              0b0000000000001000,
                              0b0000000000000001,
                              0b0000000000000100,
                            };

const uint16_t patternB[] = { 0b0000000000000001,
                              0b0000000000000100,
                              0b0000000000000010,
                              0b0000000000001000,
                            };

const uint8_t button_code_A = 2;
const uint8_t button_code_B = 3;
const uint8_t button_code_stop = 4;

const uint8_t ledPin[] = {6, 8, 10, 12};                          // original posters LED pins
//const uint8_t ledPin[] = {13, 6, 5, 9};                             // noiascas LED pins
const uint16_t myIntervall = 1000;

byte state = 0; // 0 off, 'a' pattern A, 'b' pattern B

#define DEBUG_UART 1                                                 // activate debug output on Serial to see the LED pattern 

/* ***************************
    Globals / Variablen für den Sketch
 * ************************* */

uint32_t lastMillis = 0;                                              // last update of the LED pattern
uint8_t  actualIndex = 0;                                           // actual active pattern
const size_t totalNoPins = sizeof(ledPin) / sizeof(ledPin[0]);        // how many pins are defined

/* ***************************
    Setup
 * ************************* */

void setup() {
#if DEBUG_UART
  Serial.begin(115200);
  Serial.println(F("\nTwo LED pattern"));
#endif

  for (uint8_t i = 0; i < totalNoPins; i++) {
    pinMode(ledPin[i], OUTPUT);
  }
}

void patternStop()
{
  for (uint8_t i = 0; i < totalNoPins; i++) {
    digitalWrite(ledPin[i], LOW);
  }
  actualIndex = 0;
  state = 0;
}


void patternRun(const uint16_t pattern[], const size_t totalNoPattern)
{
  if (millis() - lastMillis >= myIntervall)
  {
    for (uint8_t i = 0; i < totalNoPins; i++)
    {
      if (pattern[actualIndex] & (1 << i)) {
#if DEBUG_UART
        Serial.print(F("X"));
#endif
        digitalWrite(ledPin[i], HIGH);
      }
      else {
#if DEBUG_UART
        Serial.print(F(" "));
#endif
        digitalWrite(ledPin[i], LOW);
      }
    }
#if DEBUG_UART
    Serial.print(F(" - "));
    Serial.println(actualIndex);
#endif
    lastMillis = millis();
    actualIndex++;  // increase Sequence for next iteration
    if (actualIndex >= totalNoPattern) actualIndex = 0;
  }
}

void serialRun()
{
  if (Serial.available())
  {
    char c = Serial.read();
    switch (c)
    {
      case '0' : patternStop(); break;
      case 'a' : state = 'a'; break;
      case 'b' : state = 'b'; break;
    }
  }
}

void buttonRun()
{
  // tbd: you haven't discribed your button wiring
  // this is just an example for momentary push buttons, connecting to VCC if pressed, and external pull down resistors to GND 
  //if (digitalRead(button_code_A) == HIGH) state = 'a';
  //if (digitalRead(button_code_B) == HIGH) state = 'b';
  //if (digitalRead(button_code_stop) == HIGH) patternStop();
}

void loop() {
  serialRun();  // read commands from Serial
  buttonRun();  // read Buttons
  // handle according state
  switch (state)
  {
    case 'a' :
      patternRun(patternA, sizeof(patternA) / sizeof(patternA[0])); // call function with reference to the pattern and pattern size
      break;
    case 'b' :
      patternRun(patternB, sizeof(patternB) / sizeof(patternB[0]));
      break;
  }
}
1 Like

@noiasca I have test your code. It's working fine as of my need. but I cannot understand the code. because of I am new to Arduino. so can you please help me to understand the code.

Yes I can.
You should prepare yourself and read some pages about:

usage of millis():
https://werner.rothschopf.net/microcontroller/202109_millis_two_leds_en.htm

a simple bouncing light (KITTs Larson Scanner)
https://werner.rothschopf.net/microcontroller/202109_millis_larson_scanner_en.htm

and finally, how to deal with one pattern:
https://werner.rothschopf.net/microcontroller/202109_millis_led_sequence_en.htm

these 3 pages will lead you to the sketch I've posted in #16.

When you have read the 3 pages, tried the sketches with your hardware and still have a question regarding #16, ask a question.

@noiasca I have sent one mail to you. mail id I have got from your website. for further help or any other help can we connect on mail or can we do conversation on mail ?

please formulate your question here in the forum, not by email. This will ensure others can help you also.

1 Like

@noiasca

This is my working code. I want to add one more thing. That is if any of the pattern is running. then in between if I press the push-button of that particular LED then that LED will turn off and next LED in that pattern will turn on. I tried this code but it's not working as my expectation. There is no effect when I press that particular LED Button.

Here is my code.

const int Button_pattern_1 = 2;
const int Button_pattern_2 = 3;
const int Button_pattern_stop = 4;

const int LED_Button_one = 5;
const int LED_one = 12;

const int LED_Button_two = 6;
const int LED_two = 11;

const int LED_Button_three = 7;
const int LED_three = 10;

const int LED_Button_four = 8;
const int LED_four = 9;

int buttonState_pattern_1 = 0;
int buttonState_pattern_2 = 0;
int buttonState_pattern_stop = 0;

const long Interval = 3000;

byte state = 0;

char ledState_pattern_one = 'A', ledState_pattern_two = 'A';

unsigned long previousMillis_pattern_one = 0, previousMillis_pattern_two = 0;
const long interval = 3000;

void setup() {
  // put your setup code here, to run once:

  Serial.begin(9600);

  pinMode(Button_pattern_1, INPUT);
  pinMode(Button_pattern_2, INPUT);
  pinMode(Button_pattern_stop, INPUT);

  pinMode(LED_Button_one, INPUT);
  pinMode(LED_Button_two, INPUT);
  pinMode(LED_Button_three, INPUT);
  pinMode(LED_Button_four, INPUT);

  pinMode(LED_one, OUTPUT);
  pinMode(LED_two, OUTPUT);
  pinMode(LED_three, OUTPUT);
  pinMode(LED_four, OUTPUT);
}

void loop() {
  // put your main code here, to run repeatedly:

  unsigned long currentMillis = millis();

  buttonState_pattern_1 = digitalRead(Button_pattern_1);
//  Serial.println(buttonState_pattern_1);
  buttonState_pattern_2 = digitalRead(Button_pattern_2);
//  Serial.println(buttonState_pattern_2);
  buttonState_pattern_stop = digitalRead(Button_pattern_stop);
//  Serial.println(buttonState_pattern_stop);

  buttonRun();

  switch (state)
  {
    case 'a':
      Serial.println("Pattern one running");
      pattern_one(currentMillis);
      break;

    case 'b':
      Serial.println("Pattern two running");
      pattern_two(currentMillis);
      break;
  }
}

void buttonRun()
{
  if (digitalRead(Button_pattern_1) == HIGH)
  {
    state = 'a';
  }
  if (digitalRead(Button_pattern_2) == HIGH)
  {
    state = 'b';
  }
  if (digitalRead(Button_pattern_stop) == HIGH)
  {
    Serial.println("Pattern stop");
    patternStop();
    state = 0;
  }
}

void pattern_one(unsigned long currentMillis_pattern)
{
  if (currentMillis_pattern - previousMillis_pattern_one >= interval)
  {
    previousMillis_pattern_one = currentMillis_pattern;
    if (ledState_pattern_one == 'A')
    {
      ledState_pattern_one = 'B';
      if (digitalRead(LED_Button_two) == 1) //Here I have used pull-up resistor that's why i have checked with 1.
      {
//        Serial.print("two");
        Serial.println(digitalRead(LED_Button_two));
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
      else
      {
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
    }

    else if (ledState_pattern_one == 'B')
    {
      ledState_pattern_one = 'C';
      if (digitalRead(LED_Button_four) == 1) //Here I have used pull-up resistor that's why i have checked with 1.
      {
//        Serial.print("four");
        Serial.println(digitalRead(LED_Button_four));
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, LOW);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, HIGH);
      }
      else
      {
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
    }

    else if (ledState_pattern_one == 'C')
    {
      ledState_pattern_one = 'D';
      if (digitalRead(LED_Button_one) == 1) //Here I have used pull-up resistor that's why i have checked with 1.
      {
//        Serial.print("one");
        Serial.println(digitalRead(LED_Button_one));
        digitalWrite(LED_one, HIGH);
        digitalWrite(LED_two, LOW);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
      else
      {
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
    }

    else if (ledState_pattern_one == 'D')
    {
      ledState_pattern_one = 'A';
      if (digitalRead(LED_Button_three) == 1) //Here I have used pull-up resistor that's why i have checked with 1.
      {
//        Serial.print("three");
        Serial.println(digitalRead(LED_Button_three));
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, LOW);
        digitalWrite(LED_three, HIGH);
        digitalWrite(LED_four, LOW);
      }
      else
      {
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
    }
  }
}

void pattern_two(unsigned long currentMillis_pattern)
{
  if (currentMillis_pattern - previousMillis_pattern_two >= interval)
  {
    previousMillis_pattern_two = currentMillis_pattern;
    if (ledState == 'A')
    {
      ledState = 'B';
      if (digitalRead(LED_Button_one) == 1) //Here I have used pull-up resistor that's why i have checked with 1.
      {
//        Serial.print("one");
        Serial.println(digitalRead(LED_Button_one));
        digitalWrite(LED_one, HIGH);
        digitalWrite(LED_two, LOW);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
      else
      {
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
    }
    else if (ledState == 'B')
    {
      ledState = 'C';
      if (digitalRead(LED_Button_three) == 1) //Here I have used pull-up resistor that's why i have checked with 1.
      {
//        Serial.print("three");
        Serial.println(digitalRead(LED_Button_three));
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, LOW);
        digitalWrite(LED_three, HIGH);
        digitalWrite(LED_four, LOW);
      }
      else
      {
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
    }
    else if (ledState == 'C')
    {
      ledState = 'D';
      if (digitalRead(LED_Button_two) == 1) //Here I have used pull-up resistor that's why i have checked with 1.
      {
//        Serial.print("two");
        Serial.println(digitalRead(LED_Button_two));
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
      else
      {
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
    }
    else if (ledState == 'D')
    {
      ledState = 'A';
      if (digitalRead(LED_Button_four) == 1) //Here I have used pull-up resistor that's why i have checked with 1.
      {
//        Serial.print("four");
        Serial.println(digitalRead(LED_Button_four));
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, LOW);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, HIGH);
      }
      else
      {
        digitalWrite(LED_one, LOW);
        digitalWrite(LED_two, HIGH);
        digitalWrite(LED_three, LOW);
        digitalWrite(LED_four, LOW);
      }
    }
  }
}
void patternStop()
{
  digitalWrite(LED_one, LOW);
  digitalWrite(LED_two, LOW);
  digitalWrite(LED_three, LOW);
  digitalWrite(LED_four, LOW);
  state = 0;
}


Here is my circuit diagram.