ESP8266 - LED - Blink Without Delay

Let us imagine that ESP8266 has two jobs to accomplish: blinking an LED and monitoring the state of a button which can be pressed at any time. If we use the delay() function (as explained in a past tutorial), ESP8266 may miss out on some of the button presses. In other words, ESP8266 would not be able to fully execute the second task.

This tutorial instructs you how to make ESP8266 blink an LED and monitor the state of a button without missing any of its presses.

We will go through three examples and compare the distinctions between them:

This method is not just limited to blinking LED and checking the button's state. It generally allows ESP8266 to perform multiple tasks simultaneously without blocking each other.

Hardware Preparation

1×ESP8266 NodeMCU
1×Micro USB Cable
1×LED
1×220 ohm resistor
1×Push Button
1×(Optional) Panel-mount Push Button
1×Breadboard
1×Jumper Wires
1×(Optional) 5V Power Adapter for ESP8266
1×(Optional) ESP8266 Screw Terminal Adapter

Or you can buy the following sensor kit:

1×DIYables Sensor Kit 30 types, 69 units
Disclosure: Some of the links provided in this section are Amazon affiliate links. We may receive a commission for any purchases made through these links at no additional cost to you. We appreciate your support.

Overview of LED and Button

If you are unfamiliar with LED and button (pinout, functionality, programming ...), the following tutorials can help:

Wiring Diagram

The wiring diagram between ESP8266 NodeMCU and LED

This image is created using Fritzing. Click to enlarge image

See more in ESP8266's pinout and how to supply power to the ESP8266 and other components.

ESP8266 Code - With Delay

/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-led-blink-without-delay */ #define BUTTON_PIN D1 // The ESP8266 pin D1 connected to button #define LED_PIN D7 // The ESP8266 pin D7 connected to led #define BLINK_INTERVAL 1000 // interval at which to blink LED (milliseconds) int led_state = LOW; // led_state used to set the LED int prev_button_state = LOW; // will store last time button was updated void setup() { Serial.begin(9600); // Configure the ESP8266 pin as a digital output pin pinMode(LED_PIN, OUTPUT); // Configure the ESP8266 pin as a digital input pin pinMode(BUTTON_PIN, INPUT); } void loop() { // if the LED is off turn it on and vice-versa: led_state == (led_state == LOW) ? HIGH : LOW; // set the LED with the led_state of the variable: digitalWrite(LED_PIN, led_state); delay(BLINK_INTERVAL); // If button is pressed during this time, ESP8266 CANNOT detect int button_state = digitalRead(BUTTON_PIN); if(button_state != prev_button_state) { // print out the state of the button: Serial.println(button_state); // save the last state of button prev_button_state = button_state; } // DO OTHER WORKS HERE }

Detailed Instructions

To get started with ESP8266 on Arduino IDE, follow these steps:

  • Check out the how to setup environment for ESP8266 on Arduino IDE tutorial if this is your first time using ESP8266.
  • Wire the components as shown in the diagram.
  • Connect the ESP8266 board to your computer using a USB cable.
  • Open Arduino IDE on your computer.
  • Choose the correct ESP8266 board, such as (e.g. NodeMCU 1.0 (ESP-12E Module)), and its respective COM port.
  • Plug the USB cable into the ESP8266 and PC.
  • Launch the Arduino IDE, select the correct board and port.
  • Copy the code and open it in the Arduino IDE.
  • Click the Upload button in the Arduino IDE to compile and upload the code to the ESP8266.
How to upload code to ESP8266 NodeMCU using Arduino IDE
  • Open the Serial Monitor.
  • Press the button four times.
  • Check out the LED; it will alternate between being on and off every second.
  • Check the output in the Serial Monitor.
COM6
Send
1 0
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • On Serial Monitor, some pressing times were not registered. This is because, while in delay, ESP8266 is unable to perform any tasks. Consequently, it is not able to detect the pressing event.

ESP8266 Code - Without Delay

