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).

Video Tutorial

you can watch this video tutorial

Hardware Required

1×ESP-WROOM-32 Dev Module
1×Micro USB Cable
1×Push button
1×Breadboard
2×Jumper Wires

Wiring Diagram

Breadboard Connections

ESP32 Button LED Wiring Diagram

Image is developed using Fritzing. Click to enlarge image

click to see ESP32 pin out

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.

Copy

const int BUTTON_PIN = 2;                                          // the number of the pushbutton pin
int lastState = LOW;                                               // the previous state from the input pin
int currentState;                                                  // the current reading from the input pin
void setup() {
    Serial.begin(9600);                                            // initialize serial communication at 9600 bits per second
    pinMode(BUTTON_PIN, INPUT_PULLUP);                             // initialize the pushbutton pin as an pull-up input
}                                               
void loop() {
   currentState = digitalRead(BUTTON_PIN);                         // read the state of the switch/button
   if(lastState == HIGH && currentState == LOW)                    // check if the pushbutton is pressed. 
       Serial.println("The button is released");             
   else if(lastState == LOW && currentState == HIGH)
       Serial.println("The button is pressed");              
   }
   lastState = currentState;                                       // save the the last state
}                

Quick Steps

  • power up your board
  • Open Arduino IDE
  • Select the right board
  • Select the right port
  • Copy the above code and open with Arduino IDE
  • Click Upload button on Arduino IDE to upload code to ESP32
  • Arduino IDE Upload Code
  • Open Serial Monitor on Arduino IDE
  • Arduino IDE Upload Code
  • Keep pressing the button several seconds and then release it.
  • See the result on Serial Monitor.
  • 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

Copy

const int BUTTON_PIN = 2;                                      // GIOP21 pin connected to button
const int DEBOUNCE_DELAY = 50;                                 // the debounce time; increase if the output flickers
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() {
   Serial.begin(9600);                                         // initialize serial communication at 9600 bits per second:
   pinMode(BUTTON_PIN, INPUT_PULLUP);                          // initialize the pushbutton pin as an pull-up input
}
void loop() {
   currentState = digitalRead(BUTTON_PIN);                     // read the state of the switch/button:
       // 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 (currentState != lastFlickerableState) {                 // If the switch/button changed, due to noise or pressing:                                               // the previous state from the input pin
       lastDebounceTime = millis();                            // reset the debouncing timer
       lastFlickerableState = currentState;                    // save the the last flickerable state
   }
   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");
       lastSteadyState = currentState;                         // save the the last steady state
   }
}                

Quick Steps

  • power up your board
  • Open Arduino IDE
  • Select the right board
  • Select the right port
  • Copy the above code and open with Arduino IDE
  • Click Upload button on Arduino IDE to upload code to ESP32
  • Arduino IDE Upload Code
  • Open Serial Monitor on Arduino IDE
  • Arduino IDE Upload Code
  • Keep pressing the button several seconds and then release it.
  • See the result on Serial Monitor.
  • 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.

Book Tutorial

We are considering to make the book tutorials. If you think the book tutorials are essential, you can download it. download book

References

※ NOTE THAT:

Some components works on 3.3v and others works on 5v!