Arduino Nano ESP32 - Button - Debounce
When a button is pressed/released or when a switch is toggled between ON and OFF, its state is changed from LOW to HIGH ( or HIGH to LOW) once. Is this correct?
⇒ No, it is not. That is because in the physical world. when you do a single press on a button, the state of the button is quickly toggled between LOW and HIGH several times rather than once. This is the mechanical and physical characteristic. This phenomenon is known with a name: chattering. The chattering phenomenon makes MCU (e.g. ESP32) read multiple button presses in response to a single actual press. This results in a malfunction. The process to eliminate this phenomenon is called debounce. This tutorial shows how to do it.
This tutorial provides:
How to debounce for a button on Arduino Nano ESP32 code
How to debounce for a button on Arduino Nano ESP32 code using library
How to debounce for multiple buttons on Arduino Nano ESP32 code using library
Or you can buy the following sensor kits:
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.
Additionally, some of these links are for products from our own brand, DIYables.
We have specific tutorials about button. The tutorial contains detailed information and step-by-step instructions about hardware pinout, working principle, wiring connection to ESP32, Arduino Nano ESP32 code... Learn more about them at the following links:
This image is created using Fritzing. Click to enlarge image
To make it clear, let's run Arduino Nano ESP32 code WITHOUT and WITH debounce, and compare their results
To get started with Arduino Nano ESP32, follow these steps:
Wire the components according to the provided diagram.
Connect the Arduino Nano ESP32 board to your computer using a USB cable.
Launch the Arduino IDE on your computer.
Select the Arduino Nano ESP32 board and its corresponding COM port.* Copy the below code and paste it to Arduino IDE.
#define BUTTON_PIN D2
int prev_state = LOW;
int button_state;
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
button_state = digitalRead(BUTTON_PIN);
if (prev_state == HIGH && button_state == LOW)
Serial.println("The button is pressed");
else if (prev_state == LOW && button_state == HIGH)
Serial.println("The button is released");
prev_state = button_state;
}
Press the button once but keep it several seconds, and then release it.
Check out the result on the Serial Monitor. It looks like the below:
The button is pressed
The button is pressed
The button is pressed
The button is released
The button is released
⇒ As you can see, you did only a single press and release, but Arduino Nano ESP32 read multiple presses and releases.
※ NOTE THAT:
The chattering phenomenon does not happen all times. If it does not happen, please try the above test several time.
#define BUTTON_PIN D2
#define DEBOUNCE_TIME 50
int prev_state_steady = LOW;
int prev_state_flick = LOW;
int button_state;
unsigned long last_debounce_time = 0;
void setup() {
Serial.begin(9600);
pinMode(BUTTON_PIN, INPUT_PULLUP);
}
void loop() {
button_state = digitalRead(BUTTON_PIN);
if (button_state != prev_state_flick) {
last_debounce_time = millis();
prev_state_flick = button_state;
}
if ((millis() - last_debounce_time) > DEBOUNCE_TIME) {
if(prev_state_steady == HIGH && button_state == LOW)
Serial.println("The button is pressed");
else if(prev_state_steady == LOW && button_state == HIGH)
Serial.println("The button is released");
prev_state_steady = button_state;
}
}
Compile and upload code to Arduino Nano ESP32 board by clicking Upload button on Arduino IDE
Open Serial Monitor on Arduino IDE
Keep pressing the button several seconds and then release it.
Check out the result on the Serial Monitor. It looks like the below:
The button is pressed
The button is released
⇒ As you can see, you did one press and release, and Arduino Nano ESP32 read one press and release. The chattering is eliminated.
To make it easy for newbies, especially when deboucing for multiple buttons, we made a button library, called ezButton. You can learn about ezButton library here.
#include <ezButton.h>
#define DEBOUNCE_TIME 50
ezButton button(D2);
void setup() {
Serial.begin(9600);
button.setDebounceTime(DEBOUNCE_TIME);
}
void loop() {
button.loop();
if (button.isPressed())
Serial.println("The button is pressed");
if (button.isReleased())
Serial.println("The button is released");
}
Let's write debounce code for three buttons.
This image is created using Fritzing. Click to enlarge image
#include <ezButton.h>
#define DEBOUNCE_TIME 50
ezButton button1(D6);
ezButton button2(D7);
ezButton button3(D8);
void setup() {
Serial.begin(9600);
button1.setDebounceTime(DEBOUNCE_TIME);
button2.setDebounceTime(DEBOUNCE_TIME);
button3.setDebounceTime(DEBOUNCE_TIME);
}
void loop() {
button1.loop();
button2.loop();
button3.loop();
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");
}
DEBOUNCE_TIME value depends on the hardware. Different hardware may use different values.
The debounce should also apply for on/off switch, limit switch, reed switch, touch sensor ...