How do you plan to solve it?
I will connect a button to a microcontroller pin and write code that measures how long the button is pressed and the time between presses to tell the difference between a single click, a double click, and a long press, then print each one to the serial monitor.
// Pin Definitions
const int buttonPin = 2; // The button is on Pin 2
// Timing Constants (Milliseconds)
const unsigned long DEBOUNCE_TIME = 50; // Ignore tiny button jitters
const unsigned long LONG_PRESS_TIME = 500; // Hold for 0.5s for Long Press
const unsigned long MAX_DOUBLE_CLICK_TIME = 250; // Max time between two clicks
// State Variables
int buttonState = HIGH;
int lastButtonState = HIGH;
unsigned long lastDebounceTime = 0;
unsigned long pressStartTime = 0;
bool waitForRelease = false;
bool singleClickRegistered = false;
void setup() {
pinMode(buttonPin, INPUT_PULLUP); // Crucial: use internal pull-up
Serial.begin(9600); // Start communication
Serial.println("Ready! Press the button.");
}
void loop() {
unsigned long currentTime = millis(); // Get the current time
int reading = digitalRead(buttonPin); // Read the button
// DEBOUNCE: If the reading changed, reset the debounce timer
if (reading != lastButtonState) {
lastDebounceTime = currentTime;
}
lastButtonState = reading; // Save the reading for next time
// Only proceed if the reading has been stable for DEBOUNCE_TIME
if ((currentTime - lastDebounceTime) > DEBOUNCE_TIME) {
// If the stable reading is different from our saved state...
if (reading != buttonState) {
buttonState = reading; // Update the stable state
// Button was PRESSED (went from HIGH to LOW)
if (buttonState == LOW) {
pressStartTime = currentTime; // Record the start time of the press
Serial.println("Button pressed (start timing)");
// If we were already waiting for a 2nd click, this is a DOUBLE CLICK!
if (waitForRelease) {
Serial.println(">> DOUBLE CLICK");
waitForRelease = false;
singleClickRegistered = true;
}
}
// Button was RELEASED (went from LOW to HIGH)
else {
unsigned long pressDuration = currentTime - pressStartTime;
Serial.print("Button released. Held for: "); Serial.println(pressDuration);
// Was it a short press? And not part of a double click?
if (pressDuration < LONG_PRESS_TIME && !singleClickRegistered) {
waitForRelease = true; // It might be a single click, wait for double
lastDebounceTime = currentTime; // Reset the double-click timer
Serial.println("Waiting to see if double-click...");
}
// Was it a long press?
else if (pressDuration >= LONG_PRESS_TIME) {
Serial.println(">> LONG PRESS");
waitForRelease = false;
}
singleClickRegistered = false; // Reset the double-click flag
}
}
}
// If we're waiting for a double-click and the time runs out, it's a SINGLE CLICK
if (waitForRelease && (currentTime - lastDebounceTime) > MAX_DOUBLE_CLICK_TIME) {
Serial.println(">> SINGLE CLICK");
waitForRelease = false;
}
}
https://wokwi.com/projects/442621117817103361