All submissions

Single Double Click and Long Press Detection

Solving Approach

How do you plan to solve it?

 
 1.Connect the push button in center of the bread board
2.Connect one terminal of the push button to digital pin 2

3.Connect the diagonal terminal of the push button to GND

upload the code below and observe the output.

 

 

 

Code

//Coding done by using AI tool
// Define the pin where the push-button switch is connected
const int buttonPin = 2; // You can change this to any digital pin

// Variables for button state and timing
int buttonState;             // Current state of the button
int lastButtonState = HIGH;  // Previous state of the button
unsigned long lastDebounceTime = 0; // The last time the button input was toggled
unsigned long debounceDelay = 50;   // Debounce time in milliseconds
unsigned long lastClickTime = 0;    // The last time a click was detected
unsigned long doubleClickTime = 300; // Maximum time between clicks for a double click
unsigned long longPressTime = 1000;  // Minimum time for a long press in milliseconds
bool buttonPressed = false;      // True if the button is currently pressed
bool singleClickProcessed = false; // Flag to ensure single click is processed once per release

void setup() {
  pinMode(buttonPin, INPUT_PULLUP); // Use INPUT_PULLUP for internal pull-up resistor
  Serial.begin(115200);             // Initialize serial communication
  delay(1000); // Add a delay here (e.g., 1 to 2 seconds)
}

void loop() {
  // Read the state of the button
  int reading = digitalRead(buttonPin);

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

  if ((millis() - lastDebounceTime) > debounceDelay) {
    // If the button state has changed for longer than the debounce delay
    if (reading != buttonState) {
      buttonState = reading;

      // Button is pressed (LOW because of INPUT_PULLUP)
      if (buttonState == LOW) {
        lastClickTime = millis(); // Record the time when the button was pressed
        buttonPressed = true;
        singleClickProcessed = false; // Reset for new click detection
      }
      // Button is released (HIGH)
      else {
        if (buttonPressed) {
          unsigned long pressDuration = millis() - lastClickTime;

          // Check for long press
          if (pressDuration >= longPressTime) {
            Serial.println("Long press detected");
          }
          // Check for double click or single click
          else {
            // Check if it's within the double click window
            if ((millis() - lastClickTime) < doubleClickTime) {
              // This is a potential double click. We need to wait a bit more
              // to confirm if it's not a single click followed by nothing.
              // For simplicity, we'll detect a double click on the *second* press
              // if it occurs within the doubleClickTime.
              // A more robust solution might involve a state machine or a timer
              // to truly differentiate between single and double clicks.
            }
          }
          buttonPressed = false; // Button is no longer pressed
        }
      }
    }
  }

  // Detect single click after release, ensuring it's not a double click's first click
  // and hasn't been part of a long press.
  if (buttonState == HIGH && lastButtonState == LOW && !singleClickProcessed) {
    unsigned long releasedDuration = millis() - lastClickTime;
    if (releasedDuration < longPressTime && releasedDuration > debounceDelay) { // Ensure it's a short press
      // If no double click has occurred within the window for the *current* release
      if (millis() - lastClickTime > doubleClickTime) { // This is a simplified check for single click after release
                                                      // to avoid immediate single click reporting before double click window expires.
        Serial.println("Single click detected");
        singleClickProcessed = true; // Mark as processed
      } else {
        // If within double click window, check if it's the second click
        // This part is tricky for simultaneous single/double click detection.
        // The most common approach is to wait for doubleClickTime after a potential single click
        // before declaring it a single click, allowing for a second click to register as double.
        // For now, we'll just check if a quick press was followed by another quick press.
        static unsigned long lastPotentialSingleClick = 0;
        if (millis() - lastPotentialSingleClick < doubleClickTime && lastPotentialSingleClick != 0) {
            Serial.println("Double click detected");
            singleClickProcessed = true; // Mark as processed
            lastPotentialSingleClick = 0; // Reset for next sequence
        } else {
            lastPotentialSingleClick = millis(); // Store for potential second click
        }
      }
    }
  }

  // Update the last button state for the next iteration
  lastButtonState = reading;
}

 

 

 

Output

Video

Add a video of the output (know more)

 

 

 

 

Submit Your Solution

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