ESP8266 - Button - Debounce

When a button is pressed or released, or a switch is flipped, newbies often assume that its state changes from LOW to HIGH or HIGH to LOW. In reality, this is not the case. Due to mechanical and physical characteristics, the state of the button (or switch) may fluctuate between LOW and HIGH multiple times per single user's action. This is known as chattering. Chattering can cause a single press to be read as multiple presses, leading to malfunctioning in certain applications.

chattering phenomenon

The method to prevent this problem is referred as debouncing or debounce. This tutorial instructs you how to do it when using the button with ESP8266. We will learn though the below steps:

Hardware Preparation

1×ESP8266 NodeMCU
1×Micro USB Cable
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 Button

If you are not familiar with buttons (including pinouts, functioning, and programming), the following tutorials can help you:

Wiring Diagram

The wiring diagram between ESP8266 NodeMCU and Button

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.

Let us take a look at the ESP8266 code for both WITH and WITHOUT debounce and compare their respective behaviors.

Reading Button without Debounce

Before exploring debouncing, take a look at the code without it and observe its behavior.

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.
  • Connect your ESP8266 to your computer using a USB cable.
  • Launch the Arduino IDE, select the appropriate board and port.
  • Copy the code below and open it in the Arduino IDE.
/* * 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-button-debounce */ #define BUTTON_PIN D7 // The ESP8266 pin D7 connected to button int prev_button_state = LOW; // The previous state from the input pin int button_state; // The current reading from the input pin void setup() { // Initialize the Serial to communicate with the Serial Monitor. Serial.begin(9600); // Configure the ESP8266 pin as a pull-up input: HIGH when the button is open, LOW when pressed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: button_state = digitalRead(BUTTON_PIN); if (prev_button_state == HIGH && button_state == LOW) Serial.println("The button is pressed"); else if (prev_button_state == LOW && button_state == HIGH) Serial.println("The button is released"); // save the the last state prev_button_state = button_state; }
  • Click the Upload button on the Arduino IDE to compile and upload the code to the ESP8266.
Arduino IDE Upload Code
  • Open the Serial Monitor.
  • Press and hold the button for a few seconds, then let go.
  • Check the output in the Serial Monitor.
COM6
Send
The button is pressed The button is pressed The button is pressed The button is released The button is released
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

You may see that, sometime, you only pressed and released the button one time. Nevertheless, ESP8266 perceives it as multiple presses and releases. This is the chattering phenomenon mentioned at the beginning of the tutorial. Let's see how to fix it in the next part.

Reading Button with Debounce

The below code applies the method called debounce to prevent the chattering phenomenon.

/* * 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-button-debounce */ #define BUTTON_PIN D7 // The ESP8266 pin D7 connected to button #define DEBOUNCE_TIME 50 // The debounce time in millisecond, increase this time if it still chatters int lastSteadyState = LOW; // The previous steady state from the input pin int lastFlickerableState = LOW; // The previous flickerable state from the input pin int button_state; // The current reading from the input pin // The following variables are unsigned longs because the time, measured in // milliseconds, will quickly become a bigger number than can be stored in an int. unsigned long lastDebounceTime = 0; // The last time the output pin was toggled void setup() { // Initialize the Serial to communicate with the Serial Monitor. Serial.begin(9600); // Configure the ESP8266 pin as a pull-up input: HIGH when the button is open, LOW when pressed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: button_state = digitalRead(BUTTON_PIN); // check to see if you just pressed the button // (i.e. the input went from LOW to HIGH), and you've waited long enough // since the last press to ignore any noise: // If the switch/button changed, due to noise or pressing: if (button_state != lastFlickerableState) { // reset the debouncing timer lastDebounceTime = millis(); // save the the last flickerable state lastFlickerableState = button_state; } if ((millis() - lastDebounceTime) > DEBOUNCE_TIME) { // whatever the reading is at, it's been there for longer than the debounce // delay, so take it as the actual current state: // if the button state has changed: if(lastSteadyState == HIGH && button_state == LOW) Serial.println("The button is pressed"); else if(lastSteadyState == LOW && button_state == HIGH) Serial.println("The button is released"); // save the the last steady state lastSteadyState = button_state; } }

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.
  • Copy the code above and open it with the Arduino IDE.
  • Click the Upload button on the Arduino IDE to compile and upload the code to the ESP8266.
  • Open the Serial Monitor.
  • Hold down the button for a few seconds, then let go.
  • Check the Serial Monitor to view the outcome.
COM6
Send
The button is pressed The button is released
Autoscroll Show timestamp
Clear output
9600 baud  
Newline  

As you can observe, you only pressed and released the button once. ESP8266 is able to detect it as a single press and release, thus eliminating any unnecessary chatter.

We Made It Simple - ESP8266 Button Debounce Code with Library

We have developed a library, ezButton, to make it simpler for those just starting out, especially when they are using multiple buttons. You can find out more about the ezButton library here.

ESP8266 Button Debounce Code for A Single 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-button-debounce */ #include <ezButton.h> ezButton button(D7); // create ezButton object for pin D7 void setup() { Serial.begin(9600); button.setDebounceTime(50); // set debounce time to 50 milliseconds } void loop() { button.loop(); // MUST call the loop() function first if(button.isPressed()) Serial.println("The button is pressed"); if(button.isReleased()) Serial.println("The button is released"); }

ESP8266 Button Debounce Code for A Multiple Buttons

/* * 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-button-debounce */ #include <ezButton.h> ezButton button1(D5); // create ezButton object for pin D5 ezButton button2(D6); // create ezButton object for pin D6 ezButton button3(D7); // create ezButton object for pin D7 void setup() { Serial.begin(9600); button1.setDebounceTime(50); // set debounce time to 50 milliseconds button2.setDebounceTime(50); // set debounce time to 50 milliseconds button3.setDebounceTime(50); // set debounce time to 50 milliseconds } void loop() { button1.loop(); // MUST call the loop() function first button2.loop(); // MUST call the loop() function first button3.loop(); // MUST call the loop() function first if(button1.isPressed()) Serial.println("The button 1 is pressed"); if(button1.isReleased()) Serial.println("The button 1 is released"); if(button2.isPressed()) Serial.println("The button 2 is pressed"); if(button2.isReleased()) Serial.println("The button 2 is released"); if(button3.isPressed()) Serial.println("The button 3 is pressed"); if(button3.isReleased()) Serial.println("The button 3 is released"); }

The schematic for the code above:. The illustration of the wiring for the code:. The representation of the connections for the code:

The wiring diagram between ESP8266 NodeMCU and Button Library

This image is created using Fritzing. Click to enlarge image

Video Tutorial

Additional Knowledge

  • The value of DEBOUNCE_DELAY is depended upon the physical characteristics of the button. Each button may have different value.

Extendability

The debounce technique can be used for switches, touch sensors, and more.