Unit Testable Finite State Machine (FSM) implementation for MCU

Hello , As part of MCU exploration by means of simple home automation project I needed the FSM implementation to help me with code organization and debugging. Here are the features that were desired (in no particular order):

  • Support for multiple independent FSM instances;
  • Ability to communicate between multiple FSM instances;
  • Ability to unit test logic on PC without changing code that gets flushed onto MCU;
  • Ability to “play” with logic interactively (interactive simulation);
  • Minimization of power consumption (“Blink” should work forever from AAA battery :) );
  • Modularity, so that parts of MCU specific implementation can be replaced completely or fine-tuned to better fit project requirements, including ability to run the project on different MCUs.
  • Simplicity of use.

Since no existing implementations that would satisfy desired goals were found, new implementation was create:

New example ofsmIntersection added.

ofsmIntersection problem statement:

  • There is an intersection of road 1 and road 2
  • Both roads have green signal light, which when turned on indicates that road is in “traffic mode”
  • Only one green signal light can be turned on at any point of time
  • Unless interrupted by crosswalk button, switching between green lights happens every GREEN_LIGHT_TIMEOUT + CLEAR_INTERSECTION_TIMEOUT
  • There is a crosswalk on both roads
  • Both crosswalks are controlled by the same button
  • When button is pressed, currently in “traffic mode” road gets into “Clear Intersection” mode
  • Once button is pressed and “active” road gets into “Clear Intersection” mode, further presses of the button should be ignored

Intersection State machine diagram:


  • [Pin12] → [Diode+] [Diode-] → [R(220 Ohm)] → GND
  • [Pin2] → [ButtonTerminalA] [ButtonTerminalB] → GND

Interactive Simulation:

  • Build command: g++ -Wall -std=c++11 -fexceptions -std=c++11 -I…/…/src -g -o ofsmIntersection -x c++ ofsmIntersection.ino
  • When running, to simulate button press enter: 1 (which is a shorthand for queue,1,0,0) (please, don’t forget to hit to submit the event/command :slight_smile: )

</sub> <sub>[i]* OFSM_DECLARE_FSM() has been changed. New parameter to set initial state has been added.[/i]</sub> <sub>