ESP32 - Button - Debounce

When a button is pressed/released or when a switch is toggled, newbies usually think simply that its state is changed from LOW to HIGH or HIGH to LOW. In practice, it is not exactly like that. Because of the mechanical and physical characteristics, the state of the button (or switch) might be toggled between LOW and HIGH several times. This phenomenon is called chattering. The chattering phenomenon makes a single press that may be read as multiple presses, resulting in a malfunction in some kinds of applications. This tutorial shows how to eliminate this phenomenon (called debounce the input).

ESP32 chattering phenomenon

Hardware Required

1×ESP-WROOM-32 Dev Module
1×Micro USB Cable
1×Button
1×Breadboard
2×Jumper Wires
Please note: These are affiliate links. If you buy the components through these links, We may get a commission at no extra cost to you. We appreciate it.

About Button

If you do not have knowledge of button (pinout, how they work, how to connect them to ESP32, how to program for them...), learn about them in the following tutorials:

Wiring Diagram

ESP32 Button Wiring Diagram

Image is developed using Fritzing. Click to enlarge image

Let's see and compare ESP32 code between WITHOUT and WITH debounce and their behaviors.

Reading Button without Debounce

Before learning about debouncing, just see the code without debouncing and its behavior.

Quick Steps

  • If this is the first time you use ESP32, see how to setup environment for ESP32 on Arduino IDE
  • Connect the ESP32 board to your PC via a micro USB cable
  • Open Arduino IDE, select the right ESP32 board and COM port
  • Copy the below code and open with Arduino IDE
/* * Created by esp32io.com * * This example code is in the public domain * * Tutorial page: https://esp32io.com/tutorials/esp32-button-debounce */ // constants won't change. They're used here to set pin numbers: const int BUTTON_PIN = 21; // GIOP21 pin connected to button // Variables will change: int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin void setup() { // initialize serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: currentState = digitalRead(BUTTON_PIN); if(lastState == HIGH && currentState == LOW) Serial.println("The button is pressed"); else if(lastState == LOW && currentState == HIGH) Serial.println("The button is released"); // save the the last state lastState = currentState; }
  • Click Upload button on Arduino IDE to compile and upload code to ESP32 board
  • Arduino IDE Upload Code
  • Open Serial Monitor on Arduino IDE
  • How to open serial monitor on Arduino IDE
  • Keep pressing the button several seconds and then release it.
  • See the result on Serial Monitor. It looks like the below:
  • 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  

⇒ As you can see, you pressed and released the button just the once. However, ESP32 recognizes it as multiple presses and releases.

Reading Button with Debounce

Quick Steps

/* * Created by esp32io.com * * This example code is in the public domain * * Tutorial page: https://esp32io.com/tutorials/esp32-button-debounce */ // constants won't change. They're used here to set pin numbers: const int BUTTON_PIN = 21; // GIOP21 pin connected to button const int DEBOUNCE_DELAY = 50; // the debounce time; increase if the output flickers // Variables will change: int lastSteadyState = LOW; // the previous steady state from the input pin int lastFlickerableState = LOW; // the previous flickerable state from the input pin int currentState; // 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 serial communication at 9600 bits per second: Serial.begin(9600); // initialize the pushbutton pin as an pull-up input // the pull-up input pin will be HIGH when the switch is open and LOW when the switch is closed. pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { // read the state of the switch/button: currentState = 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 (currentState != lastFlickerableState) { // reset the debouncing timer lastDebounceTime = millis(); // save the the last flickerable state lastFlickerableState = currentState; } if ((millis() - lastDebounceTime) > DEBOUNCE_DELAY) { // 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 && currentState == LOW) Serial.println("The button is pressed"); else if(lastSteadyState == LOW && currentState == HIGH) Serial.println("The button is released"); // save the the last steady state lastSteadyState = currentState; } }
  • Click Upload button on Arduino IDE to compile and upload code to ESP32 board
  • Open Serial Monitor on Arduino IDE
  • How to open serial monitor on Arduino IDE
  • Keep pressing the button several seconds and then release it.
  • See the result on Serial Monitor. It looks like the below:
  • COM6
    Send
    The button is pressed The button is released
    Autoscroll Show timestamp
    Clear output
    9600 baud  
    Newline  

⇒ As you can see, you pressed and released the button just the once. ESP32 recognizes it as the single press and release. The chatter is eliminated.

We Made It Simple - ESP32 Button Debounce Code with Library

To make it much easier for beginners, especially when using multiple buttons, we created a library, called ezButton. You can learn about ezButton library here.

ESP32 Button Debounce Code for A Single Button

/* * Created by esp32io.com * * This example code is in the public domain * * Tutorial page: https://esp32io.com/tutorials/esp32-button-debounce */ #include <ezButton.h> ezButton button(21); // create ezButton object that attach to pin GIOP21 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"); }

ESP32 Button Debounce Code for A Multiple Buttons

/* * Created by esp32io.com * * This example code is in the public domain * * Tutorial page: https://esp32io.com/tutorials/esp32-button-debounce */ #include <ezButton.h> ezButton button1(21); // create ezButton object that attach to pin GIOP21; ezButton button2(22); // create ezButton object that attach to pin GIOP22; ezButton button3(23); // create ezButton object that attach to pin GIOP23; 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 wiring diagram for above code:

ESP32 Button Library Wiring Diagram

Image is developed using Fritzing. Click to enlarge image

Video Tutorial

We are considering to make the video tutorials. If you think the video tutorials are essential, please subscribe to our YouTube channel to give us motivation for making the videos.

Additional Knowledge

  • DEBOUNCE_DELAY value depends on the applications. Different applications may use different values.

Extendability

The debounce method can apply for switch, touch sensor ...

Button on Commercial Products

Most electronic products have a reset button. Additionally, the button also keeps other functionalities in many products.

※ NOTE THAT:

Note that this tutorial is incomplete. We will post on our Facebook Page when the tutorial is complete. Like it to get updated.

※ NOTICES

  • We are AVAILABLE for HIRE. See how to hire us to do your project
  • If this tutorial is useful for you, please support us to make more tutorials.
  • We spent a lot of time and effort to create the content for this tutorial, please respect our work! Please do not copy the content to share on other websites. Howerver, please feel free to share the link of this tutorial anywhere