Need Help w/ End of My Code

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
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:

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;
  }
}
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.

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.

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;
  }
}
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:
  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
  }
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.

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.
 

Ya’akov

Joined Jan 27, 2019
10,249
One question I've had with all these segments of code is there a textbook, video, classes, etc.
This is a two part video from Ralph Bacon on writing state machines in the Arduino environment. While I personally don’t care for Ralph’s style of presentation, he is accurate, thorough, and seems to have a good handle on what information a neophyte needs. He has quite a few videos on various fundamental topics, highly recommended if you like his style.

 

Thread Starter

Alln3w2m3

Joined Jun 20, 2023
57
This is a two part video from Ralph Bacon on writing state machines in the Arduino environment. While I personally don’t care for Ralph’s style of presentation, he is accurate, thorough, and seems to have a good handle on what information a neophyte needs. He has quite a few videos on various fundamental topics, highly recommended if you like his style.

Great, thank you. I will take a look at those.
 

strantor

Joined Oct 3, 2010
6,875
This is a two part video from Ralph Bacon on writing state machines in the Arduino environment. While I personally don’t care for Ralph’s style of presentation, he is accurate, thorough, and seems to have a good handle on what information a neophyte needs. He has quite a few videos on various fundamental topics, highly recommended if you like his style.
I have never heard of him but I watched the videos just now and share your opinion. I wish he had used the Arduino IDE instead of Visual Studio as his intended audience is likely to be confused by the unfamiliar environment and may question if they are watching the right video. I understand it offers more demo-friendly features like collapsable code blocks, but even that is potentially bewildering for someome who has never used an IDE which has that feature. He didn't even attempt to explain the unfamiliar visuals until the 2nd video and even then it was just a footnote. BTW he doesn't actually start talking about state machines until the 2nd video.

But my real gripe is that (IMO) he introduced too many concepts under the heading of one lesson. Static variables, switch case, and enum are each a bit mystifying in their own right and deserve their own separate lessons. That's why I stuck to using if/else if, and an integer for state, in the state machines I posted here. I think if I were at square one and I watched those videos I would be more confused right now than when I started. But I am not the sharpest crayon in the box; maybe he understands his target audience better than I do.

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.
Excellent, glad it worked!

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 couldn't say about classes/books. I got started learning what I know about programming much the same way you are getting started now; with a very specific focus, a specific goal, to achieve a specific task in a specific project. I learned what I needed to learn to complete that task, and not much else. Then I had another project where I had to learn something else, and then something else, and so on. I am not the kind of person whose thought processes are well suited to reading through a book from start to finish, learning for the sake of learning; for me the reading and learning happens along the way of actually doing something. This means I have holes in my knowledge. I would be better at programming, more well rounded, stay closer to straight in the lanes of standard best practices if I went the way of @MrChips and other classically trained folk. But that's not me, and I suspect that's not you, so that's why I'm here.

Going about it the way I did presents certain challenges. The creator of a video, blog, tutorial, whatever, can't know what level of experience you bring with you on arrival at their lesson. Some of them assume you know nothing, so the lesson is hours long before they finally get to the point. Sometimes it's the opposite and they're already over your head in the first 30 seconds. You'll never find a resource that is a perfect fit for where you are, at any given time. And sometimes they actually suck at programming and shouldn't be teaching anyone anything (could apply to me). That said, I can tell you that for Arduino the most valuable resources I found were Arduino Docs website, the Arduino forum, Stack Echange, Stack Overflow, AllAboutCircuits (<-- you are here), YouTube, and above all else, just plain 'ol google, since it usually leads you by the hand to the right spot in one of the other references already mentioned.

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.
Yep. It's drinking (questionably potable) water from a firehose.

For a more structured (but accelerated) learning experience, my first inclination would be a "for dummies" book. That's how I learned Visual Basic 4.0 on Windows 95 as a kid during the dry spells between AOL dialup trial CDs. I've never read "Arduino For Dummies" but here it is, if you want to give it a try.

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 tried looking for a good reference for this, for you, geared toward someone at your level, and didn't find anything appropriate. Everything I found is either too basic (classic turnstile 2-state or traffic light 3-state machines which could just as easily be done without a state machine and don't convey any obvious reason for using one) or way too advanced/theoretical (30 seconds in, vomiting complex equations with Greek letters that I don't even understand). On top of that, they're almost all language-specific (and not to arduino) so coveyance of the concept is hampered by language-specific distractions. I didn't find anything better than what @Ya’akov already posted.

What would be better is if I could explain further with a real-world example that you are already familiar with. Turns out I already laid the groundwork for that. If you want a personalized lesson in state machines, how about running that second program I posted and analyze what it's doing, try to replicate its results using the same flavor of if/then statements you started this thread with, and come back with any questions. I know its operation doesn't satisfy the outcome you are after but it wasn't intended to; it was intended as an instructional tool.
 
Last edited:
Top