const uint8_t ledPin = 13 ;
const uint8_t button_switch = 2; // external interrupt pin
const unsigned long debounceDelay = 100 ; // the debounce time; increase if the output flickers
enum ButtonState { PENDING_PRESS, IN_PRESS, PENDING_RELEASE} ;
ButtonState buttonState = ButtonState::PENDING_PRESS ;
uint32_t stateEnteredAtMs = millis() ;
void setup() {
Serial.begin(115200);
pinMode( ledPin, OUTPUT) ;
pinMode( button_switch, INPUT_PULLUP) ;
}
void loop() {
uint32_t ms = millis() ;
static uint32_t lastButtonCheckAtMs = 0 ;
if( ms - lastButtonCheckAtMs > 10 ) {
switch ( buttonState ) {
case ButtonState::PENDING_PRESS : {
if ( digitalRead(button_switch) == LOW ) {
buttonState = ButtonState::IN_PRESS ;
stateEnteredAtMs = ms ;
}
break ;
}
case ButtonState::IN_PRESS : {
if ( digitalRead(button_switch) == HIGH ) {
if ( ms - stateEnteredAtMs < debounceDelay ) {
stateEnteredAtMs = ms ;
buttonState = ButtonState::PENDING_PRESS ;
}
else {
stateEnteredAtMs = ms ;
buttonState = ButtonState::PENDING_RELEASE ;
digitalWrite( ledPin, ! digitalRead(ledPin)) ; // toggle led
}
}
break ;
}
case ButtonState::PENDING_RELEASE : {
if ( ms - stateEnteredAtMs > debounceDelay ) {
stateEnteredAtMs = ms ;
buttonState = ButtonState::PENDING_PRESS ;
}
break ;
}
}
lastButtonCheckAtMs = ms ;
}
}