- 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 parts:
typedefstruct {Predicatepredicate;// Predicate Function Pointerid_tnextF;// Next State on FALSEid_tnextT;// Next State on TRUEProcessprocess;// Process Function PointerEventHandlereventHandler;// Event Function Pointertime_tdelayTime;// Delay TimeTimerTypetimerType;// Timer Type}Transition;
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 theNextF andnextT:
Syntax:
boolPredicateCallbackFunction(id_tid);// Predicate Callback Function
Example:
boolPredicateCallbackFunction(id_tid) {// TODO: PREDICATE FUNCTIONreturnbutton[id].isPressed(); }
Or,
boolPredicateCallbackFunction(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 the condition of the Timer and 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 the condition of the Timer and Predicate function is
TRUE.
The Process Function is a function to implement Input/Output control, read/write data, etc.
typedefvoid (*Process)(id-t);// Process Function Pointer
The following function acceptsid from a caller; type is parameters of typeid_t:
Syntax:
voidProcessCallbackFunction(id_tid);// Process Callback Function
Example:
voidMotorProcess(id_tid) {StatusStatestatus;if (motor[id].timerON) {if (motor[id].running) {status=RUNNING; }else {status=FAULT; }digitalWrite(motor[id].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,DURINT, andEXIT actions.
typedefvoid (*EventHandler)(EventArgs);// Event Handler Function Pointer
EventArgs:
typedefstruct {id_tid;// State idActionaction;// Action State}EventArgs;
Action:
enumAction {DURING,EXIT,ENTRY};
The following function acceptsid_t, andAction from a caller; type is the parameters of typeEventArgs:
Syntax:
voidEventCallbackFunction(EventArgse);// Event Callback Function
Example:
voidEvnetOnActionChanged(EventArgse) {switch (e.action) {caseENTRY:digitalWrite(motor[e.id].output, true);break;caseDURING:// TODO: SOMETHINGbreak;caseEXIT:digitalWrite(motor[e.id].output, false);break; }}
A Timer is an option. Finite-State will predict the condition for the next state with a timer when the timer type selects and the delay time value is greater than zero.
enumTimerType {NOT_USED,// Not Used TimerTRANS_TIMER,// Transition TimerPREDIC_TIMER,// Predicate TimerFALSE_TIMER,// False State TimerTRUE_TIMER,// True State Timer};
When Timer is not used, The condition for the next state is determined by the Predicate function's return value.
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | PredicateCallbackFunction | 0 | 1 | ProcessCallbackFunction | EventCallbackFunction | - | - |
| 1 | PredicateCallbackFunction | 1 | 0 | ProcessCallbackFunction | EventCallbackFunction | - | - |
Transitiontransitions[]= { {PredicateCallbackFunction,0,1,ProcessCallbackFunction,EventCallbackFunction},// State-0 - NextF = 0, NextT = 1 {PredicateCallbackFunction,1,0,ProcessCallbackFunction,EventCallbackFunction}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Number of TransitionsFiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object
When selecting the transition timer, the condition for the next state will ignore the Predicate function's return value. It is the onlyNextT condition possible during the timer timeout.
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | nullptr | 0 | 1 | ProcessCallbackFunction | EventCallbackFunction | 3,000 | TRANS_TIMER |
| 1 | nullptr | 1 | 0 | ProcessCallbackFunction | EventCallbackFunction | 5,000 | TRANS_TIMER |
Transitiontransitions[]= { {nullptr,0,1,ProcessCallbackFunction,EventCallbackFunction,3000,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1 {nullptr,1,0,ProcessCallbackFunction,EventCallbackFunction,5000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Number of TransitionsFiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object
When selecting the predicate timer, the condition for the next state will ignore the Predicate function's return value during the timer running. The Predicate function's return value will be used for the state selection when the timer timeout.
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | PredicateCallbackFunction | 0 | 1 | ProcessCallbackFunction | EventCallbackFunction | 3,000 | PREDIC_TIMER |
| 1 | PredicateCallbackFunction | 1 | 0 | ProcessCallbackFunction | EventCallbackFunction | 5,000 | PREDIC_TIMER |
Transitiontransitions[]= { {PredicateCallbackFunction,0,1,ProcessCallbackFunction,EventCallbackFunction,3000,PREDIC_TIMER},// State-0 - NextF = 0, NextT = 1 {PredicateCallbackFunction,1,0,ProcessCallbackFunction,EventCallbackFunction,5000,PREDIC_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Number of TransitionsFiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object
When selecting the false-state timer, the condition for the next state will ignore the Predicate function'sFalse value except for theTrue deal during the timer running. The state will be accepted the "False" when the timer timeout.
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | PredicateCallbackFunction | 1 | 0 | ProcessCallbackFunction | EventCallbackFunction | 3,000 | FALSE_TIMER |
| 1 | PredicateCallbackFunction | 0 | 1 | ProcessCallbackFunction | EventCallbackFunction | 5,000 | FALSE_TIMER |
Transitiontransitions[]= { {PredicateCallbackFunction,1,0,ProcessCallbackFunction,EventCallbackFunction,3000,FALSE_TIMER},// State-0 - NextF = 1, NextT = 0 {PredicateCallbackFunction,0,1,ProcessCallbackFunction,EventCallbackFunction,5000,FALSE_TIMER}// State-1 - NextF = 0, NextT = 1};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Number of TransitionsFiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object
When selecting the true-state timer, the condition for the next state will ignore the Predicate function'sTrue value except for theFalse deal during the timer running. The state will be accepted theTrue when the timer timeout.
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | PredicateCallbackFunction | 0 | 1 | ProcessCallbackFunction | EventCallbackFunction | 3,000 | TRUE_TIMER |
| 1 | PredicateCallbackFunction | 1 | 0 | ProcessCallbackFunction | EventCallbackFunction | 5,000 | TRUE_TIMER |
Transitiontransitions[]= { {PredicateCallbackFunction,0,1,ProcessCallbackFunction,EventCallbackFunction,3000,TRUE_TIMER},// State-0 - NextF = 0, NextT = 1 {PredicateCallbackFunction,1,0,ProcessCallbackFunction,EventCallbackFunction,5000,TRUE_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Number of TransitionsFiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | FanStartPredicate | 0 | 1 | StartFanProcess | - | - | - |
| 1 | FanStopPredicate | 1 | 0 | StopFanProcess | - | - | - |
Transitiontransitions[]= { {FanStartPredicate,0,1,StartFanProcess},// State-0 - NextF = 0, NextT = 1 {FanStopPredicate,1,0,StopFanProcess}// State-1 - NextF = 1, NextT = 0};
#include"FiniteState.h"#definethermostatPin A0#definestartStatusPin 5#definestopStatusPin 6uint8_tstatusPins[]= {stopStatusPin,startStatusPin};constuint8_tnumberOfStatus=sizeof(statusPins) /sizeof(uint8_t);voidStartFanProcess(id_tid);voidStopFanProcess(id_tid);boolFanStartPredicate(id_tstate);boolFanStopPredicate(id_tstate);Transitiontransitions[]= { {FanStartPredicate,0,1,StartFanProcess},// State-0 - NextF = 0, NextT = 1 {FanStopPredicate,1,0,StopFanProcess}// State-1 - NextF = 1, NextT = 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}voidStartFanProcess(id_tid) {FanControl(id);// Fan control output}boolFanStopPredicate(id_tstate) {returntemperature <=30;// Determine Fan Stop Action}voidStopFanProcess(id_tid) {FanControl(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 | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | DelayTimePredicate | 0 | 1 | nullptr | EventOnActionChanged | - | - |
| 1 | DelayTimePredicate | 1 | 2 | nullptr | EventOnActionChanged | - | - |
| 2 | DelayTimePredicate | 2 | 0 | nullptr | EventOnActionChanged | - | - |
Transitiontransitions[]= { {DelayTimePredicate,0,1,nullptr,EventOnActionChanged},// State-1 - NextF = 0, NextT = 1 {DelayTimePredicate,1,2,nullptr,EventOnActionChanged},// State-2 - NextF = 1, NextT = 2 {DelayTimePredicate,2,0,nullptr,EventOnActionChanged},// State-3 - NextF = 2, NextT = 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 (Input)voidEventOnActionChanged(EventArgse);// Event StateTransitiontransitions[]= { {DelayTimePredicate,0,1,nullptr,EventOnActionChanged},// State-1 - NextF = 0, NextT = 1 {DelayTimePredicate,1,2,nullptr,EventOnActionChanged},// State-2 - NextF = 1, NextT = 2 {DelayTimePredicate,2,0,nullptr,EventOnActionChanged},// State-3 - NextF = 2, NextT = 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}voidEventOnActionChanged(EventArgse) {switch (e.action) {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; }}
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | nullptr | 0 | 1 | nullptr | EventOnActionChanged | 5,000 | TRANS_TIMER |
| 1 | nullptr | 1 | 2 | nullptr | EventOnActionChanged | 10,000 | TRANS_TIMER |
| 2 | nullptr | 2 | 0 | nullptr | EventOnActionChanged | 3,000 | TRANS_TIMER |
Transitiontransitions[]= { {nullptr,0,1,nullptr,EventOnActionChanged,5000,TRANS_TIMER},// State-1 - NextF = 0, NextT = 1 {nullptr,1,2,nullptr,EventOnActionChanged,10000,TRANS_TIMER},// State-2 - NextF = 1, NextT = 2 {nullptr,2,0,nullptr,EventOnActionChanged,3000,TRANS_TIMER},// State-3 - NextF = 2, NextT = 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.voidEventOnActionChanged(EventArgse);// Event StateTransitiontransitions[]= { {nullptr,0,1,nullptr,EventOnActionChanged,5000,TRANS_TIMER},// State-1 - NextF = 0, NextT = 1 {nullptr,1,2,nullptr,EventOnActionChanged,10000,TRANS_TIMER},// State-2 - NextF = 1, NextT = 2 {nullptr,2,0,nullptr,EventOnActionChanged,3000,TRANS_TIMER},// State-3 - NextF = 2, NextT = 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}voidEventOnActionChanged(EventArgse) {switch (e.action) {caseENTRY:digitalWrite(lightPins[e.id],HIGH);// Set Light with the HIGH state.break;caseEXIT:digitalWrite(lightPins[e.id],LOW);// Set Light with the LOW state.break; }}
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | CoinPredicate | 0 | 1 | LockedProcess | - | - | - |
| 1 | PushPredicate | 1 | 0 | UnlockedProcess | - | - | - |
Transitiontransitions[]= { {CoinPredicate,0,1,LockedProcess},// State-0 - NextF = 0, NextT = 1 {PushPredicate,1,0,UnlockedProcess}// State-1 - NextF = 1, NextT = 0};
#include"FiniteState.h"#include"RepeatButton.h"#defineCOIN A0 // Define the Coin input pin.#definePUSH A1 // Define the Push input pin.#defineLOCKED 7 // Define the Locked state output pin.#defineUNLOCKED 6 // Define the Unlocked state output pin.boolCoinPredicate(id_tid);// Declare Coin Predicate functionboolPushPredicate(id_tid);// Declare Push Predicate functionvoidLockedProcess(id_tid);// Declare Locked Process functionvoidUnlockedProcess(id_tid);// Declare Unlocked Process functionTransitiontransitions[]= { {CoinPredicate,0,1,LockedProcess},// State-0 - NextF = 0, NextT = 1 {PushPredicate,1,0,UnlockedProcess}// State-1 - NextF = 1, NextT = 0};constuint8_tNumberOfTransitions=2;// Number Of TransitionsFiniteStatecoinOperatedTurnstile(transitions,NumberOfTransitions);// Finite-State ObjectRepeatButtoncoin;// Declare the Coin RepeatButton objectRepeatButtonpush;// Declare the Push RepeatButton objectvoidsetup() {coin.buttonMode(COIN,INPUT_PULLUP);// Set the Coin input pin modepush.buttonMode(PUSH,INPUT_PULLUP);// Set the Push input pin modepinMode(LOCKED,OUTPUT);// Set the Locked state pin modepinMode(UNLOCKED,OUTPUT);// Set the Unlocked state pin modecoinOperatedTurnstile.begin(0);// FSM begins with Initial Transition Id 0}voidloop() {coin.repeatButton();// Executing the Coin repeat button functionpush.repeatButton();// Executing the Push repeat button functioncoinOperatedTurnstile.execute();// Execute the FSM}boolCoinPredicate(id_tid) {returncoin.isPressed();// Predicate putting a coin.}boolPushPredicate(id_tid) {returnpush.isPressed();// Predicate pushing the arm.}voidLockedProcess(id_tid) {digitalWrite(LOCKED,HIGH);// Turn on the locked position status.digitalWrite(UNLOCKED,LOW);// Turn off the unlocked position status.}voidUnlockedProcess(id_tid) {digitalWrite(LOCKED,LOW);// Turn off the locked position status.digitalWrite(UNLOCKED,HIGH);// Turn on the unlocked position status.}
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | inputPredicate | 0 | 1 | nullptr | EventOnActionChanged | - | - |
| 1 | inputPredicate | 1 | 0 | nullptr | EventOnActionChanged | - | - |
Transitiontransitions[]= { {inputPredicate,0,1,nullptr,EventOnActionChanged},// State-0 - NextF = 0, NextT = 1 {inputPredicate,1,0,nullptr,EventOnActionChanged}// State-1 - NextF = 1, NextT = 0};
#include"FiniteState.h"#include"RepeatButton.h"#defineCOIN A0 // Define the Coin input pin.#definePUSH A1 // Define the Push input pin.#defineLOCKED 7 // Define the Locked state output pin.#defineUNLOCKED 6 // Define the Unlocked state output pin.boolinputPredicate(id_tid);// Declare Coin Predicate functionvoidEventOnActionChanged(EventArgse);// Event On Action ChangedTransitiontransitions[]= { {inputPredicate,0,1,nullptr,EventOnActionChanged},// State-0 - NextF = 0, NextT = 1 {inputPredicate,1,0,nullptr,EventOnActionChanged}// State-1 - NextF = 1, NextT = 0};constuint8_tNumberOfTransitions=2;// Number Of Transitionsuint8_tinputPins[NumberOfTransitions]= {COIN,PUSH};// Declare the Coin RepeatButton objectuint8_toutputPins[NumberOfTransitions]= {LOCKED,UNLOCKED};// Declare the Coin RepeatButton objectFiniteStatecoinOperatedTurnstile(transitions,NumberOfTransitions);// Finite-State ObjectRepeatButtonturnstileInputs[NumberOfTransitions];// Declare the Turnstile Inputs RepeatButton objectvoidsetup() {for (uint8_tindex=0;index<NumberOfTransitions;index++) {turnstileInputs[index].buttonMode(inputPins[index],INPUT_PULLUP);// Set the Turnstile repeat button pin modepinMode(outputPins[index],OUTPUT);// Set the Output state pin mode }coinOperatedTurnstile.begin(0);// FSM begins with Initial Transition Id 0}voidloop() {for (uint8_tindex=0;index<NumberOfTransitions;index++) {turnstileInputs[index].repeatButton();// Executing the Turnstile repeat button function }coinOperatedTurnstile.execute();// Execute the FSM}boolinputPredicate(id_tid) {returnturnstileInputs[id].isPressed();// Predicate putting a coin.}voidEventOnActionChanged(EventArgse) {switch (e.action) {caseENTRY:digitalWrite(outputPins[e.id],HIGH);// Turn on the turnstile position status.break;caseEXIT:digitalWrite(outputPins[e.id],LOW);// Turn off the previous turnstile position status.break; }}
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | nullptr | 0 | 1 | TurnON | nullptr | 500 | TRANS_TIMER |
| 1 | nullptr | 1 | 2 | TurnOFF | nullptr | 1,000 | TRANS_TIMER |
Transitiontransitions[]= { {nullptr,0,1,TurnON,nullptr,500,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1 {nullptr,1,0,TurnOFF,nullptr,1000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};
#include"FiniteState.h"voidTurnON(id_tid);// Declare Turn LED On Process functionvoidTurnOFF(id_tid);// Declare Turn LED Off Process functionTransitiontransitions[]= { {nullptr,0,1,TurnON,nullptr,500,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1 {nullptr,1,0,TurnOFF,nullptr,1000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tNumberOfTransitions=2;// Number Of TransitionsFiniteStateblinkFS(transitions,NumberOfTransitions);// Finite-State Objectvoidsetup() {pinMode(LED_BUILTIN,OUTPUT);// Set the LED_BUILTIN pin modeblinkFS.begin(0);// FSM begins with Initial Transition Id 0}voidloop() {blinkFS.execute();// Execute the FSM}voidTurnON(id_tid) {digitalWrite(LED_BUILTIN,HIGH);// Turn on the LED.}voidTurnOFF(id_tid) {digitalWrite(LED_BUILTIN,LOW);// Turn off the LED.}
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | ReadButton | 0 | 1 | Released | - | - | - |
| 1 | ReadButton | 0 | 2 | nullptr | nullptr | 10 | TRUE_TIMER |
| 2 | ReadButton | 3 | 2 | Pressed | - | - | - |
| 3 | ReadButton | 0 | 2 | nullptr | nullptr | 10 | FALSE_TIMER |
Transitiontransitions[]= { {ReadButton,0,1,Released},// State-0 - NextF = 0, NextT = 1 {ReadButton,0,2,nullptr,nullptr,10,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2 {ReadButton,3,2,Pressed},// State-2 - NextF = 3, NextT = 2 {ReadButton,0,2,nullptr,nullptr,10,FALSE_TIMER}// State-3 - NextF = 0, NextT = 2};
#include"FiniteState.h"#defineBUTTON A0 // Define the button input pin.#defineLED 7 // Define the LED output pin.#definedebounce 10 // Debounce Delay 10 millisecondsboolReadButton(id_tid);// Declare Read Button Predicate functionvoidReleased(id_tid);// Declare Released Process functionvoidPressed(id_tid);// Declare Pressed Process functionTransitiontransitions[]= { {ReadButton,0,1,Released},// State-0 - NextF = 0, NextT = 1 {ReadButton,0,2,nullptr,nullptr,debounce,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2 {ReadButton,3,2,Pressed},// State-2 - NextF = 3, NextT = 2 {ReadButton,0,2,nullptr,nullptr,debounce,FALSE_TIMER}// State-3 - NextF = 0, NextT = 2};constuint8_tNumberOfTransitions=4;// Number Of TransitionsFiniteStatedebounceFS(transitions,NumberOfTransitions);// Finite-State Objectboolstate;voidsetup() {pinMode(BUTTON,INPUT_PULLUP);// Set the Button pin modepinMode(LED,OUTPUT);// Set the LED pin modedebounceFS.begin(0);// FSM begins with Initial Transition Id 0}voidloop() {debounceFS.execute();// Execute the FSMdigitalWrite(LED,state);// Set LED with the state.}boolReadButton(id_tid) {return !digitalRead(BUTTON);// Read Button value.}voidReleased(id_tid) {state= false;// Set the state with false value.}voidPressed(id_tid) {state= true;// Set the state with true value.}
| Id | Predicate | Next State - F | Next State - T | Process | Event | Delay Time (mS) | Timer Type |
|---|---|---|---|---|---|---|---|
| 0 | AnalogPredicate | 0 | 1 | NormalProcess | - | - | - |
| 1 | AnalogPredicate | 0 | 2 | PreAlarmProcess | nullptr | alarmDelay | TRUE_TIMER |
| 2 | AnalogPredicate | 2 | 0 | HighAlarmProcess | - | - | - |
Transitiontransitions[]= { {AnalogPredicate,0,1,NormalProcess},// State-0 - NextF = 0, NextT = 1 {AnalogPredicate,0,2,PreAlarmProcess,nullptr,alarmDelay,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2 {AnalogPredicate,2,0,HighAlarmProcess}// State-2 - NextF = 2, NextT = 0};
#include"FiniteState.h"#defineprocessValuePin A0 // Define the Process value input pin.#definenormalPin 6 // Define the normal status output pin.#definepreAlarmPin 5 // Define the pre-alarm status output pin.#definehighAlarmPin 4 // Define the high-alarm status output pin.enumOperator {LT,// Less than operatorLE,// Less than or equal operatorGT,// Greater than operatorGE// Greater than or equal operator};constlongsetpoint=85;// Alarm Setpointconstlongdeadband=5;// Alarm DeadbandOperatoroperators []= {GE,GE,LT};// Comparison operatorslongsetpoints []= {setpoint,setpoint,setpoint-deadband};// Comparison setpointsconstlongAnalogRead();// Declare Analog Read FunctionvoidProcessAlarmStatus(boolnormal,boolpreAlarm,boolhighAlarm);// Declare Process Alarm Status FunctionlongprocessValue;// Declare processValue variableboolAnalogPredicate(id_tid);// Declare analog predicate FunctionvoidNormalProcess(id_tid);// Declare normal process FunctionvoidPreAlarmProcess(id_tid);// Declare pre-alarm process FunctionvoidHighAlarmProcess(id_tid);// Declare high-alarm process Function#definealarmDelay 3000 // Define alarm dalayTransitiontransitions[]= { {AnalogPredicate,0,1,NormalProcess},// State-0 - NextF = 0, NextT = 1 {AnalogPredicate,0,2,PreAlarmProcess,nullptr,alarmDelay,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2 {AnalogPredicate,2,0,HighAlarmProcess}// State-2 - NextF = 2, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Number of TransitionsFiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Objectvoidsetup() {pinMode(normalPin,OUTPUT);// Set the normal LED pin modepinMode(preAlarmPin,OUTPUT);// Set the pre-alarm LED pin modepinMode(highAlarmPin,OUTPUT);// Set the hith-alarm LED= pin modefiniteStateMachine.begin(0);// FSM begins with Initial Transition Id 0}voidloop() {finiteStateMachine.execute();// Execute the FSMprocessValue=AnalogRead();// Read processValue}voidNormalProcess(id_tid) {ProcessAlarmStatus(true, false, false);// Update process alarm status}voidPreAlarmProcess(id_tid) {ProcessAlarmStatus(false, true, false);// Update process alarm status}voidHighAlarmProcess(id_tid) {ProcessAlarmStatus(false, true, true);// Update process alarm status}boolAnalogPredicate(id_tid) {boolvalue;switch (operators[id]) {caseGE:value=processValue >=setpoints[id];// Compare process value with setpointbreak;caseLT:value=processValue<setpoints[id];// Compare process value with setpointbreak;default:value= false;break; }returnvalue;}voidProcessAlarmStatus(boolnormal,boolpreAlarm,boolhighAlarm) {digitalWrite(normalPin,normal);// Update normal statusdigitalWrite(preAlarmPin,preAlarm);// Update pre-alarm statusdigitalWrite(highAlarmPin,highAlarm);// Update high-alarm status}constlongAnalogRead() {longvalue=analogRead(processValuePin);// Read Process Valuereturnmap(value,0,1023,0,100);// Scaling processValue}
WikipediaFinite-State Machine
MathWorksModel Finite State Machines
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.





