const int LED_PIN = 16;
const int RELAY_PIN = 4; // 继电器引脚, GPIO/0, GPIO/1(TX), GPIO/2(LED), GPIO/3(RX)
const int BUTTON_PIN = 5; // 物理按钮引脚
bool relayState = false; // 设备初始状态
unsigned long lastMillis = 0;
unsigned long lastInterruptTime = 0;
unsigned long longPressTime = 1000;
unsigned long debounceTime = 110;
void IRAM_ATTR buttonPressHandler();
void IRAM_ATTR buttonReleaseHandler();
/**
* Interrupt Service Routine (ISR)
*
* 按下按键, 引脚从高电平变为低电平(FALLING)
*/
void IRAM_ATTR buttonPressHandler() {
detachInterrupt(digitalPinToInterrupt(BUTTON_PIN));
unsigned long interruptTime = millis();
unsigned long timeDiff;
timeDiff = interruptTime - lastInterruptTime;
// If interrupts come faster than 100ms, assume it's a bounce and ignore
if (timeDiff > debounceTime) {
lastInterruptTime = interruptTime;
}
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonReleaseHandler, RISING);
}
/**
* Interrupt Service Routine (ISR)
*
* 松开按键, 引脚从低电平变为高电平(RISING)
*/
void IRAM_ATTR buttonReleaseHandler() {
detachInterrupt(digitalPinToInterrupt(BUTTON_PIN));
unsigned long interruptTime = millis();
unsigned long timeDiff;
timeDiff = interruptTime - lastInterruptTime;
// 小于100ms, 判断为抖动, 忽略
if (timeDiff > debounceTime) {
// 长按
if ( timeDiff >= longPressTime ) {
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
}
// 短按
else {
switchRelay(false);
//digitalWrite(RELAY_PIN, !digitalRead(RELAY_PIN));
}
lastInterruptTime = interruptTime;
}
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonPressHandler, FALLING);
}
/**
* 切换继电器状态
*/
void switchRelay(bool publish) {
relayState = !relayState;
digitalWrite(RELAY_PIN, relayState);
}
void setup() {
Serial.begin(9600);
//Serial.setDebugOutput(false);
delay(100); // Wait for serial port
pinMode(LED_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(BUTTON_PIN, INPUT_PULLUP); // 设置物理按键引脚
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonPressHandler, FALLING); // 设置中断
digitalWrite(RELAY_PIN, relayState);
Serial.println("Beginning...");
}
void loop() {
delay(100);
Serial.println(relayState);
}