Single Double Click and Long Press Detection

huntezmonstez
huntezmonstez

Solving Approach

How do you plan to solve it?

 
 

 

 

 

Code

/*Paste your code here*/
const int buttonPin = 18; // chọn chân nút bấm (đảm bảo sử dụng INPUT_PULLUP)
int buttonState = HIGH;  // trạng thái hiện tại của nút (với pull-up, HIGH khi không bấm)
int lastButtonState = HIGH;

unsigned long lastDebounceTime = 0;
const unsigned long debounceDelay = 50; // thời gian debounce

unsigned long pressStartTime = 0; // thời điểm nút được nhấn xuống
unsigned long lastReleaseTime = 0; // thời điểm nút được nhả (để so sánh khoảng cách giữa 2 lần nhấn)

bool waitingForSecondPress = false;

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(115200);
}

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

  // Debounce: nếu trạng thái thay đổi, cập nhật thời gian debounce
  if (reading != lastButtonState) {
    lastDebounceTime = millis();
  }
  
  // Nếu đã ổn định sau debounce
  if ((millis() - lastDebounceTime) > debounceDelay) {
    // Kiểm tra sự thay đổi của nút
    if (reading != buttonState) {
      buttonState = reading;
      
      // Khi nút được nhấn xuống
      if (buttonState == LOW) {
        pressStartTime = millis();
      }
      
      // Khi nút được nhả ra
      else { // buttonState == HIGH
        unsigned long pressDuration = millis() - pressStartTime;
        
        // Kiểm tra long press
        if (pressDuration >= 1000) {
          Serial.println("Long press detected");
          waitingForSecondPress = false; // hủy bỏ đợi lần nhấn thứ 2
        }
        else { // Đây là một lần nhấn ngắn
          if (waitingForSecondPress) {
            // Nếu khoảng cách giữa 2 lần nhấn ≤ 400ms, nhận là double press
            if ((millis() - lastReleaseTime) <= 400) {
              Serial.println("Double press detected");
              waitingForSecondPress = false;
            }
            // Nếu quá thời gian cho phép, xử lý lần nhấn trước là single
            else {
              Serial.println("Single press detected");
              // Bắt đầu đợi lần nhấn mới (nếu có)
              waitingForSecondPress = true;
            }
          }
          else {
            // Đây là lần nhấn đầu tiên, bắt đầu đợi lần nhấn thứ 2
            waitingForSecondPress = true;
          }
          // Cập nhật thời điểm nhả nút
          lastReleaseTime = millis();
        }
      }
    }
  }
  
  // Nếu đang chờ lần nhấn thứ 2 mà đã hết thời gian (400ms) thì xử lý lần nhấn đầu là single press
  if (waitingForSecondPress && (millis() - lastReleaseTime) > 400 && buttonState == HIGH) {
    Serial.println("Single press detected");
    waitingForSecondPress = false;
  }
  
  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!