// DelayedLedButton -- blink a LED after a delay
// https://wokwi.com/projects/424083999010945025
// See more state-change detection examples at:
// https://forum.arduino.cc/t/wokwi-simulations-for-arduino-built-in-examples/1304754/14
//
// This sketch demonstrates state change detection on several things:
// inputs
// variables
// millis()-based timing variables
//
const int OnPin = 4;
const int LedPin = 12;
const uint32_t LedDelayTime = 1000, LedOnTime = 1000 ;
const bool DEBUG = true;
const uint32_t DebounceInterval = 10;
int lastButtonState;
uint32_t buttonChangeTime, buttonOnTime, timerStart;
enum LedStates {OFF, ARMED, ON} ledState = OFF, lastLedState = OFF;
void setup() {
Serial.begin(115200);
Serial.println(
R"(DelayedLedButton:
led goes on 1 second after button is pressed,
and led turns off 2 seconds after it was last pressed.
Serial monitor shows ledState:)");
pinMode(OnPin, INPUT_PULLUP);
pinMode(LedPin, OUTPUT);
}
void loop() {
// Input phase of https://en.wikipedia.org/wiki/IPO_model
uint32_t now = millis();
bool buttonOn = digitalRead(OnPin) == LOW;
// Processing phase of https://en.wikipedia.org/wiki/IPO_model
// Detect the button rising and falling events using
// state change detection and rate-limiting for debouncing:
if (buttonOn != lastButtonState && now - buttonChangeTime > DebounceInterval) { // change detection
buttonChangeTime = now;
if (buttonOn) {
buttonOnTime = millis();
ledState = ARMED;
if(DEBUG) Serial.print('v');
}
else
{
if(DEBUG) Serial.print("^");
}
lastButtonState = buttonOn;
}
// Manage the ledState according the state and the timers
switch (ledState) {
case OFF:
// do nothing
break;
case ARMED:
// state-change detection on timing threshold
if (now - buttonOnTime > LedDelayTime) {
ledState = ON;
timerStart = now; // record time for turning off
}
break;
case ON:
// state-change detection on timing threshold
if (now - timerStart > LedOnTime) {
ledState = OFF;
}
break;
}
// Output phase of https://en.wikipedia.org/wiki/IPO_model
// state change detection on ledState to update the LED pin only as needed
if (ledState != lastLedState) {
lastLedState = ledState;
if (ledState == ON) {
digitalWrite(LedPin, HIGH);
}
if (ledState == OFF) {
digitalWrite(LedPin, LOW);
}
}
// show the state changes on the serial monitor
report();
}
void report() {
// report on the state of the system
static int lastLedState = 0;
// state change detection on state variable to minimize output
if (ledState != lastLedState) {
lastLedState = ledState;
Serial.print(ledState);
}
}