jonblack / arduino-fsm

Arduino library for implementing a finite state machine.
MIT License
200 stars 97 forks source link

"In state" callback function not executed? #39

Open fkromer opened 3 years ago

fkromer commented 3 years ago

I've created the following example.

#include "Fsm.h"

#define STATE_1_TO_2_EVENT 1
#define STATE_2_TO_1_EVENT 2

void on_state_1_on_enter()
{
  Serial.println("Entering State 1");
}

void on_state_1_in_state()
{
  Serial.println("State 1");
}

void on_state_1_on_exit()
{
  Serial.println("Exiting State 1");
}

void on_state_2_on_enter()
{
  Serial.println("Entering State 2");
}

void on_state_2_in_state()
{
  Serial.println("State 2");
}

void on_state_2_on_exit()
{
  Serial.println("Exiting State 2");
}

State state_1(&on_state_1_on_enter, &on_state_1_in_state, &on_state_1_on_exit);
State state_2(&on_state_2_on_enter, &on_state_2_in_state, &on_state_2_on_exit);
Fsm fsm(&state_1);

void on_trans_1_to_2() {
    Serial.println("State 1 -> State 2");
}

void on_trans_2_to_1() {
    Serial.println("State 2 -> State 1");
}

// standard arduino functions
void setup()
{
  Serial.begin(9600);

  fsm.add_transition(&state_1, &state_2,
                     STATE_1_TO_2_EVENT,
                     &on_trans_1_to_2);
  fsm.add_transition(&state_2, &state_1,
                     STATE_2_TO_1_EVENT,
                     &on_trans_2_to_1);
  fsm.run_machine();
}

void loop()
{
  delay(2000);
  fsm.trigger(STATE_1_TO_2_EVENT);
  delay(2000);
  fsm.trigger(STATE_2_TO_1_EVENT);
}

If I run the example the serial console output is as follows:

Entering State 1
State 1
Exiting State 1
State 1 -> State 2
Entering State 2
Exiting State 2
State 2 -> State 1
Entering State 1
Exiting State 1
State 1 -> State 2
Entering State 2
Exiting State 2
(...)

The "in state" callback function for state 1 on_state_1_in_state() is executed only once, implicitly as part of Fsm fsm(&state_1);. The callback function for state 2 on_state_2_in_state() is not executed at all. Have I not used the API correctly?

Jason-CHK commented 2 years ago

I think you need to call fsm.run_machine(); in loop() instead of setup(), like this example.