/*
Forum: https://forum.arduino.cc/t/millis-statt-delay-funktioniert-so-nicht/1381778
Wokwi: https://wokwi.com/projects/431040999760784385
A very simple state machine that demonstrates the use of
enums for states
millis() instead of delays to control sequence flows
A sequence is started by Serial input 's' or 'S'.
The sequence ends after "sequenceDuration" [ms]
ec2021
2025/05/15
*/
constexpr unsigned long sequenceDuration = 3500; // [ms]
constexpr unsigned long printInterval = 333; // [ms]
enum States {IDLE, RUNNING};
States state = IDLE;
unsigned long seqStart = 0;
unsigned long lastTimeHere = 0;
void setup() {
Serial.begin(115200);
Serial.println("Input s or S");
}
void loop() {
verySimpleStateMachine();
}
boolean startSequence() {
if (Serial.available()) {
char c = Serial.read();
if (toupper(c) == 'S') {
return true;
}
}
return false;
}
void verySimpleStateMachine() {
switch (state) {
case IDLE:
if (startSequence()) {
// This is performed when a sequence shall start
// We store the start time
seqStart = millis();
// Do something that shall be done once everytime
// a sequence starts (here we only print something)
Serial.print("Start - Running - ");
// and now change the state to RUNNING
state = RUNNING;
}
break;
case RUNNING:
if (millis() - lastTimeHere >= printInterval) {
// This is performed every printInterval while state == RUNNING
// We store the time when this if clause was entered for the next loop()
lastTimeHere = millis();
// We could do e.g. read sensor values or control a stepper or ...just print something
Serial.print('.');
}
if (millis() - seqStart >= sequenceDuration) {
// This is performed when sequenceDuration is expired
// We could stop a motor, switch an led on or off, or just print something
Serial.println(" - Stop");
Serial.println("Input s or S");
// As the sequenceDuration has expired and we have done our "final work" we go back to IDLE
state = IDLE;
}
break;
}
}