// Button management library
#include <Toggle.h>
const byte buttonPin = 4; // Our button is on pin 4
Toggle button;
// Pins used for LEDs
const byte pinRedLed = 8;
const byte pinOrangeLed = 9;
const byte pinYellowLed = 10;
const byte pinGreenLed = 11;
// Introducing time as an additional event
unsigned long chrono; // Note: unsigned long, like millis()
const unsigned long TimeOut = 15000ul; // 15 seconds (ul at the end for unsigned long, a good habit to adopt)
// The list of possible states of our system
// along with a currentState variable taking one of these values
enum {REST, STATE_G, STATE_GY, STATE_GYO, STATE_GYOR} currentState;
void turnLedsOff() {
digitalWrite(pinGreenLed, LOW);
digitalWrite(pinYellowLed, LOW);
digitalWrite(pinOrangeLed, LOW);
digitalWrite(pinRedLed, LOW);
}
void runStateMachine() {
button.poll(); // update the state of the button
// TEST FOR CLICK
switch (currentState) {
case REST: // we are at rest and if we get a click, turn on the green LED
if (button.onPress()) { // this is our event detection
digitalWrite(pinGreenLed, HIGH); // execute the associated action. Green LED powered
chrono = millis(); // We just had an action, so we reset our stopwatch
currentState = STATE_G; // note the new state of our system
}
break;
case STATE_G: // green LED was on and if we get a click, turn on the yellow LED
if (button.onPress()) { // this is our event detection
digitalWrite(pinYellowLed, HIGH); // execute the associated action. Yellow LED powered
chrono = millis(); // We just had an action, so we reset our stopwatch
currentState = STATE_GY; // note the new state of our system
}
break;
case STATE_GY: // green and yellow were on, if we get a click, turn on the orange LED
if (button.onPress()) { // this is our event detection
digitalWrite(pinOrangeLed, HIGH); // execute the associated action. Orange LED powered
chrono = millis(); // We just had an action, so we reset our stopwatch
currentState = STATE_GYO; // note the new state of our system
}
break;
case STATE_GYO: // green, orange, and yellow were on, if we get a click, turn on the red LED
if (button.onPress()) { // this is our event detection
digitalWrite(pinRedLed, HIGH); // execute the associated action. Red LED powered
chrono = millis(); // We just had an action, so we reset our stopwatch
currentState = STATE_GYOR; // note the new state of our system
}
break;
case STATE_GYOR: // everything was on, if we get a click a click, return to rest
if (button.onPress()) { // this is our event detection
turnLedsOff(); // execute the associated action. return to the initial state
chrono = millis(); // We just had an action, so we reset our stopwatch
currentState = REST;
}
break;
}
// TEST FOR TIMEOUT
if ((currentState != REST) && (millis() - chrono >= TimeOut)) { // timeout event
turnLedsOff();
currentState = REST;
}
}
// ------------------------------------------------------
// We initialize our system in the setup
// ------------------------------------------------------
void setup() {
// configure
pinMode(pinRedLed, OUTPUT);
pinMode(pinOrangeLed, OUTPUT);
pinMode(pinYellowLed, OUTPUT);
pinMode(pinGreenLed, OUTPUT);
button.begin(buttonPin);
// define Initial conditions
turnLedsOff();
currentState = REST;
}
void loop() {
// we update ou system based on possible events
runStateMachine();
// Here, we can do other things as long as it doesn't take too long and is non blocking
}