# Flashing multiple LEDs at the same time

**URL:** <https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564>\
**Category:** Tutorials\
**Created:** [December 14, 2022, 5:22pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564 "2022-12-14T17:22:40Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![PerryBebbington](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/perrybebbington/32/238766_2.png) [@PerryBebbington](https://forum.arduino.cc/u/PerryBebbington)\
**Post date:** [December 14, 2022, 5:22pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/1 "2022-12-14T17:22:40Z")

</div>

**Introduction**  
A common question is to ask how to flash 2 (or more) LEDs at the same time. Typically the person asking will be using delay and will be experiencing the main problem with delay: it blocks and stops anything else from happening.

This tutorial contains several different approaches to the problem of flashing 2 or more LEDs at the same time with independent timing for each LED. The basic principles for each can all be adapted for other situations requiring multiple timers working independently without blocking. All the ideas presented demonstrate the principles of using millis() for timing, and for collaborative, multi-tasking code.

**Further reading**  
[Using millis for timing](https://forum.arduino.cc/index.php?topic=503368.0)  
[Demonstration for several things at the same time](https://forum.arduino.cc/index.php?topic=223286.0)

**Thanks**  
In addition to the people who contributed directly to this tutorial the following also gave helpful advice and comments: @killzone_kid , @Koepel , @dlloyd , @anon57585045 , @dougp. Thank you all for your contributions and interest.

---

<div class="post-metadata">

**Author:** ![PerryBebbington](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/perrybebbington/32/238766_2.png) [@PerryBebbington](https://forum.arduino.cc/u/PerryBebbington)\
**Post date:** [December 14, 2022, 5:33pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/2 "2022-12-14T17:33:20Z")

</div>

**C style code**  
My code below flashes 2 LEDs, one connected to pin 2 and one to Pin 3, each with a suitable resistor (220 Ohms or thereabouts) to 0V. Each LED flashes independently of the other.

**Notes**  
I have used separate functions called from the loop function to illustrate putting code into functions rather than trying to do everything in the loop function.

There are 2 different flash functions, each uses millis() independently for timing. The first, flashEqualOnOffPin2(), flashes the LED on pin 2 with equal on and off times. The second, flashUnequalOnOffPin3(), flashes the LED on pin 3 and allows the on and off times to be different.

Having 2 functions illustrates having non-blocking code called from the loop function. At no point does any part of any function wait for anything, it just checks to see if it is time to change the state of a pin and if it is then it changes the pin then returns, otherwise it just returns having done nothing.

To flash more LEDs copy the relevant flash function, change its name and the pin number, paste it into your code and call it from the loop function.

There is a lot that can be done to improve this code, such as having an array for the pin numbers, having an array for the on and off times for each pin, having one function for flashing everything and passing the required pin number, on and off times to it. Each of these improvements would be worth exploring but each would also complicate the code. My aim was to make the code simple for beginners.

Tested on a Nano Every, should work on most if not all Arduino boards.

If the comments in the code do not adequately explain it then please ask.

**Complete sketch**

```arduino
    const int LED_PIN2 = 2;
    const int LED_PIN3 = 3;

    #define LED_ON HIGH
    #define LED_OFF LOW
    
void setup() {
    Serial.begin(115200);
    pinMode(LED_PIN2, OUTPUT);
    pinMode(LED_PIN3, OUTPUT);
    digitalWrite(LED_PIN2, LED_OFF); // Give the output pins a definite, known state at start up
    digitalWrite(LED_PIN3, LED_OFF);
    Serial.println("Setup complete");
}

void loop() {
    flashEqualOnOffPin2();
    flashUnequalOnOffPin3();
}

void flashEqualOnOffPin2() {
    uint32_t currentMillis = millis();
    static uint32_t lastMillis;
    const uint32_t onOffTime = 500; //Duration for LED to be on or off before changing state, in miliseconds
    
    if (currentMillis - lastMillis >= onOffTime) {
        lastMillis += onOffTime;

        
    if (digitalRead(LED_PIN2) == LED_ON) {
            digitalWrite(LED_PIN2, LED_OFF);
        } else {
            digitalWrite(LED_PIN2, LED_ON);
        }
    }
}

void flashUnequalOnOffPin3() {
    uint32_t currentMillis = millis();
    static uint32_t lastMillis;
    const uint32_t onTime = 1750; //Duration for LED to be on, in miliseconds
    const uint32_t offTime = 350; //Duration for LED to be off, in miliseconds

        if (digitalRead(LED_PIN3) == LED_ON) { // Read the current state of pin 3
            if (currentMillis - lastMillis >= onTime) { // Pin 3 is high (LED on), check on time and turn LED off if time has expired
                lastMillis += onTime; // Add the value of onTime to lastMillis ready to start the next timing interval
                digitalWrite(LED_PIN3, LED_OFF); // Turn LED off
            }
     } else {
        if (currentMillis - lastMillis >= offTime) { // Pin 3 is low (LED off), check off time and turn LED on if time has expired
            lastMillis += offTime; // Add the value of offTime to lastMillis ready to start the next timing interval
            digitalWrite(LED_PIN3, LED_ON); // Turn LED on
        }
     }
}
```

**Simulation**

> **[2 LEDs flashing at different rates - Wokwi ESP32, STM32, Arduino Simulator](https://wokwi.com/projects/351045282069217880)**
>
> Run IoT and embedded projects in your browser: ESP32, STM32, Arduino, Pi Pico, and more. No installation required!

Edit: Code modified for clarity, with thanks to @camsysca for suggested improvements.

---

<div class="post-metadata">

**Author:** ![J-M-L](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/j-m-l/32/766245_2.png) [@J-M-L](https://forum.arduino.cc/u/J-M-L)\
**Post date:** [December 14, 2022, 5:50pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/3 "2022-12-14T17:50:50Z")

</div>

Here is a basic entry level C++ like class based version

```cpp
class FlashingLed {
  private:
    byte ledPin;
    unsigned long onTime, offTime, lastMillis;

  public:
    FlashingLed(const byte pin, const unsigned long on, const unsigned long off) : ledPin(pin), onTime(on), offTime(off) {}

    void begin() {
      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin, HIGH); // Turn LED on
      lastMillis = millis(); // remember when we did so
    }

    void flashWhenNeeded() {
      if (digitalRead(ledPin) == HIGH) { // if the led is ON a it's the right time, turn it off (HIGH is on)
        if (millis() - lastMillis >= onTime) { // check on time and turn LED off if time has expired
          lastMillis += onTime; // Add the value of onTime to lastMillis ready to start the next timing interval
          digitalWrite(ledPin, LOW); // Turn LED off
        }
      } else { // LED is off, if it's the right time, turn it on
        if (millis() - lastMillis >= offTime) { // check off time and turn LED on if time has expired
          lastMillis += offTime; // Add the value of offTime to lastMillis ready to start the next timing interval
          digitalWrite(ledPin, HIGH); // Turn LED on
        }
      }
    }
};

FlashingLed leds[] = {
  {2, 500, 500}, // pin 2, 500ms ON and 500 ms OFF
  {3, 1750, 350} // pin 3, 1750ms ON and 350ms OFF
}; 

void setup() {
  Serial.begin(115200);
  Serial.println(F( __FILE__ ));
  for (auto &l : leds) l.begin();
  Serial.println("Setup complete");
}

void loop() {
  for (auto &l : leds) l.flashWhenNeeded();
}

```

and a simulation if you want to see the blinking

> **[sketch.ino - Wokwi Arduino and ESP32 Simulator](https://wokwi.com/projects/350871561341764179)**
>
> Run IoT and embedded projects in your browser: ESP32, Arduino, Pi Pico, and more. No installation required!

---

<div class="post-metadata">

**Author:** ![paulpaulson](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/paulpaulson/32/363643_2.png) [@paulpaulson](https://forum.arduino.cc/u/paulpaulson)\
**Post date:** [December 14, 2022, 6:15pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/4 "2022-12-14T18:15:31Z")

</div>

Here we go

This is a simple class-less C++ sketch for three leds.  
My aim was to make the code simple for beginners how starts coding in C++.

```cpp
/* BLOCK COMMENT
  - Flashing 2 or more LEDs at the same time
  - This sketch may contain traces of C++.
  - In case of indisposition:
  - https://www.learncpp.com/
  - Hardware:
  - Thanks to LarryD
  - https://aws1.discourse-cdn.com/arduino/original/4X/7/e/0/7e0ee1e51f1df32e30893550c85f0dd33244fb0e.jpeg
  - Tested @ Arduino: Mega[X] - UNO [] - Nano []
*/
enum Cntrl {Off, On};
enum Port2Led {One, Two, Three};
constexpr byte LedPins[] {9, 10, 11};
struct BLINKLED
{
  const byte Pin;
  const unsigned long Duration[2]; // Off/On time
  unsigned long stamp;
};
BLINKLED blinkLeds[]
{
  {LedPins[One], {250, 500}, 0},
  {LedPins[Two], {500, 500}, 0},
  {LedPins[Three], {500, 250}, 0},
};
void setup()
{
  for (auto blinkLed : blinkLeds) pinMode(blinkLed.Pin, OUTPUT);
}
void loop()
{
  unsigned long currentTime = millis();
  for (auto &blinkLed : blinkLeds) {
    if (currentTime - blinkLed.stamp >= blinkLed.Duration[digitalRead(blinkLed.Pin)])
    {
      blinkLed.stamp = currentTime;
      digitalWrite(blinkLed.Pin, !digitalRead(blinkLed.Pin));
    }
  }
}

```

---

<div class="post-metadata">

**Author:** ![LarryD](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/larryd/32/215550_2.png) [@LarryD](https://forum.arduino.cc/u/LarryD)\
**Post date:** [December 14, 2022, 8:28pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/5 "2022-12-14T20:28:38Z")

</div>

# An example similar to Perry's, just a bit different:

```arduino
//LarryD

// ********************************************^************************************************
// Version YY/MM/DD Description
// 1.00 22/11/22 Running sketch
//
//

//A Sketch to toggle two LEDs using the timing below

//wired so +5V turns LED ON LED
#define LEDon HIGH //[Output Pin]---[220R]---[A->|-K]---GND
#define LEDoff LOW

const byte LED_PIN2 = 2;
const byte LED_PIN3 = 3;

// *********************
//Timing stuff
unsigned long LED2Time;
unsigned long LED3Time;

const unsigned long LED2OnOffInterval = 500;
const unsigned long LED3OnTimeInterval = 1750;
const unsigned long LED3OffTimeInterval = 350;

//at powerup, LED3 is OFF
unsigned long LED3Interval = LED3OnTimeInterval;

// ********************************************^************************************************
void setup()
{
  Serial.begin(115200);

  pinMode(LED_PIN2, OUTPUT);
  pinMode(LED_PIN3, OUTPUT);

  //power up conditions
  digitalWrite(LED_PIN2, LEDon);
  digitalWrite(LED_PIN3, LEDon);

  //initialize our 2 TIMERs
  LED2Time = millis();
  LED3Time = millis();

} //END of setup()

// ********************************************^************************************************
void loop()
{
  checkLED2();
  checkLED3();

  // ****************************************
  // Other non blocking code goes here
  // ****************************************

} //END of loop()

// ********************************************^************************************************
void checkLED2()
{
  // **************************************** LED2 T I M E R
  //is it time to toggle LED2 ?
  if (millis() - LED2Time >= LED2OnOffInterval)
  {
    //restart the TIMER
    LED2Time = millis();

    //current state of our LED
    byte LED2State = digitalRead(LED_PIN2);

    //toggle the LED
    digitalWrite(LED_PIN2, !LED2State);

  } //END of this TIMER

} //END of checkLED2()

// ********************************************^************************************************
void checkLED3()
{
  // **************************************** LED3 T I M E R
  //is it time to toggle LED3 ?
  if (millis() - LED3Time >= LED3Interval)
  {
    //restart the TIMER
    LED3Time = millis();

    //current state of our LED
    byte LED3State = digitalRead(LED_PIN3);

    //toggle the LED
    digitalWrite(LED_PIN3, !LED3State);

    // *****************
    //is the LED currently ON ?
    if (!LED3State == LEDon)
    {
      //set this TIMER to the LED ON duration
      LED3Interval = LED3OnTimeInterval;
    }

    // *****************
    //LED is currently OFF
    else
    {
      //set this TIMER to the LED OFF duration
      LED3Interval = LED3OffTimeInterval;
    }

  } //END of this TIMER

} //END of checkLED3()

// ********************************************^************************************************

```

---

<div class="post-metadata">

**Author:** ![LarryD](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/larryd/32/215550_2.png) [@LarryD](https://forum.arduino.cc/u/LarryD)\
**Post date:** [December 14, 2022, 8:30pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/6 "2022-12-14T20:30:52Z")

</div>

# An example similar to paulpaulson's sketch:

```arduino
//TIMERs are in milliseconds or microseconds
//LarryD

// ********************************************^************************************************
// Version YY/MM/DD Description
// 2.00 22/11/12 Running sketch
// 2.50 22/11/12 Changed some variable names
//

//wired so +5V turns LED ON LED
#define LEDon HIGH //[Output Pin]---[220R]---[A->|-K]---GND
#define LEDoff LOW

const byte redLEDpin = 2;
const byte greenLEDpin = 3;

const unsigned long redLEDonOffInterval = 500;

const unsigned long greenLEDonInterval = 1750;
const unsigned long greenLEDoffInterval = 350;

// ********************************************^************************************************
//a structure that creates TIMER objects
struct makeTimer
{
  //previousTime = the time this TIMER was (re)started
  //waitInterval = delay time (ms/us)we are looking for
  //restart = do we start this TIMER again and again
  //enableFlag = is this TIMER enabled/allowed to be accessed
  //timeType = true = millis(), false = micros()
  //
  // **********************
  //For each TIMER object we need to define it:
  //Example:
  // makeTimer myTimer = //give the TIMER a name "myTimer"
  // {
  // 0, 200UL, true, true, true //previousTime, waitInterval, restart, enableFlag, timeType
  // };
  // You have access to:
  // Variables: myTimer.previousTime, myTimer.waitInterval, myTimer.restart, myTimer.enableFlag, myTimer.timeType,
  // Functions: myTimer.checkTime(), myTimer.enableTimer(), myTimer.expireTimer()
  // **********************

  unsigned long previousTime;
  unsigned long waitInterval;
  bool restart;
  bool enableFlag;
  bool timeType;

  unsigned long currentTime;

  // ******************************************
  //Function to check if this TIMER has expired ex: myTimer.checkTime();
  bool checkTime()
  {
    if (timeType == true)
    {
      currentTime = millis();
    }
    else
    {
      currentTime = micros();
    }

    //has this TIMER expired ?
    if (enableFlag == true && currentTime - previousTime >= waitInterval)
      //Note: if delays of < 2 millis are needed, use micros() and adjust waitInterval as needed
    {
      //should this TIMER start again?
      if (restart)
      {
        //get ready for the next iteration
        previousTime = currentTime;
      }
      //TIMER has expired
      return true;
    }

    //TIMER has not expired or is disabled
    return false;

  } //END of checkTime()

  // ******************************************
  //Function to enable and initialize this TIMER, ex: myTimer.enableTimer();
  void enableTimer()
  {
    enableFlag = true;

    //initialize previousTime to current millis() or micros()
    if (timeType == true)
    {
      previousTime = millis();
    }
    else
    {
      previousTime = micros();
    }

  } //END of enableTimer()

  // ******************************************
  //Function to force this TIMER to expire ex: myTimer.expireTimer();
  void expireTimer()
  {
    //force this TIMER to expire now
    previousTime = currentTime - waitInterval;

  } //END of expireTimer()

}; //END of structure “makeTimer”

// ********************************************^************************************************

//Let's create and and initialize 2 "makeTimer" objects

// ***************************
makeTimer redLEDtimer = //create redLEDtimer
{
  0, redLEDonOffInterval, true, true, true //previousTime, waitInterval, restart, enableFlag, true=millis/false=micros
};

// ***************************
makeTimer greenLEDtimer = //create greenLEDtimer
{
  0, greenLEDoffInterval, true, true, true //previousTime, waitInterval, restart, enableFlag, true=millis/false=micros
};

// ********************************************^************************************************
void setup()
{
  Serial.begin(115200);

  pinMode(redLEDpin, OUTPUT);
  pinMode(greenLEDpin, OUTPUT);

  //power up conditions
  digitalWrite(redLEDpin, LEDoff);
  digitalWrite(greenLEDpin, LEDoff);

  //initialize our 2 TIMERs
  redLEDtimer.expireTimer();
  greenLEDtimer.expireTimer();

} //END of setup()

// ********************************************^************************************************
void loop()
{
  // ***************************
  //is it time to toggle the red LED ?
  if (redLEDtimer.checkTime())
  {
    serviceRedLED();
  }

  // ***************************
  //is it time to toggle the green LED ?
  if (greenLEDtimer.checkTime())
  {
    serviceGreenLED();
  }

  // **********************************
  //Put other non-blocking code here
  // **********************************

} //END of loop()

// ********************************************^************************************************
void serviceRedLED()
{
  //current state of our red LED
  byte redLEDstate = digitalRead(redLEDpin);

  //is the LED ON ?
  if (redLEDstate == LEDon)
  {
    digitalWrite(redLEDpin, LEDoff);
  }

  else
  {
    digitalWrite(redLEDpin, LEDon);
  }

} //END of serviceRedLED()

// ********************************************^************************************************
void serviceGreenLED()
{
  //current state of our green LED
  byte greenLEDstate = digitalRead(greenLEDpin);

  //is the LED ON ?
  if (greenLEDstate == LEDon)
  {
    digitalWrite(greenLEDpin, LEDoff);

    //set this TIMER to the LED OFF duration
    greenLEDtimer.waitInterval = greenLEDoffInterval;
  }

  else
  {
    digitalWrite(greenLEDpin, LEDon);

    //set this TIMER to the LED ON duration
    greenLEDtimer.waitInterval = greenLEDonInterval;
  }

} //END of serviceGreenLED()

// ********************************************^************************************************

```

---

<div class="post-metadata">

**Author:** ![LarryD](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/larryd/32/215550_2.png) [@LarryD](https://forum.arduino.cc/u/LarryD)\
**Post date:** [December 14, 2022, 8:41pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/7 "2022-12-14T20:41:56Z")

</div>

This is the schematic that accompanies the 5 sketches above.

It is always a good idea to start with a schematic so you have a good idea what to expect when you write your sketch.

Notice we have each LED wired so a HIGH on the output pin will turn ON the LED.

 ![2022-12-13_13-24-24](https://europe1.discourse-cdn.com/arduino/original/4X/6/e/d/6ed0018a0f2e7dad043a8492c4432ab6998fcd47.jpeg)

* * *

Here is an oscilloscope screen capture of the output pin signals.

This shows clearly the results of running the sketch.

 ![2022-12-13_13-41-26](https://europe1.discourse-cdn.com/arduino/original/4X/3/3/b/33b75ae4a5100332d7972c93e7d0bf4aaa8e0cc2.jpeg)

---

<div class="post-metadata">

**Author:** ![PerryBebbington](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/perrybebbington/32/238766_2.png) [@PerryBebbington](https://forum.arduino.cc/u/PerryBebbington)\
**Post date:** [December 15, 2022, 8:21am UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/8 "2022-12-15T08:21:09Z")

</div>

Closed on December 15, 2022, 8:21am UTC



---

<div class="post-metadata">

**Author:** ![PerryBebbington](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/perrybebbington/32/238766_2.png) [@PerryBebbington](https://forum.arduino.cc/u/PerryBebbington)\
**Post date:** [December 16, 2022, 8:59am UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/9 "2022-12-16T08:59:45Z")

</div>

Pinned on December 16, 2022, 8:59am UTC



---

<div class="post-metadata">

**Author:** ![Ballscrewbob](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/ballscrewbob/32/950458_2.png) [@Ballscrewbob](https://forum.arduino.cc/u/Ballscrewbob)\
**Post date:** [March 7, 2023, 4:45pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/10 "2023-03-07T16:45:41Z")

</div>

Opened on March 7, 2023, 4:45pm UTC



---

<div class="post-metadata">

**Author:** ![DaveX](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/davex/32/751443_2.png) [@DaveX](https://forum.arduino.cc/u/DaveX)\
**Post date:** [March 7, 2023, 5:03pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/11 "2023-03-07T17:03:12Z")

</div>

I think the ideas in this thread are worthy of a new example in the IDE, per

> [@The fact that something has been used for a long time is in no way an argument for making it the same for another 100 years](https://forum.arduino.cc/t/the-fact-that-something-has-been-used-for-a-long-time-is-in-no-way-an-argument-for-making-it-the-same-for-another-100-years/1097951/63):
>
> If is easy to point folks to BWOD but linkage-wise the comments point to [https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay](https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay) which starts off with the motivating example of doing two things at once, but doesn't actually get there.

Here's my effort:

```arduino
/*
  BlinkWithoutDelayMore -- Blink without Delay for more LEDs, using Functions

  Turns on and off a 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.

  State diagram: tinyurl.com/BWODMdiag 

  The circuit:
  - Use the onboard LED.
  - Note: Most Arduinos have an on-board LED you can control. On the UNO, MEGA
    and ZERO it is attached to digital pin 13, on MKR1000 on pin 6. LED_BUILTIN
    is set to the correct LED pin independent of which board is used.
    If you want to know what pin the on-board LED is connected to on your
    Arduino model, check the Technical Specs of your board at:
    https://www.arduino.cc/en/Main/Products

  created 2005
  by David A. Mellis
  modified 8 Feb 2010
  by Paul Stoffregen
  modified 11 Nov 2013
  by Scott Fitzgerald
  modified 9 Jan 2017
  by Arturo Guadalupi
  modified by 7 Mar 2023
  by David Forrest

  This example code is in the public domain.

  For a tutorial on how this works, please read:
  https://www.arduino.cc/en/Tutorial/BuiltInExamples/BlinkWithoutDelay

  Simulation: https://wokwi.com/projects/358554786853847041

  This was written for the discussion at
  https://forum.arduino.cc/t/the-fact-that-something-has-been-used-for-a-long-time-is-in-no-way-an-argument-for-making-it-the-same-for-another-100-years/1097951/24
  on improving the BlinkWithoutDelay example.

  For other ways of doing multiple things at once please read:
  https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/
  https://learn.adafruit.com/multi-tasking-the-arduino-part-1/now-for-two-at-once

*/

// constants won't change. Used here to set a pin number:
const int ledPin = LED_BUILTIN; // the number of the LED pin
const int ledPin2 = 3; // the number of the second LED pin

// Variables will change:
int ledState = LOW; // ledState used to set the LED

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated

// constants won't change:
const long interval = 1000; // interval at which to blink (milliseconds)

void setup() {
  // set the digital pin as output:
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  checkIfItIsTimeToBlinkAndDoIt();  
  // ^^ this function separates the BlinkWithoutDelay core
  // into a function

  checkIfItIsTimeToBlinkAndDoIt_variable(500); // function handles a separate LED
}

/////// 

void checkIfItIsTimeToBlinkAndDoIt() {
  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.  

  // save the current time
  unsigned long currentMillis = millis();

  // test if it is time yet
  if (currentMillis - previousMillis >= interval) {
    // save the last time you changed the LED
    previousMillis = currentMillis;

    // Toggle the ledState variable:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    // set the LED output to match the ledState variable:
    digitalWrite(ledPin, ledState);
  } // end interval check

}

void checkIfItIsTimeToBlinkAndDoIt_variable(unsigned long interval) {
  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  // If it is not yet time it immediately returns control back to loop()

  // These "local scope" variables mask variables of the same name in other scopes
  // this helps keep the global namespace cleaner and easier to maintain
  const int ledPin = ledPin2 ; // copy from global constant
  // use static for private state variables that will persist across calls
  static bool initialized = false;
  static int ledState = LOW;
  static unsigned long previousMillis ;

  // save the current time
  unsigned long currentMillis = millis();

  if (initialized == false) { // 
    ledState = LOW;
    pinMode(ledPin, OUTPUT);
    digitalWrite(ledPin, ledState);
    initialized = true;
    previousMillis = millis();
  }

  // test if it is time yet
  if (currentMillis - previousMillis >= interval) {
    // save the last time you changed the LED
    previousMillis = currentMillis;

    // Toggle the ledState variable:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    // set the LED output to match the ledState variable:
    digitalWrite(ledPin, ledState);
  } // end interval check

}

```

(I reserve the right to edit this code to follow the sim in that Wokwi link. )

In contrast with the other example, my schematic follows BWOD by using LED\_BUILTIN on 13, while the other is on pin 3.

> **[BlinkWithoutDelayMore - Wokwi ESP32, STM32, Arduino Simulator](https://wokwi.com/projects/358554786853847041)**
>
> Run IoT and embedded projects in your browser: ESP32, STM32, Arduino, Pi Pico, and more. No installation required!

What I like about my code is that it builds directly from the venerable BWOD, giving a clear path forward from doing one thing without delay to [DoingSeveralThingsAtTheSameTime](https://forum.arduino.cc/t/demonstration-code-for-several-things-at-the-same-time/217158) without delay. I think it would be good to highlight this thread, and the other good tutorials on how to solve the same problem in the code's comments, because comparing different ways to do the same thing helps with learning.

Also pointing at more advanced multitasking tutorials would be helpful:

- [Overview | Multi-tasking the Arduino - Part 1 | Adafruit Learning System](https://learn.adafruit.com/multi-tasking-the-arduino-part-1)
- [Demonstration code for several things at the same time](https://forum.arduino.cc/t/demonstration-code-for-several-things-at-the-same-time/217158)
- [Planning and Implementing an Arduino Program](https://forum.arduino.cc/t/planning-and-implementing-an-arduino-program/252364)
- [Using millis() for timing. A beginners guide](https://forum.arduino.cc/t/using-millis-for-timing-a-beginners-guide/483573)
- [A Demo-Code explaining the switch-case state-machine and how to do things (almost) in parallel](https://forum.arduino.cc/t/a-demo-code-explaining-the-switch-case-state-machine-and-how-to-do-things-almost-in-parallel/888172)

---

<div class="post-metadata">

**Author:** ![PerryBebbington](https://dub1.discourse-cdn.com/arduino/user_avatar/forum.arduino.cc/perrybebbington/32/238766_2.png) [@PerryBebbington](https://forum.arduino.cc/u/PerryBebbington)\
**Post date:** [March 8, 2023, 10:37pm UTC](https://forum.arduino.cc/t/flashing-multiple-leds-at-the-same-time/1065564/12 "2023-03-08T22:37:04Z")

</div>

Closed on March 8, 2023, 10:37pm UTC


