// note the simulation speed is about one third of real time
// adjust timings if using on real hardware.
const int buttonPin = 5;
unsigned long inStateAtMs = millis() ;
int buttonState ; // 0 = waiting for press, 1= waiting for release 2= differentiate single or double 3= wait button release (double)
void setup() {
pinMode(buttonPin, INPUT_PULLUP);
Serial.begin(9600);
}
void loop() {
if ( buttonState == 0 ) {
// wait for button press
if ( millis() - inStateAtMs > 100 ) {
if (!digitalRead(buttonPin)) {
buttonState = 1 ;
inStateAtMs = millis();
}
}
}
else if ( buttonState == 1 ) {
// wait for stable button release 1
if ( millis() - inStateAtMs > 100 && digitalRead(buttonPin) ) {
buttonState = 2 ;
inStateAtMs = millis();
}
}
else if ( buttonState == 2 ) {
// differentiate between single and double press
if ( millis() - inStateAtMs > 400 ) {
// timeout - is a single press
Serial.println("single");
buttonState = 0 ;
inStateAtMs = millis() ;
}
else if ( ( ! digitalRead(buttonPin) ) && (millis() - inStateAtMs > 100 ) ) {
// got second press within timeout - double
Serial.println("double");
buttonState = 3 ;
inStateAtMs = millis() ;
}
}
else if ( buttonState == 3 ) {
// wait for stable button release 2
if ( millis() - inStateAtMs > 100 && digitalRead(buttonPin) ) {
buttonState = 0 ;
inStateAtMs = millis();
}
}
}