/*
Nested state example.
Here a variable is set on change of state so the successor state logic can
do its own initialisation.
*/
const int button = 4 ;
const int mixerPin = 5 ;
enum class States { WAIT_BUTTON_PRESS_DELAYED, IN_MIX } ;
States state = States::WAIT_BUTTON_PRESS_DELAYED ;
uint32_t stateTimer = millis() ;
bool stateChangeNew = true ; // indicating a new entry to state
void setup() {
Serial.begin(115200);
pinMode( button, INPUT_PULLUP) ;
pinMode( mixerPin, OUTPUT) ;
}
void loop() {
switch ( state ) {
case States::WAIT_BUTTON_PRESS_DELAYED : {
enum class StatesIntern { INIT, WAIT_BUTTON_PRESS, WAIT_BUFFER_TIME } ;
static StatesIntern stateIntern ;
static uint32_t stateTimerIntern = 0 ;
if (stateChangeNew) {
stateChangeNew = false ; // reset
Serial.println("we are new in state WAIT_BUTTON_PRESS_DELAYED so initialise") ;
stateIntern = StatesIntern::WAIT_BUTTON_PRESS ;
stateTimerIntern = millis() ;
}
switch ( stateIntern ) {
case StatesIntern::WAIT_BUTTON_PRESS :
if ( !digitalRead( button ) ) {
Serial.println("button press detected. Pausing.") ;
stateIntern = StatesIntern::WAIT_BUFFER_TIME ;
stateTimerIntern = millis() ;
}
break ;
case StatesIntern::WAIT_BUFFER_TIME :
if ( millis() - stateTimerIntern > 1000 ) {
state = States::IN_MIX ;
stateTimer = millis() ;
stateChangeNew = true ;
}
break ;
}
break ;
}
case States::IN_MIX :
if (stateChangeNew) {
stateChangeNew = false ; // reset
Serial.println("we are new in state IN_MIX so initialise") ;
digitalWrite( mixerPin, HIGH ) ;
}
if ( millis() - stateTimer > 5000 ) {
Serial.println("terminating and back to start") ;
state = States::WAIT_BUTTON_PRESS_DELAYED ;
stateTimer = millis() ;
stateChangeNew = true ;
digitalWrite( mixerPin, LOW ) ;
}
break ;
}
}