// https://forum.arduino.cc/t/timed-response-after-release/964154
https://wokwi.com/projects/368902020106599425
// version 2. remove crude debouncing, put actionStarted flag in more obvious place
int soundSensor = 2;
// several tweaks because I use a button not a sound sensor
int buttonState = 0;
int lastButtonState = 0;
const int debouncePeriod = 33;
const unsigned long actionDelayPeriod = 5000; //serial print action 5 seconds for testing - life too short
unsigned long myDebounceTimer;
unsigned long myActionTimer;
void setup() {
Serial.begin(115200);
Serial.println("\nWake up!\n");
pinMode (soundSensor, INPUT_PULLUP); // for proxy pushbutton here
}
void loop() {
static bool actionStarted = true; // intial condition
int buttonState = !digitalRead(soundSensor); // button upside down
// compare the buttonState to its previous state
if (buttonState != lastButtonState) {
// when the state has CHANGED
// check if button-state change is bouncing or not
if ( TimePeriodIsOver(myDebounceTimer,debouncePeriod) ) {
// when button is not bouncing
if (buttonState == HIGH) { // if high, this means button pressed dowb
// if the current state is HIGH then the button went from off to on:
Serial.println("button pressed down");
actionStarted = false; // reset the action-flag to false
}
else { // button is released
Serial.println("button released");
}
lastButtonState = buttonState; // update variable lastButtonState
}
}
// when the button is pressed, set timer-variable to actual time (= resets the timer)
if (buttonState == HIGH) {
myActionTimer = millis();
actionStarted = false; // reset the actionStarted-flag to false
// trust or verify Serial.println(" reset timer");
}
// check if delay-time is over and action is not started
if (TimePeriodIsOver(myActionTimer,actionDelayPeriod) && !actionStarted) {
Serial.println(" Do something!");
actionStarted = true;
}
}
// easy to use helper-function for non-blocking timing
boolean TimePeriodIsOver (unsigned long &startOfPeriod, unsigned long TimePeriod) {
unsigned long currentMillis = millis();
if ( currentMillis - startOfPeriod >= TimePeriod ) {
// more time than TimePeriod has elapsed since last time if-condition was true
startOfPeriod = currentMillis; // a new period starts right here so set new starttime
return true;
}
else return false; // actual TimePeriod is NOT yet over
}