EUREKA! That first one is exactly what I was after. It will provide an excellent jumping off point if I need to add features and start using the real parts.OK I changed this to a Finite State Machine using if/else ifs (switch/case would be more proper but I get to do this how I want, and I want if/else if).
The purpose of the requested behavior isn't obvious to me so I question if I understand correctly, but this should do what I understand you to be asking for:
I made another version of it you can play around with, that makes more sense to me for using a momentary pushbutton, and which demonstrates the benefit of using a Finite State Machine as a program grows and becomes more complex.C-like:int switchState = 0; const int event_1 = 3000; const int event_2 = 7000; unsigned long previousTime = 0; unsigned long latchTime = 0; unsigned long currentTime = 0; int fsmState = 0; void setup(){ pinMode(2, INPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); } void loop(){ currentTime = millis(); switchState = digitalRead(2); if (fsmState == 0){ // STATE 0: IDLE. the board will boot into this state: digitalWrite(3, HIGH); // green led digitalWrite(4, LOW); // red led // previousTime increments in state 0 and freezes upon leaving state 0, // frozen value to be used in state 10 previousTime = millis(); if (switchState == HIGH) fsmState = 10; } else if (fsmState == 10){ // STATE 10: IDLE with button held down. Waiting for 5s to elapse. if (currentTime - previousTime >= event_1) fsmState = 20; else if (switchState == LOW) fsmState = 0; // latchTime increments in state 10 and freezes upon leaving state 10, // frozen value to be used in state 20 latchTime = millis(); } else if (fsmState == 20){ // STATE 20: Switch still ON after 5s, turn red light on. digitalWrite(3, LOW); // green led digitalWrite(4, HIGH); // red led if ((currentTime - latchTime >= event_2) or (switchState == LOW)) fsmState = 0; } }
Turn on, neither LED lights up
Press once and release, red comes on
press again and release, green comes on
press again and release, both come on
Leave it on more than 7s in any of these states, and it times out, turns off.
Imagine trying to manage this sequence with normal if/then statements instead of the Finite State Machine (fsmState). Each of your statements might look something like this:C-like:int buttonState = 0; const int event_1 = 3000; const int event_2 = 7000; unsigned long timeEnteredState = 0; unsigned long currentTime = 0; int fsmState = 0; void setup(){ pinMode(2, INPUT); pinMode(3, OUTPUT); pinMode(4, OUTPUT); } void loop(){ currentTime = millis(); buttonState = digitalRead(2); if (fsmState == 0){ // STATE 0: IDLE. the board will boot into this state: digitalWrite(3, LOW); // green led digitalWrite(4, LOW); // red led if (buttonState == HIGH) fsmState = 10; } else if (fsmState == 10){ // STATE 10: transtion state, wait for button release. timeEnteredState = millis(); if (buttonState == LOW) fsmState = 20; } else if (fsmState == 20){ // STATE 20: red light ON, green light OFF digitalWrite(4, HIGH); // red led if (buttonState == HIGH) fsmState = 30; else if (currentTime - timeEnteredState >= event_2) fsmState = 0; } else if (fsmState == 30){ // STATE 30: transtion state, wait for button release. digitalWrite(4, LOW); // red led timeEnteredState = millis(); if (buttonState == LOW) fsmState = 40; } else if (fsmState == 40){ // STATE 40: red light OFF, green light ON digitalWrite(3, HIGH); // green led if (buttonState == HIGH) fsmState = 50; else if (currentTime - timeEnteredState >= event_2) fsmState = 0; } else if (fsmState == 50){ // STATE 50: transtion state, wait for button release. digitalWrite(3, LOW); // green led timeEnteredState = millis(); if (buttonState == LOW) fsmState = 60; } else if (fsmState == 60){ // STATE 60: Both lights ON digitalWrite(3, HIGH); // green led digitalWrite(4, HIGH); // red led if (buttonState == HIGH) fsmState = 0; else if (currentTime - timeEnteredState >= event_2) fsmState = 0; } }
C-like:if ((buttonState == HIGH) and (previousButtonState == LOW) and (redLightWasOnBeforeThat == true) and (currentTime - previousTime >= event_1) and (theresNoOtherConditionIForgotToMention == true)){ digitalWrite(3, HIGH); // green led digitalWrite(4, HIGH); // red led }
One question I've had with all these segments of code is there a textbook, video, classes, etc. that I could get a hold of and go step by step through each of the functions to understand how to use it better? I understood some of the basic "if" and "else" uses but those obviously cluttered up the works here. The finite state machine is very interesting, but that's the first mention I've seen about it and it might as well be magic.
I've been watching a seemingly prominent YouTuber that has explained some things well (he's where I got the millis idea), and I've try Googling everything, but it's a bit like looking for a dry spot on the Titanic: there's water (info) everywhere and I'm not sure what to trust.