Single Double Click and Long Press Detection

Solving Approach

How do you plan to solve it?

 Setup the push button input (with either INPUT_PULLUP or external resistor).

  1. Track button state changes:
    • Detect when the button is pressed and released.
    • Measure time duration between press and release.
  2. Define thresholds:
    • Single click to short press & release (e.g., < 500 ms).
    • Double click to two presses within a time window more or less 400ms apart.
    • Long press to  button held down beyond threshold 1000ms.
  3. Use millis() for timing instead of delay (non-blocking).
  4. Output result to the Serial Monitor.
     

 

 

 

Code

/*Paste your code here*/

const int buttonPin = 2;  

unsigned long lastDebounceTime = 0;
unsigned long debounceDelay = 50;
unsigned long lastClickTime = 0;
unsigned long pressStartTime = 0;

bool buttonState = HIGH;       // Current state of button
bool lastButtonState = HIGH;   // Previous state of button
int clickCount = 0;
bool longPressDetected = false;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP); // Use internal pull-up resistor
  Serial.begin(115200);
}

void loop() {
  int reading = digitalRead(buttonPin);

  // Debounce
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }

  if ((millis() - lastDebounceTime) > debounceDelay) {
    if (reading != buttonState) {
      buttonState = reading;

      // Button pressed
      if (buttonState == LOW) {
        pressStartTime = millis();
        longPressDetected = false;
      } 
      // Button released
      else {
        unsigned long pressDuration = millis() - pressStartTime;

        // Check for long press
        if (pressDuration >= 1000) {  
          Serial.println("Long press detected");
          longPressDetected = true;
          clickCount = 0;
        } else {
          clickCount++;
          if (clickCount == 1) {
            lastClickTime = millis();
          }
        }
      }
    }
  }

  // Single Click vs double click
  if (clickCount > 0 && !longPressDetected) {
    if ((millis() - lastClickTime) > 400) {  // 400 ms timeout for double click
      if (clickCount == 1) {
        Serial.println("Single click detected");
      } else if (clickCount == 2) {
        Serial.println("Double click detected");
      }
      clickCount = 0;
    }
  }

  lastButtonState = reading;
}

 

 

 

Output

Video

Add a video of the output (know more)

 

 

 

 

Upvote
Downvote

Submit Your Solution

Note: Once submitted, your solution goes public, helping others learn from your approach!