Help creating finite state machine

I'm trying to create a finite state machine with three different states that can be toggled between by entering 0 or 1 in the serial monitor. I'm using switch and case for it.

The issue I am having is when I want to switch to case C from B, it will revert back to case B without any input. Why is this?

I am using an Arduino MRK1000.

char PresentState;
char NextState;
int UserInput;

void setup() {

  Serial.begin(9600);
  PresentState = 'A';
  Serial.print("Initial State= ");
  Serial.print(PresentState);
  Serial.print("\n");

}

void loop() {

  Serial.print("Input 0 or 1 to change state: ");
  
  while(Serial.available() == 0);
  UserInput = Serial.parseInt();
  Serial.print(UserInput);
  Serial.print("\n");
  Serial.print("Current State: ");
  
  Serial.print(PresentState);
  Serial.print("\n");
  

  switch(PresentState){
      case 'A':{
        if (UserInput == 1)
        NextState = 'B';
        else
        NextState = PresentState;
      }break;
     
      case 'B':{
        if (UserInput == 1)
        NextState = 'C';
        else
        NextState = PresentState;
      }break;
      
      case 'C':{
        if (UserInput == 1)
        NextState = 'A';
        else if(UserInput == 0)
         NextState = 'B';
      }break;
    }
  Serial.print("Next State: ");
  Serial.print(NextState);
  Serial.print("\n");

  PresentState = NextState;
}
  while(Serial.available() == 0);

The usual reason for using a state machine is to avoid blocking. This destroys that benefit completely by blocking any other code, until some input comes along. Use

 if (Serial.available() )
    {...

I'm not sure if the braces {} in each of your case statements are screwing up your switch statement, but they don't belong there. Go look up the switch/case statement documentation.

I think you don't understand the purpose of loop(). It is supposed to run thousands of times a second. Not halt to do this, halt to do that.

the stimulus in a particular state doesn't require a state change.

there are two types of states machines: one when the action depends on the state and the second where the action depends on the transition (the state and the stimulus). a stimulus can be back to the same state

You'll also find a quite comprehensive finite state machine tutorial following the link here: State machine for Arduino tutorial - Exhibition / Gallery - Arduino Forum

Each of the directories on the linked Github repository has a PDF file with documentation for the examples.

case 'C':{
if (UserInput == 1)
NextState = 'A';
else if(UserInput == 0)// in this case you're always switch back to this state
NextState = 'B';//set another state then 'B' as Nextstate
}break;

The Serial.parseInt() will return 0 if no integer is found in the timeout interval. Make sure you have the line ending menu at the bottom of Serial Monitor set to "No line ending".

I think this will behave better:

char PresentState, NextState;
int UserInput;


void setup()
{
  Serial.begin(9600);


  PresentState = 'A';
  Serial.print("Initial State= ");
  Serial.println(PresentState);


  Serial.println("Input 0 or 1 to change state: ");
}


void loop()
{
  UserInput = -1;
  if (Serial.available())
  {
    UserInput = Serial.read();
    Serial.print("User Input: ");
    Serial.println((char)UserInput);
    Serial.print("Current State: ");
    Serial.println(PresentState);
  }


  NextState = PresentState;
  
  switch (PresentState)
  {
    case 'A':
      if (UserInput == '1')
        NextState = 'B';
      break;


    case 'B':
      if (UserInput == '1')
        NextState = 'C';
      break;


    case 'C':
      if (UserInput == '1')
        NextState = 'A';
      else if (UserInput == '0')
        NextState = 'B';
      break;
  }


  // Display if there is a state change
  if (NextState != PresentState)
  {
    Serial.print("Next State: ");
    Serial.println(NextState);


    PresentState = NextState;
  }
}

aarg:
I'm not sure if the braces {} in each of your case statements are screwing up your switch statement, but they don't belong there. Go look up the switch/case statement documentation.

You need to use braces in cases if you introduce local variables.
Otherwise, they do no harm.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.