1. Hardware Setup:
Connect a push button to a GPIO pin (say pin 2) with a pull-down or internal pull-up resistor.
The button will send a HIGH signal when pressed.
2. Logic:
Measure the time between button press and release.
If button is pressed and released quickly → single click.
If two presses occur within a short time interval (say < 400 ms) → double click.
If button is held down for a long duration (say > 1 second) → long press.
3. Implementation Steps:
Use millis() to track press timings.
Use simple state tracking (pressed, released) to detect different cases.
const int buttonPin = 2; // GPIO pin for button
unsigned long lastPressTime = 0;
unsigned long pressDuration = 0;
unsigned long lastReleaseTime = 0;
bool buttonState = LOW;
bool lastButtonState = LOW;
int pressCount = 0;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // use internal pull-up resistor
Serial.begin(115200);
}
void loop() {
buttonState = digitalRead(buttonPin);
// Detect press
if (buttonState == LOW && lastButtonState == HIGH) {
lastPressTime = millis();
}
// Detect release
if (buttonState == HIGH && lastButtonState == LOW) {
pressDuration = millis() - lastPressTime;
lastReleaseTime = millis();
pressCount++;
}
// Long press detection
if (buttonState == LOW && (millis() - lastPressTime > 1000)) {
Serial.println("Long press detected");
// Prevent multiple triggers
while (digitalRead(buttonPin) == LOW);
pressCount = 0;
}
// Single or Double click detection
if (pressCount == 1 && (millis() - lastReleaseTime > 400)) {
Serial.println("Single click detected");
pressCount = 0;
}
else if (pressCount == 2) {
Serial.println("Double click detected");
pressCount = 0;
}
lastButtonState = buttonState;
}
"Single click detected"
"Double click detected"
"Long press detected"