- Notifications
You must be signed in to change notification settings - Fork1
Finite-State Machine (FSM) for Arduino
License
MicroBeaut/Finite-State
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
Finite-State provides a bounded state machine that combinesstate transitions, which has the following part:
typedefstruct {Predicatepredicate;// Predicate Function Pointerid_tnextF;// Next State on FALSEid_tnextT;// Next State on TRUEProcessprocess;// Process Function PointerEventHandlereventHandler;// Event Handler Function Pointer}Transition;
The Finite-State require to initial with an initial id.
Syntax:
voidbegin(constid_tid);
Example:
objectName.begin(3);// FSM begins with Initial Transition Id 3
A Predicate Function will determine whether the specified object meets the criteria.
typedefbool (*Predicate)(id_t);// Predicate Function Pointer
The following function acceptsid from a caller; type is a parameter of typeid_t. The return type isboolean. It will be used to determine a Next-State for thecurrent state andnext state:
Syntax:
boolPredicateFunction(id_tid);// Predicate Function
Example:
boolPredicateFunction(id_tid) {// TODO: PREDICATE FUNCTIONreturnbutton[id].isPressed(); }
Or,
boolPredicateFunction(id_tid) {// TODO: PREDICATE FUNCTIONreturnarray[id]==10; }
A Next-State has two destinations:
Next State On FALSE (
nextF)AnextF will be defined by the Id number when the return value from Predicate function is
FALSE.Next State On TRUE (
nextT)ANext State On TURE will be defined by the Id number when the return value from Predicate function is
TRUE.
The Process Function is a function to implement Input/Output control, read/write data, etc.
typedefvoid (*Process)(State);// Process Function Pointer
State:
typedefstruct {id_tid;// State idboolfirstScan;// First Scan when State Activated}State;
The following function acceptsstate from a caller; type is parameters of typeState:
Syntax:
voidProcessFunction(Statestate);// Process Function
Example:
voidMotorProcess(Statestate) {StatusStatestatus;if (state.firstScan) {Serial.println("Motor Status Function") }if (motor[state.id].timerON) {if (motor[state.id].running) {status=RUNNING; }else {status=FAULT; }digitalWrite(motor[state.in].faultPin,status==FAULT); }}
NOTE: The Id can also be obtained fromobjectName.id.
id_tid=finiteStateMachine.id;
An Event Handler Function is an option. Finite-State will handle events when the state changes forENTRY andEXIT actions.
typedefvoid (*EventHandler)(EventArgs);// Event Handler Function Pointer
EventArgs:
typedefstruct {id_tid;// State idEventsevent;// Event State}EventArgs;
Events:
enumEvents :int8_t {PROCESS,EXIT,ENTRY,};
The following function acceptsstate from a caller; type is parameters of typeState:Syntax:
voidEventHandlerFunction(EventArgse);// Event Handler Function Pointer
Example:
voidOnEventChanged(EventArgse) {switch (e.event) {caseENTRY:digitalWrite(motor[state.in].output, true);break;caseEXIT:digitalWrite(motor[state.in].output, false);break; }}
| Id | Predicate | Next State - F | Next State - T | Process | Event |
|---|---|---|---|---|---|
| 0 | FanStartPredicate | 0 | 1 | StartFan | nullptr |
| 1 | FanStopPredicate | 1 | 0 | StopFan | nullptr |
Transitiontransitions[]= { {FanStartPredicate,0,1,StartFan},// State-0 - Current-State = 0, Next-State = 1 {FanStopPredicate,1,0,StopFan}// State-1 - Current-State = 1, Next-State = 0};
#include"FiniteState.h"#definethermostatPin A0#definestartStatusPin 5#definestopStatusPin 6uint8_tstatusPins[]= {stopStatusPin,startStatusPin};constuint8_tnumberOfStatus=sizeof(statusPins) /sizeof(uint8_t);voidStartFan(Statestate);voidStopFan(Statestate);boolFanStartPredicate(id_tstate);boolFanStopPredicate(id_tstate);Transitiontransitions[]= { {FanStartPredicate,0,1,StartFan},// State-0 - Current-State = 0, Next-State = 1 {FanStopPredicate,1,0,StopFan}// State-1 - Current-State = 1, Next-State = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State ObjectconstlongThermostatRead();voidFanControl(id_tid);longtemperature;voidsetup() {for (uint8_tindex=0;index<numberOfStatus;index++) {pinMode(statusPins[index],OUTPUT);digitalWrite(statusPins[index],LOW); }finiteStateMachine.begin(0);// FSM begins with Initial Transition Id 0}voidloop() {finiteStateMachine.execute();// Execute the FSMtemperature=ThermostatRead();// Read temperature}boolFanStartPredicate(id_tstate) {returntemperature >=40;// Determine Fan Start Action}voidStartFan(Statestate) {FanControl(state.id);// Fan control output}boolFanStopPredicate(id_tstate) {returntemperature <=30;// Determine Fan Stop Action}voidStopFan(Statestate) {FanControl(state.id);// Fan control output}voidFanControl(id_tid) {for (uint8_tindex=0;index<numberOfStatus;index++) {boolvalue=index==id;digitalWrite(statusPins[index],value);// Update Status }}constlongThermostatRead() {longvalue=analogRead(thermostatPin);// Read Pushbutton Valuereturnmap(value,0,1023,0,100);// Scaling temperature}
| Id | Predicate | Next State - F | Next State - T | Process | Event |
|---|---|---|---|---|---|
| 0 | DelayTimePredicate | 0 | 1 | nullptr | EventStates |
| 1 | DelayTimePredicate | 1 | 2 | nullptr | EventStates |
| 2 | DelayTimePredicate | 2 | 0 | nullptr | EventStates |
Transitiontransitions[]= { {DelayTimePredicate,0,1,nullptr,EventStates},// State-0 - Current-State = 0, Next-State = 1 {DelayTimePredicate,1,2,nullptr,EventStates},// State-1 - Current-State = 1, Next-State = 2 {DelayTimePredicate,2,0,nullptr,EventStates},// State-2 - Current-State = 2, Next-State = 0};
#include"FiniteState.h"#defineredLightPin 5#defineyellowLightPin 4#definegreenLightPin 3uint8_tlightPins[]= {redLightPin,greenLightPin,yellowLightPin};// Define an array of light pins.constuint8_tnumberOfLights=sizeof(lightPins) /sizeof(uint8_t);// Calculate the number of lights.typedefstruct {unsigned longdelayTime;unsigned longstartTime;}Timer;TimerdelayTimes[]= { {5000},// RED Delay Time 5 seconds {10000},// GREEN Delay Time 10 seconds {3000},// YELLOW Delay Time 3 seconds};boolDelayTimePredicate(id_tid);// Predicate FunctionvoidEventStates(EventArgse);// Event StateTransitiontransitions[]= { {DelayTimePredicate,0,1,nullptr,EventStates},// State-0 - Current-State = 0, Next-State = 1 {DelayTimePredicate,1,2,nullptr,EventStates},// State-1 - Current-State = 1, Next-State = 2 {DelayTimePredicate,2,0,nullptr,EventStates},// State-2 - Current-State = 2, Next-State = 0};constuint8_tnumberOftransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOftransitions);// Define Finite-State Objectvoidsetup() {for (uint8_tindex=0;index<numberOfLights;index++) {pinMode(lightPins[index],OUTPUT);// Set Pin ModedigitalWrite(lightPins[index],LOW);// Set Light with the LOW state. }finiteStateMachine.begin(0);// FSM begins with Initial Transition Id 0}voidloop() {finiteStateMachine.execute();// Execute the FSM}boolDelayTimePredicate(id_tid) {return (millis()-delayTimes[id].startTime >=delayTimes[id].delayTime);// Determine Time Delay}voidEventStates(EventArgse) {switch (e.event) {caseENTRY:delayTimes[e.id].startTime=millis();// Reload start timedigitalWrite(lightPins[e.id],HIGH);// Set Light with the HIGH state.break;caseEXIT:digitalWrite(lightPins[e.id],LOW);// Set Light with the LOW state.break; }}
WikipediaFinite-State Machine
About
Finite-State Machine (FSM) for Arduino
Topics
Resources
License
Uh oh!
There was an error while loading.Please reload this page.
Stars
Watchers
Forks
Packages0
Uh oh!
There was an error while loading.Please reload this page.

