Blinking LEDs – Non-Blocking

Blinking LEDs With Non-Blocking Code


Our goal in this project is to blink the default Arduino LED and to also toggle a predefined output pin. We will do this without using non-blocking code.


There are several ways by which we can introduce a delay in our program. We could use the built-in Arduino delay function, similar to what was done in the blinky example but this makes the loop a bit sluggish. The reason for this is because when the delay function is called, it forces the micro-controller to “wait” until the delay time has lapsed. This causes our entire loop to come to a standstill and the program loses responsiveness. If the program is only toggling a single LED, then this will not make much of a difference, but the moment we start scanning inputs or start processing data, we will soon observe the undesired effect of the delay function.

We can overcome this by using the built-in timing function called millis() which returns the time in milliseconds since the board was powered on. We can use this to keep track of time. Please note that the function overflows in about 49 days, so there could be issues if you use it in projects that are left running for more than 49 days.

Let’s start by defining the pins as outputs and turning both LEDs off. The reason we turn both the LEDs off will be clear once we look at the code further.

void setup() {
  // initialize digital pin 0 as an output.
  pinMode(0, OUTPUT);
  // initialize digital pin LED_BUILTIN as an output.

  //turn OFF both LEDs
  digitalWrite(0, LOW);
  digitalWrite(LED_BUILTIN, LOW);

We then proceed to adding the time keeping logic as below:

  unsigned long currentMillis = millis();               // get current time

  if (currentMillis - previousMillis >= 1000) {         // check if 1000mS (1 second) have elapsed since the last check
    previousMillis = currentMillis;                     // save the current time for reference

    // blink LEDs
Keeping track of time

We get the current time using the millis() fucntion and store this in the currentMillis variable. We then compare this with the reference time (previousMillis) to check if 1 second or more has elapsed since the reference time. If yes, then we blink the LEDs, else we wait for the time to pass. The time interval is currently set to 1000mS but this can be updated to suit the application.

We’re going to make use of a clever way to toggle the LEDs. We will first read the current state of the LEDs and then write the opposite value to the output port as follows:

    // blink LEDs
    digitalWrite(0, !digitalRead(0));                       // toggle LED on pin 0
    digitalWrite(LED_BUILTIN, !digitalRead(LED_BUILTIN));   // toggle built-in LED
Toggling LEDs

Please note that the digitalRead() function gets executed first and gives us the current LED state. We invert this using the ‘!’ operator and write this new value back to the pin. This is the reason we set both the LEDs off during initializaiton as we wanted to set them to a known state to keep them in sync.

Using this method eliminates the need to keep track of the LED state and frees up some memory. It may not seem like much, but variables quickly add up and it’s always best practice to use memory efficiently.

Here’s the result:

Piksey Blinking LEDs

And that’s it! You are now familiar with non-blocking code and can use this to write efficient programs.


The complete Arduino project is available for download using the following link. Downloads are restricted to registered users. Registration is and will always be 100% FREE.

Project Source: P2_Blinking_LEDs_Non_Blocking


This project uses standard Arduino libraries and is thus compatible with all Arduino boards that contain the built-in LED (on pin 13) and digital pin 0. Make sure the correct board is selected in the Arduino IDE.