diff --git a/Fsm.cpp b/Fsm.cpp index 8a73782..5da70fe 100644 --- a/Fsm.cpp +++ b/Fsm.cpp @@ -26,7 +26,8 @@ State::State(void (*on_enter)(), void (*on_exit)()) Fsm::Fsm(State* initial_state) : m_current_state(initial_state), m_transitions(NULL), - m_num_transitions(0) + m_num_transitions(0), + m_initialized(false) { } @@ -96,6 +97,14 @@ void Fsm::trigger(int event) if (m_transitions[i].state_from == m_current_state && m_transitions[i].event == event) { + if (! m_initialized) + { + m_initialized = true; + if (m_transitions[i].state_from->on_enter != NULL) + { + m_transitions[i].state_from->on_enter(); + } + } m_current_state = m_transitions[i].make_transition(); return; } @@ -112,12 +121,20 @@ void Fsm::check_timer() { if (transition->start == 0) { + if (! m_initialized) + { + m_initialized = true; + if (transition->transition.state_from->on_enter != NULL) + { + transition->transition.state_from->on_enter(); + } + } transition->start = millis(); } else { unsigned long now = millis(); - Serial.println(now); + //Serial.println(now); //jfm if (now - transition->start >= transition->interval) { m_current_state = transition->transition.make_transition(); diff --git a/Fsm.h b/Fsm.h index f58757f..bd03268 100644 --- a/Fsm.h +++ b/Fsm.h @@ -72,6 +72,7 @@ class Fsm State* m_current_state; Transition* m_transitions; int m_num_transitions; + boolean m_initialized; TimedTransition* m_timed_transitions; int m_num_timed_transitions; diff --git a/examples/initBugTest/initBugTest.ino b/examples/initBugTest/initBugTest.ino new file mode 100644 index 0000000..ec11d84 --- /dev/null +++ b/examples/initBugTest/initBugTest.ino @@ -0,0 +1,74 @@ +/* + initBugTest -- sketch to demonstrate startup behaviour of a classic event + driven FSM and also a timed-transition FSM. + + Issue with first invokation of the trigger() function. + Issue with first invokation of the check_timer() function. + + Expect to see the "on_enterX" function called followed by + the "on_exitX" function. + + Only one state machine is needed to demonstrate the problem. + However the change I made to fix the problem requires a fresh + copy of the FSM to excercise the two code paths affected. + + John Mauzey 20160212 +*/ +#include + +#define BAUD 115200 //for console log of status messages + +//define a standard FSM that prints a text message on both enter and exit +#define TRANS_TEST 1 //for testing classic transitions (not timed) +void on_enter1(void) +{ + Serial.print(millis()); + Serial.println(" fsm1: on_enter called"); +} + +void on_exit1(void) +{ + Serial.print(millis()); + Serial.println(" fsm1: on_exit called "); +} + +State state_enter_exit1(&on_enter1,&on_exit1); +Fsm fsm1(&state_enter_exit1); + +//define a periodic FSM that prints a text message on both enter and exit +void on_enter2(void) +{ + Serial.print(millis()); + Serial.println(" fsm2: on_enter called"); +} + +void on_exit2(void) +{ + Serial.print(millis()); + Serial.println(" fsm2: on_exit called "); +} + +State state_enter_exit2(&on_enter2,&on_exit2); + +Fsm fsm2(&state_enter_exit2); + +void setup() +{ + Serial.begin(BAUD); + fsm1.add_transition(&state_enter_exit1, &state_enter_exit1, TRANS_TEST, NULL); + fsm2.add_timed_transition(&state_enter_exit2, &state_enter_exit2, 3000, NULL); + + Serial.println("Testing classic state machine -- Sending first trigger"); + fsm1.trigger(TRANS_TEST); + + Serial.println("Testing classic state machine -- Sending second trigger"); + fsm1.trigger(TRANS_TEST); + Serial.println(""); + Serial.println("Testing timed state machine -- 3 second periodic timer"); +} + +void loop(void) +{ + fsm2.check_timer(); +} +