ESP32 - Button - Long Press Short Press
We are going to learn how to:
-
How to detect the button's short press
-
How to detect the button's long press
-
How to detect both the button's long press and short press
-
Long press and short press with debouncing
In the first three parts, we learn how to detect in principle.
In the last part, we learn how to detect in practical use by applying the debounce. See why do we need to debounce for button.Without debouncing, we may detect wrong the button short press.
Video Tutorial
you can watch this video tutorial
Hardware Required
1 | × | ESP-WROOM-32 Dev Module | |
1 | × | Micro USB Cable | |
1 | × | Button | |
1 | × | Breadboard | |
n | × | Jumbers |
Wiring Diagram
Breadboard Connections
In this tutorial, we will use the internal pull-up resistor. Therefore, the state of the button is HIGH when normal and LOW when pressed.
How To Detect Short Press
We measure the time duration between the pressed and released events. If the duration is shorter than a defined time, the short press event is detected.
Let's see step by step:
-
Define how long the maximum of short press lasts
const int SHORT_PRESS_TIME = 500; // 500 milliseconds
if(lastState == HIGH && currentState == LOW) pressedTime = millis();
if(lastState == LOW && currentState == HIGH) releasedTime = millis();
long pressDuration = releasedTime - pressedTime;
if( pressDuration < SHORT_PRESS_TIME ) Serial.println("A short press is detected");
ESP32 Code for detecting the short press
const int BUTTON_PIN = 2; // GIOP2 pin connected to button const int SHORT_PRESS_TIME = 500; // 500 milliseconds int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin unsigned long pressedTime = 0; unsigned long releasedTime = 0; void setup() { Serial.begin(9600); pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { currentState = digitalRead(BUTTON_PIN); // read the state of the switch/button: if(lastState == HIGH && currentState == LOW) // button is pressed pressedTime = millis(); else if(lastState == LOW && currentState == HIGH) { // button is released releasedTime = millis(); long pressDuration = releasedTime - pressedTime; if( pressDuration < SHORT_PRESS_TIME ) Serial.println("A short press is detected"); } lastState = currentState; // save the the last state }
Quick Steps
- Open Arduino IDE
- Select the right board and port
- Copy the above code and open with Arduino IDE
- Click Upload button on Arduino IDE to upload code to ESP32
- Press the button shortly several times.
- See the result on Serial Monitor.
※ NOTE THAT:
The Serial Monitor may show several short press detection for one press. This is the normal behavior of the button. This behavior is called the “chattering phenomenon”. The issue will be solved in the last part of this tutorial.
How To Detect Long Press
There are two use cases for detecting the long press.
-
The long-press event is detected right after the button is released
-
The long-press event is detected during the time the button is being pressed, even the button is not released yet.
In the first use case, We measure the time duration between the pressed and released events. If the duration is longer than a defined time, the long-press event is detected.
In the second use case, After the button is pressed, We continuously measure the pressing time and check the long-press event until the button is released. During the time button is being pressed. If the duration is longer than a defined time, the long-press event is detected.
ESP32 Code for detecting long press when released
const int BUTTON_PIN = 21; // GIOP21 pin connected to button const int LONG_PRESS_TIME = 1000; // 1000 milliseconds int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin unsigned long pressedTime = 0; unsigned long releasedTime = 0; void setup() { Serial.begin(9600); pinMode(BUTTON_PIN, INPUT_PULLUP); pinMode(15, OUTPUT); } void loop() { currentState = digitalRead(BUTTON_PIN); // read the state of the switch/button: if(lastState == HIGH && currentState == LOW) // button is pressed pressedTime = millis(); else if(lastState == LOW && currentState == HIGH) { // button is released releasedTime = millis(); long pressDuration = releasedTime - pressedTime; if( pressDuration > LONG_PRESS_TIME ) Serial.println("A long press is detected"); } lastState = currentState; // save the the last state }
Quick Steps
- Open Arduino IDE
- Select the right board and port
- Copy the above code and open with Arduino IDE
- Click Upload button on Arduino IDE to upload code to ESP32
- Press and release the button after one second.
- See the result on Serial Monitor.
The long-press event is only detected right after the button is released
ESP32 Code for detecting long press during pressing
const int BUTTON_PIN = 21; // GIOP21 pin connected to button const int LONG_PRESS_TIME = 1000; // 1000 milliseconds int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin unsigned long pressedTime = 0; bool isPressing = false; bool isLongDetected = false; void setup() { Serial.begin(9600); pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { currentState = digitalRead(BUTTON_PIN); // read the state of the switch/button: if(lastState == HIGH && currentState == LOW) { // button is pressed pressedTime = millis(); isPressing = true; isLongDetected = false; } else if(lastState == LOW && currentState == HIGH) { // button is released isPressing = false; } if(isPressing == true && isLongDetected == false) { long pressDuration = millis() - pressedTime; if( pressDuration > LONG_PRESS_TIME ) { Serial.println("A long press is detected"); isLongDetected = true; } } lastState = currentState; // save the the last state }
Quick Steps
- Open Arduino IDE
- Select the right board and port
- Copy the above code and open with Arduino IDE
- Click Upload button on Arduino IDE to upload code to ESP32
- Press and release the button after one second.
- See the result on Serial Monitor.
The long-press event is only detected when the button is not released yet
How To Detect Both Long Press and Short Press
Short Press and Long Press after released
const int BUTTON_PIN = 21; // GIOP21 pin connected to button const int SHORT_PRESS_TIME = 1000; // 1000 milliseconds const int LONG_PRESS_TIME = 1000; // 1000 milliseconds int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin unsigned long pressedTime = 0; unsigned long releasedTime = 0; void setup() { Serial.begin(9600); pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { currentState = digitalRead(BUTTON_PIN); // read the state of the switch/button: if(lastState == HIGH && currentState == LOW) // button is pressed pressedTime = millis(); else if(lastState == LOW && currentState == HIGH) { // button is released releasedTime = millis(); long pressDuration = releasedTime - pressedTime; if( pressDuration < SHORT_PRESS_TIME ) Serial.println("A short press is detected"); if( pressDuration > LONG_PRESS_TIME ) Serial.println("A long press is detected"); } lastState = currentState; // save the the last state }
Quick Steps
- Open Arduino IDE
- Select the right board and port
- Copy the above code and open with Arduino IDE
- Click Upload button on Arduino IDE to upload code to ESP32
- Long and short press the button.
- See the result on Serial Monitor.
※ NOTE THAT:
The Serial Monitor may show several short press detection for one press. This is the normal behavior of the button. This behavior is called the “chattering phenomenon”. The issue will be solved in the last part of this tutorial.
Short Press and Long Press During pressing
const int BUTTON_PIN = 21; // GIOP21 pin connected to button const int SHORT_PRESS_TIME = 1000; // 1000 milliseconds const int LONG_PRESS_TIME = 1000; // 1000 milliseconds int lastState = LOW; // the previous state from the input pin int currentState; // the current reading from the input pin unsigned long pressedTime = 0; unsigned long releasedTime = 0; bool isPressing = false; bool isLongDetected = false; void setup() { Serial.begin(9600); pinMode(BUTTON_PIN, INPUT_PULLUP); } void loop() { currentState = digitalRead(BUTTON_PIN); // read the state of the switch/button: if(lastState == HIGH && currentState == LOW) { // button is pressed pressedTime = millis(); isPressing = true; isLongDetected = false; } else if(lastState == LOW && currentState == HIGH) { // button is released isPressing = false; releasedTime = millis(); long pressDuration = releasedTime - pressedTime; if( pressDuration < SHORT_PRESS_TIME ) Serial.println("A short press is detected"); } if(isPressing == true && isLongDetected == false) { long pressDuration = millis() - pressedTime; if( pressDuration > LONG_PRESS_TIME ) { Serial.println("A long press is detected"); isLongDetected = true; } } lastState = currentState; // save the the last state }
Quick Steps
- Open Arduino IDE
- Select the right board and port
- Copy the above code and open with Arduino IDE
- Click Upload button on Arduino IDE to upload code to ESP32
- Press and release the button after one second.
- See the result on Serial Monitor.
※ NOTE THAT:
The Serial Monitor may show several short press detection for one press. This is the normal behavior of the button. This behavior is called the “chattering phenomenon”. The issue will be solved in the last part of this tutorial.
Long Press and Short Press with Debouncing
It is very important to debounce the button in many applications.
Debouncing is a little complicated, especially when using multiple buttons. To make it much easier for beginners, we created a library, called ezButton.
We will use this library in below codes
Short Press and Long Press with debouncing after released
#include <ezButton.h> const int SHORT_PRESS_TIME = 1000; // 1000 milliseconds const int LONG_PRESS_TIME = 1000; // 1000 milliseconds ezButton button(21); // create ezButton object that attach to pin GIOP21 unsigned long pressedTime = 0; unsigned long releasedTime = 0; 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()) pressedTime = millis(); if(button.isReleased()) { releasedTime = millis(); long pressDuration = releasedTime - pressedTime; if( pressDuration < SHORT_PRESS_TIME ) Serial.println("A short press is detected"); if( pressDuration > LONG_PRESS_TIME ) Serial.println("A long press is detected"); } }
Quick Steps
- Open Arduino IDE
- Select the right board and port
- Copy the above code and open with Arduino IDE
- Click Upload button on Arduino IDE to upload code to ESP32
- Long and short press the button.
- See the result on Serial Monitor.
※ NOTE THAT:
The Serial Monitor may show several short press detection for one press. This is the normal behavior of the button. This behavior is called the “chattering phenomenon”. The issue will be solved in the last part of this tutorial.
Short Press and Long Press with debouncing During Pressing
#include <ezButton.h> const int SHORT_PRESS_TIME = 1000; // 1000 milliseconds const int LONG_PRESS_TIME = 1000; // 1000 milliseconds ezButton button(21); // create ezButton object that attach to pin GIOP21 unsigned long pressedTime = 0; unsigned long releasedTime = 0; bool isPressing = false; bool isLongDetected = false; 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()){ pressedTime = millis(); isPressing = true; isLongDetected = false; } if(button.isReleased()) { isPressing = false; releasedTime = millis(); long pressDuration = releasedTime - pressedTime; if( pressDuration < SHORT_PRESS_TIME ) Serial.println("A short press is detected"); } if(isPressing == true && isLongDetected == false) { long pressDuration = millis() - pressedTime; if( pressDuration > LONG_PRESS_TIME ) { Serial.println("A long press is detected"); isLongDetected = true; } } }
Quick Steps
- Open Arduino IDE
- Select the right board and port
- Copy the above code and open with Arduino IDE
- Click Upload button on Arduino IDE to upload code to ESP32
- Press and release the button after one second.
- See the result on Serial Monitor.
※ NOTE THAT:
The Serial Monitor may show several short press detection for one press. This is the normal behavior of the button. This behavior is called the “chattering phenomenon”. The issue will be solved in the last part of this tutorial.
Why Needs Long Press and Short Press
-
To save the number of buttons. A single button can keep two or more functionalities. For example, short press for changing operation mode, long press for turn off the device.
-
Use of long press to reduce the short press by accident. For example, some kinds of devices use the button for factory reset. If the button is pressed by accident, it is dangerous. To avoid it, the device is implemented to be factory reset only when the button is long-press (e.g over 5 seconds).
Book Tutorial
We are considering to make the book tutorials. If you think the book tutorials are essential, you can download it. download book
See Also
References
※ NOTE THAT:
Some components works on 3.3v and others works on 5v!