/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-led-blink-without-delay */ #define BUTTON_PIN D1 // The ESP8266 pin D1 connected to button #define LED_PIN D7 // The ESP8266 pin D7 connected to led #define BLINK_INTERVAL 1000 // interval at which to blink LED (milliseconds) int led_state = LOW; // led_state used to set the LED int prev_button_state = LOW; // will store last time button was updated unsigned long prev_time_ms = 0; // will store last time LED was updated void setup() { Serial.begin(9600); // Configure the ESP8266 pin as a digital output pin pinMode(LED_PIN, OUTPUT); // Configure the ESP8266 pin as a digital input pin pinMode(BUTTON_PIN, INPUT); } void loop() { // 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. unsigned long time_ms = millis(); if (time_ms - prev_time_ms >= BLINK_INTERVAL) { // if the LED is off turn it on and vice-versa: led_state == (led_state == LOW) ? HIGH : LOW; // set the LED with the led_state of the variable: digitalWrite(LED_PIN, led_state); // save the last time you blinked the LED prev_time_ms = time_ms; } // check button state's change int button_state = digitalRead(BUTTON_PIN); if(button_state != prev_button_state) { // print out the state of the button: Serial.println(button_state); // save the last state of button prev_button_state = button_state; } // DO OTHER WORKS HERE }

Detailed Instructions

  • Wire the components as shown in the diagram.
  • Connect the ESP8266 board to your computer using a USB cable.
  • Open Arduino IDE on your computer.
  • Choose the correct ESP8266 board, such as (e.g. NodeMCU 1.0 (ESP-12E Module)), and its respective COM port.
  • Execute the code and press the button 4 times.
  • Check out the LED, which will alternate between ON and OFF at regular intervals of one second.
  • Check the output in the Serial Monitor.
COM6
Send
1 0 1 0 1 0 1 0
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  
  • All occurrences of urgent matters were identified.

Code Explanation

Check out the line-by-line explanation contained in the comments of the source code!

Adding More Tasks

The ESP8266 code below does

  • Makes two LEDs blink with different intervals.
  • Checks the state of the button.
/* * This ESP8266 NodeMCU code was developed by newbiely.com * * This ESP8266 NodeMCU code is made available for public use without any restriction * * For comprehensive instructions and wiring diagrams, please visit: * https://newbiely.com/tutorials/esp8266/esp8266-led-blink-without-delay */ #define BUTTON_PIN D1 // The ESP8266 pin D1 connected to button #define LED_PIN_1 D6 // The ESP8266 pin D7 connected to led #define LED_PIN_2 D7 // The ESP8266 pin D7 connected to led #define BLINK_INTERVAL_1 1000 // interval at which to blink LED 1 (milliseconds) #define BLINK_INTERVAL_2 500 // interval at which to blink LED 2 (milliseconds) int led_state_1 = LOW; // led_state used to set the LED 1 int led_state_2 = LOW; // led_state used to set the LED 2 int prev_button_state = LOW; // will store last time button was updated unsigned long prev_time_ms_1 = 0; // will store last time LED 1 was updated unsigned long prev_time_ms_2 = 0; // will store last time LED 2 was updated void setup() { Serial.begin(9600); // Configure the ESP8266 pin as a digital output pin pinMode(LED_PIN_1, OUTPUT); pinMode(LED_PIN_2, OUTPUT); // Configure the ESP8266 pin as a digital input pin pinMode(BUTTON_PIN, INPUT); } void loop() { unsigned long time_ms = millis(); // check to see if it's time to blink the LED 1 if (time_ms - prev_time_ms_1 >= BLINK_INTERVAL_1) { // if the LED is off turn it on and vice-versa: led_state_1 == (led_state_1 == LOW) ? HIGH : LOW; // set the LED with the led_state of the variable: digitalWrite(LED_PIN_1, led_state_1); // save the last time you blinked the LED prev_time_ms_1 = time_ms; } // check to see if it's time to blink the LED 2 if (time_ms - prev_time_ms_2 >= BLINK_INTERVAL_2) { // if the LED is off turn it on and vice-versa: led_state_2 == (led_state_2 == LOW) ? HIGH : LOW; // set the LED with the led_state of the variable: digitalWrite(LED_PIN_2, led_state_2); // save the last time you blinked the LED prev_time_ms_1 = time_ms; } // check button state's change int button_state = digitalRead(BUTTON_PIN); if(button_state != prev_button_state) { // print out the state of the button: Serial.println(button_state); // save the last state of button prev_button_state = button_state; } // DO OTHER WORKS HERE }

Video Tutorial

Extendability

This method allows ESP8266 to perform multiple tasks simultaneously, without one task blocking another. For instance, sending a request to the Internet and waiting for the response, while also blinking LED indicators and monitoring the cancel button.