// https://www.instructables.com/Arduino-Dual-Function-Button-Long-PressShort-Press/
// https://esp32io.com/tutorials/esp32-button-long-press-short-press
int LED_PIN = 16; // LED引脚
int RELAY_PIN = 4; // 继电器引脚
int BUTTON_PIN = 5; // 物理按钮引脚
boolean ledState = false; // LED初始状态
boolean relayState = false; // 设备初始状态
unsigned long buttonTimer = 0; // 按下按键时的时间戳
unsigned long debounceTime = 30; // 按键消抖时间
unsigned long longPressTime = 1000; // 长按所需要时间, 达到这个时间才识别为长按
boolean buttonActive = false; // 是否按下按键
boolean longPressActive = false; // 是否长按按键
void IRAM_ATTR interruptHandler() {
//detachInterrupt(digitalPinToInterrupt(BUTTON_PIN));
checkSwitch();
//attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), interruptHandler, CHANGE);
}
void checkSwitch() {
static unsigned long lastInterruptTime = 0;
if ((millis() - lastInterruptTime) > debounceTime) {
// 按下按键, 低电平
if (digitalRead(BUTTON_PIN) == LOW) {
if (buttonActive == false) {
buttonActive = true;
buttonTimer = millis();
}
// 长按事件触发
if ((millis() - buttonTimer > longPressTime) && (longPressActive == false)) {
longPressActive = true;
relayState = !relayState;
digitalWrite(RELAY_PIN, relayState);
Serial.println("A long press is detected");
}
}
// 松开按键, 高电平
else {
if (buttonActive == true) {
// 长按松开
if (longPressActive == true) {
longPressActive = false;
}
// 非长按松开, 短按事件触发
else {
ledState = !ledState;
digitalWrite(LED_PIN, ledState);
Serial.println("A short press is detected");
}
buttonActive = false;
}
}
lastInterruptTime = millis();
}
}
void setup() {
Serial.begin(9600);
pinMode(LED_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP);
digitalWrite(LED_PIN, ledState ? HIGH : LOW);
digitalWrite(RELAY_PIN, relayState ? HIGH : LOW);
//attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), interruptHandler, CHANGE);
Serial.println("Beginning...");
}
void loop() {
checkSwitch();
}