Skip to content
This repository has been archived by the owner on Mar 1, 2024. It is now read-only.
/ YA_FSM Public archive

Simple state machine. Implements a "Petri net" (GRAFCET/SFC) inspired state machine with states, transitions and actions

License

Notifications You must be signed in to change notification settings

cotestatnt/YA_FSM

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

YA_FSM Arduino Library - YET ANOTHER FINITE STATE MACHINE

The YA_FSM Arduino library implements a Finite State Machine with pre-defined states and transitions associated to callback functions.

This library try to reproduce the type of automation you can define with a SFC/GRAFCET model. In the example folders you can find an image where the inspiring FSM model is represented with an SFC diagram


Introduction

States represent the different situations in which the machine can be at any time. The transitions connect two states, one at the input and others at the output, and are associated with a trigger condition which carries out the change of state (if you take a look at the examples included, you will find some different way for triggering a transition).

To update the states, you must call the Update() function in your loop(), which checks for transitions that have the current state as input and associated conditions.

If any of the transitions associated with the current state satisfy the trigger condition, the machine goes into the next state.

SFC_esempio

State definition and Callback functions

Each of the states of the machine can be binded with a callback function that will be executed when the state is activated (on entering), when it is left (on leaving) and while it is running (on state).

For each state it is also possible to define an optional maximum and a minimum duration time.

If a callback function is not needed, simply use value nullptr instead of the name of function.

stateMachine.AddState(STATE_LABEL, TIME_MAX, TIME_MIN, onEnterCB, onStateCB, onExitCB);
stateMachine.AddState(STATE_LABEL, TIME_MAX, onEnterCB, onStateCB, onExitCB);

Transition definition and trigger

To connect two states, you need to define the transition. The trigger of transition can be performed with a bool function() or a bool variable.

Also the timeout of state itself (it is a bool) can be used for triggering to next state.

In order to check if a specific state has exceeded its timeout, use the AddTimedTransition() method, which checks the CurrentState()->timeout bool property stored in the related struct of type FSM_State

stateMachine.AddTimedTransition(FROM_STATE_INDEX, TO_STATE_INDEX);

You can check timeout for a specific state also testing the property timeout

if(stateMachine.CurrentState()->timeout) {....}
if(stateMachine.Timeout(state_index)) {....}

Action definition

For each state you can define also a set of qualified action, that will be execute when state is active causing effect to the target bool variable

bool targetVar1, targetVar2;
stateMachine.AddAction(STATE_INDEX, YA_FSM::N, targetVar1);
stateMachine.AddAction(STATE_INDEX, YA_FSM::R, targetVar2);

The library actually support this action qualifiers:

Action qualifier Description Short explanation on the effect Duration
N Non-stored Action is active (target = TRUE) as long as the state input is active NO
R Reset Reset to FALSE the value of target variable NO
S Set (or Stored) Set to TRUE the value of target variable NO
L time Limited target = TRUE until the end of the set time or until the state is deactivated YES
D time Delayed target = TRUE after the set time has elapsed until the state is deactivated YES

Examples

Take a look at the examples provided in the examples folder. Start from the simplest Blinky.ino or PedestrianLight.ino

or a more advanced like classic algorithm for opening an automatic gate (simplified) AutomaticGate or rail crossing RailCRossing.ino

Constructor

// Create new SFC
YA_FSM stateMachine;

General methods

// Get current state index
uint8_t GetState() const;

// Get pointer to current state object
FSM_State* CurrentState();

// Get pointer to a specific state object passing the index
FSM_State*  GetStateAt(uint8_t index);

// Get active state name
const char* ActiveStateName();

// Get the number of defined finite states
const int GetNumStates()

// Set machine to state at index. Will call every function as expected unless told otherwise
// If is the same state as the current, it should call onEntering and onLeaving and Refresh Timeout
void SetState (uint8_t index, bool callOnEntering = true, bool callOnLeaving = true)
  
// Set or modify a state timeout (preset = milliseconds)
void SetTimeout(uint8_t index, uint32_t preset);

// Check if a state is timeouted
bool GetTimeout(uint8_t index);		// deprecated
bool Timeout(uint8_t index);		// More clear method name
stateMachine.CurrentState()->timeout	// Access directly to the value stored in FSM_State struct

// Get the time (milliseconds) when state was activated
uint32_t GetEnteringTime(uint8_t index) 
	
// Update state machine. Run in loop()
bool Update();

// Set up a transition and trigger input callback function (or bool variable)
void AddTransition(uint8_t inputState, uint8_t outputState, condition_cb condition);
void AddTransition(uint8_t inputState, uint8_t outputState, bool condition);

// Set up a timed transition
void AddTransition(uint8_t inputState, uint8_t outputState);
void AddTimedTransition(uint8_t inputState, uint8_t outputState);

// Set up and action for a specific state (supported qualifiers N, S, R, D, L
// More actions can be added to the same state (actaully limited by #define MAX_ACTIONS 64)
uint8_t AddAction(uint8_t inputState, uint8_t type, bool &target, uint32_t _time=0);

// Set up a state with properties and callback function
uint8_t AddState(const char* name, uint32_t maxTime, uint32_t minTime,	action_cb onEntering, action_cb onState, action_cb onLeaving);
uint8_t AddState(const char* name, uint32_t maxTime, action_cb onEntering, action_cb onState, action_cb onLeaving);
	
------- OLD VERSION  -------
// Configure input and output and run actions of a state
void SetOnEntering(uint8_t index, action_cb action);
void SetOnLeaving(uint8_t index, action_cb action);
void SetOnState(uint8_t index, action_cb action, uint32_t setTimeout = 0)   // 0 disabled

void ClearOnEntering(uint8_t index);
void ClearOnLeaving(uint8_t index);
void ClearOnState(uint8_t index);

Supported boards

The library works virtually with every boards supported by Arduino framework (no hardware dependency)

  • 1.0.8 Edit state min and max time at runtime
  • 1.0.7 Added utility class for led blinking (Blinker.h)
  • 1.0.6 Added timed transition
  • 1.0.5 Added support for Action Qualifiers N, S, R, D, L (pedestrainLight example updated with this method)
  • 1.0.4 Examples simplified, bug fixes
  • 1.0.3 Added ActiveStateName() method and updated all examples with new style (addTransition() and addStep() )
  • 1.0.2 Bug fix
  • 1.0.1 Dinamic memory allocation for states and transitions
  • 1.0.0 Initial version

About

Simple state machine. Implements a "Petri net" (GRAFCET/SFC) inspired state machine with states, transitions and actions

Topics

Resources

License

Stars

Watchers

Forks

Packages

No packages published

Languages