Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Finite-State Machine (FSM) for Arduino

License

NotificationsYou must be signed in to change notification settings

MicroBeaut/Finite-State

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

78 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Finite-State

Finite-State Machine for Arduino

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;

Predicate Function

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; }

Next State

A Next-State has two destinations:

  1. 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 isFALSE.

  2. 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 isTRUE.

Process Function

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;

Event Handler Function

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 idActionaction;// Action State}EventArgs;

Action:

enumAction {NONE,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;caseEXIT:digitalWrite(motor[e.id].output, false);break;  }}

Timer

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};

Not Used Timer (NOT_USED)

When Timer is not used, The predicate function is nonnullptr. The Predicate function's return value determines the condition for the next state.

Not-Used Timer State Diagram

State transitions can be defined as three options,

Predicate Function with Process and Event

Typical Predicate Function with Process and Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01ProcessFunctionEventOnActionChanged--
1PredicateFunction10ProcessFunctionEventOnActionChanged--

State-Transition Declaration

boolPredicateFunction(id_tid);voidProcessFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {PredicateFunction,0,1,ProcessFunction,EventOnActionChanged},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,ProcessFunction,EventOnActionChanged}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Predicate Function with Process

Typical Predicate Function with Process State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01ProcessFunction---
1PredicateFunction10ProcessFunction---

State-Transition Declaration

boolPredicateFunction(id_tid);voidProcessFunction(id_tid);Transitiontransitions[]= {  {PredicateFunction,0,1,ProcessFunction},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,ProcessFunction}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Predicate Function with Event

Typical Predicate Function with Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01-EventOnActionChanged--
1PredicateFunction10-EventOnActionChanged--

State-Transition Declaration

boolPredicateFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {PredicateFunction,0,1,nullptr,EventOnActionChanged},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,nullptr,EventOnActionChanged}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Transition Timer (TRANS_TIMER)

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. The predicate function isnullptr.

Transition-Timer State Diagram

State transitions can be defined as three options,

Transition Timer with Process and Event

Typical Transition Timer with Process and Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0-01ProcessFunctionEventOnActionChanged1,000TRANS_TIMER
1-10ProcessFunctionEventOnActionChanged1,000TRANS_TIMER

State-Transition Declaration

voidProcessFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {nullptr,0,1,ProcessFunction,EventOnActionChanged,1000,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1  {nullptr,1,0,ProcessFunction,EventOnActionChanged,1000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Transition Timer with Process

Typical Transition Timer with Process State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0-01ProcessFunction-1,000TRANS_TIMER
1-10ProcessFunction-1,000TRANS_TIMER

State-Transition Declaration

voidProcessFunction(id_tid);Transitiontransitions[]= {  {nullptr,0,1,ProcessFunction,nullptr,1000,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1  {nullptr,1,0,ProcessFunction,nullptr,1000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Transition Timer with Event

Typical Transition Timer with Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0-01-EventOnActionChanged1,000TRANS_TIMER
1-10-EventOnActionChanged1,000TRANS_TIMER

State-Transition Declaration

voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {nullptr,0,1,nullptr,EventOnActionChanged,1000,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1  {nullptr,1,0,nullptr,EventOnActionChanged,1000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Predicate Timer (PREDIC_TIMER)

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. The predicate function is nonnullptr.

Predicate-Timer State Diagram

State transitions can be defined as three options,

Predicate Timer with Process and Event

Typical Predicate Timer with Process and Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01ProcessFunctionEventOnActionChanged1,000PREDIC_TIMER
1PredicateFunction10ProcessFunctionEventOnActionChanged1,000PREDIC_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidProcessFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {PredicateFunction,0,1,ProcessFunction,EventOnActionChanged,1000,PREDIC_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,ProcessFunction,EventOnActionChanged,1000,PREDIC_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Predicate Timer with Process

Typical Predicate Timer with Process State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01ProcessFunction-1,000PREDIC_TIMER
1PredicateFunction10ProcessFunction-1,000PREDIC_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidProcessFunction(id_tid);Transitiontransitions[]= {  {PredicateFunction,0,1,ProcessFunction,nullptr,1000,PREDIC_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,ProcessFunction,nullptr,1000,PREDIC_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Predicate Timer with Event

Typical Predicate Timer with Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01-EventOnActionChanged1,000PREDIC_TIMER
1PredicateFunction10-EventOnActionChanged1,000PREDIC_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {PredicateFunction,0,1,nullptr,EventOnActionChanged,1000,PREDIC_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,nullptr,EventOnActionChanged,1000,PREDIC_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

False-State Timer (FALSE_TIMER)

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. The predicate function is nonnullptr.

False-Timer State Diagram

State transitions can be defined as three options,

False Timer with Process and Event

Typical False Timer with Process and Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01ProcessFunctionEventOnActionChanged1,000FALSE_TIMER
1PredicateFunction10ProcessFunctionEventOnActionChanged1,000FALSE_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidProcessFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {PredicateFunction,0,1,ProcessFunction,EventOnActionChanged,1000,FALSE_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,ProcessFunction,EventOnActionChanged,1000,FALSE_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

False Timer with Process

Typical False Timer with Process State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01ProcessFunction-1,000FALSE_TIMER
1PredicateFunction10ProcessFunction-1,000FALSE_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidProcessFunction(id_tid);Transitiontransitions[]= {  {PredicateFunction,0,1,ProcessFunction,nullptr,1000,FALSE_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,ProcessFunction,nullptr,1000,FALSE_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

False Timer with Event

Typical False Timer with Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01-EventOnActionChanged1,000FALSE_TIMER
1PredicateFunction10-EventOnActionChanged1,000FALSE_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {PredicateFunction,0,1,nullptr,EventOnActionChanged,1000,FALSE_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,nullptr,EventOnActionChanged,1000,FALSE_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

True-State Timer (TRUE_TIMER)

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. The predicate function is nonnullptr.

True-Timer State Diagram

State transitions can be defined as three options,

True Timer with Process and Event

Typical True Timer with Process and event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01ProcessFunctionEventOnActionChanged1,000TRUE_TIMER
1PredicateFunction10ProcessFunctionEventOnActionChanged1,000TRUE_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidProcessFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {PredicateFunction,0,1,ProcessFunction,EventOnActionChanged,1000,TRUE_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,ProcessFunction,EventOnActionChanged,1000,TRUE_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

True Timer with Process

Typical True Timer with Process State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01ProcessFunction-1,000TRUE_TIMER
1PredicateFunction10ProcessFunction-1,000TRUE_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidProcessFunction(id_tid);Transitiontransitions[]= {  {PredicateFunction,0,1,ProcessFunction,nullptr,1000,TRUE_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,ProcessFunction,nullptr,1000,TRUE_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

True Timer with Event

Typical True Timer with Event State Diagram

State-Transition Table
IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateFunction01-EventOnActionChanged1,000TRUE_TIMER
1PredicateFunction10-EventOnActionChanged1,000TRUE_TIMER

State-Transition Declaration

boolPredicateFunction(id_tid);voidEventOnActionChanged(EventArgse);Transitiontransitions[]= {  {PredicateFunction,0,1,nullptr,EventOnActionChanged,1000,TRUE_TIMER},// State-0 - NextF = 0, NextT = 1  {PredicateFunction,1,0,nullptr,EventOnActionChanged,1000,TRUE_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Example

Fan Control With A Thermostat

State Diagram

Schematic Diagram

State-Transition Table Table

StateIdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
STOP0HighTempPredicate01FanStopProcess---
START1LowTempPredicate10FanStartProcess---

State-Transition Declaration

Transitiontransitions[]= {  {HighTempPredicate,0,1,FanStopProcess},// State-0 - NextF = 0, NextT = 1  {LowTempPredicate,1,0,FanStartProcess}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Or,

enumFanState :id_t {STOP,START};Transitiontransitions[]= {  {HighTempPredicate,STOP,START,FanStopProcess},// State-0 - NextF = 0, NextT = 1  {LowTempPredicate,START,STOP,FanStartProcess}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Sketch

WokwiFan Control With A Thermostat

#include"FiniteState.h"#definethermostatPin   A0#definestartStatusPin  5#definestopStatusPin   6voidFanStartProcess(id_tid);voidFanStopProcess(id_tid);boolHighTempPredicate(id_tstate);boolLowTempPredicate(id_tstate);enumFanState :id_t {STOP,START};Transitiontransitions[]= {  {HighTempPredicate,STOP,START,FanStopProcess},// State-0 - NextF = 0, NextT = 1  {LowTempPredicate,START,STOP,FanStartProcess}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State ObjectconstlongThermostatRead();voidsetup() {pinMode(startStatusPin,OUTPUT);// Set the start status pin modepinMode(stopStatusPin,OUTPUT);// Set the sotp status pin modefiniteStateMachine.begin(STOP);// FSM begins with Initial Transition Id 0}voidloop() {finiteStateMachine.execute();// Execute the FSM}boolHighTempPredicate(id_tstate) {returnThermostatRead() >=40;// Determine Fan Start Action}boolLowTempPredicate(id_tstate) {returnThermostatRead() <=30;// Determine Fan Stop Action}voidFanStartProcess(id_tid) {digitalWrite(stopStatusPin, false);// Update fan stop statusdigitalWrite(startStatusPin, true);// Update fan start status}voidFanStopProcess(id_tid) {digitalWrite(startStatusPin, false);// Update fan start statusdigitalWrite(stopStatusPin, true);// Update fan stop status}constlongThermostatRead() {longvalue=analogRead(thermostatPin);// Read Pushbutton Valuereturnmap(value,0,1023,0,100);// Scaling temperature}

Traffic Light

Traffic Light with Customized Timer (NOT_USED)

State Diagram

Schematic Diagram

State-Transition Table Table

StateIdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
RED0TimePredicate01-EventOnActionChanged--
GREEN1TimePredicate12-EventOnActionChanged--
YELLOW2TimePredicate20-EventOnActionChanged--

State-Transition Declaration

Transitiontransitions[]= {  {TimePredicate,0,1,nullptr,EventOnActionChanged},// State-1 - NextF = 0, NextT = 1  {TimePredicate,1,2,nullptr,EventOnActionChanged},// State-2 - NextF = 1, NextT = 2  {TimePredicate,2,0,nullptr,EventOnActionChanged},// State-3 - NextF = 2, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Or,

enumLightState {RED,GREEN,YELLOW};Transitiontransitions[]= {  {TimePredicate,RED,GREEN,nullptr,EventOnActionChanged},// State-1 - NextF = 0, NextT = 1  {TimePredicate,GREEN,YELLOW,nullptr,EventOnActionChanged},// State-2 - NextF = 1, NextT = 2  {TimePredicate,YELLOW,RED,nullptr,EventOnActionChanged},// State-3 - NextF = 2, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Sketch

WokwiTraffic Light with Customized Timer

#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};boolTimePredicate(id_tid);// Predicate (Input)voidEventOnActionChanged(EventArgse);// Event StateenumLightState {RED,GREEN,YELLOW};Transitiontransitions[]= {  {TimePredicate,RED,GREEN,nullptr,EventOnActionChanged},// State-1 - NextF = 0, NextT = 1  {TimePredicate,GREEN,YELLOW,nullptr,EventOnActionChanged},// State-2 - NextF = 1, NextT = 2  {TimePredicate,YELLOW,RED,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(RED);// FSM begins with Initial Transition Id 0}voidloop() {finiteStateMachine.execute();// Execute the FSM}boolTimePredicate(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;  }}

Traffic Light with Transition Timer (TRANS_TIMER)

State Diagram

Schematic Diagram

State-Transition Table Table

StateIdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
RED0-01-EventOnActionChanged5,000TRANS_TIMER
GREEN1-12-EventOnActionChanged10,000TRANS_TIMER
YELLOW2-20-EventOnActionChanged3,000TRANS_TIMER

State-Transition Declaration

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};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Or,

enumLightState :id_t {RED,GREEN,YELLOW};Transitiontransitions[]= {  {nullptr,RED,GREEN,nullptr,EventOnActionChanged,5000,TRANS_TIMER},// State-1 - NextF = 0, NextT = 1  {nullptr,GREEN,YELLOW,nullptr,EventOnActionChanged,10000,TRANS_TIMER},// State-2 - NextF = 1, NextT = 2  {nullptr,YELLOW,RED,nullptr,EventOnActionChanged,3000,TRANS_TIMER},// State-3 - NextF = 2, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Sketch

WokwiTraffic Light with Transition Timer

#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 StateenumLightState :id_t {RED,GREEN,YELLOW};Transitiontransitions[]= {  {nullptr,RED,GREEN,nullptr,EventOnActionChanged,5000,TRANS_TIMER},// State-1 - NextF = 0, NextT = 1  {nullptr,GREEN,YELLOW,nullptr,EventOnActionChanged,10000,TRANS_TIMER},// State-2 - NextF = 1, NextT = 2  {nullptr,YELLOW,RED,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(RED);// 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;  }}

Coin Operated Turnstile

Coin Operated Turnstile with Predicate and Process

State Diagram

Schematic Diagram

State-Transition Table Table

StateIdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
LOCKED0CoinPredicate01LockedProcess---
UNLOCKED1ArmPredicate10UnlockedProcess---

State-Transition Declaration

Transitiontransitions[]= {  {CoinPredicate,0,1,LockedProcess},// State-0 - NextF = 0, NextT = 1  {ArmPredicate,1,0,UnlockedProcess}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Or,

enumTurnstileState :id_t {LOCKED,UNLOCKED};Transitiontransitions[]= {  {CoinPredicate,LOCKED,UNLOCKED,LockedProcess},// State-0 - NextF = 0, NextT = 1  {ArmPredicate,UNLOCKED,LOCKED,UnlockedProcess}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Sketch

WokwiCoin Operated Turnstile with Predicate and Process

#include"FiniteState.h"#include"RepeatButton.h"#definecoinInputPin      A0    // Define the Coin input pin.#definearmInputPin       A1    // Define the Arm input pin.#definelockedStatusPin   7     // Define the Locked state output pin.#defineunlockedStatusPin 6     // Define the Unlocked state output pin.boolCoinPredicate(id_tid);// Declare Coin Predicate functionboolArmPredicate(id_tid);// Declare Arm Predicate functionvoidLockedProcess(id_tid);// Declare Locked Process functionvoidUnlockedProcess(id_tid);// Declare Unlocked Process functionenumTurnstileState :id_t {LOCKED,UNLOCKED};Transitiontransitions[]= {  {CoinPredicate,LOCKED,UNLOCKED,LockedProcess},// State-0 - NextF = 0, NextT = 1  {ArmPredicate,UNLOCKED,LOCKED,UnlockedProcess}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatecoinOperatedTurnstile(transitions,numberOfTransitions);// Finite-State ObjectRepeatButtoncoin;// Declare the Coin RepeatButton objectRepeatButtonarm;// Declare the Arm RepeatButton objectvoidsetup() {coin.buttonMode(coinInputPin,INPUT_PULLUP);// Set the Coin input pin modearm.buttonMode(armInputPin,INPUT_PULLUP);// Set the Arm input pin modepinMode(lockedStatusPin,OUTPUT);// Set the Locked state pin modepinMode(unlockedStatusPin,OUTPUT);// Set the Unlocked state pin modecoinOperatedTurnstile.begin(LOCKED);// FSM begins with Initial Transition Id 0}voidloop() {coin.repeatButton();// Executing the Coin repeat button functionarm.repeatButton();// Executing the Arm repeat button functioncoinOperatedTurnstile.execute();// Execute the FSM}boolCoinPredicate(id_tid) {returncoin.isPressed();// Predicate putting a coin.}boolArmPredicate(id_tid) {returnarm.isPressed();// Predicate pushing the arm.}voidLockedProcess(id_tid) {digitalWrite(lockedStatusPin,HIGH);// Turn on the locked position status.digitalWrite(unlockedStatusPin,LOW);// Turn off the unlocked position status.}voidUnlockedProcess(id_tid) {digitalWrite(lockedStatusPin,LOW);// Turn off the locked position status.digitalWrite(unlockedStatusPin,HIGH);// Turn on the unlocked position status.}

Coin Operated Turnstile with Predicate and Event

State Diagram

Schematic Diagram

State-Transition Table Table

StateIdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
LOCKED0CoinPredicate01-EventOnActionChanged--
UNLOCKED1ArmPredicate10-EventOnActionChanged--

State-Transition Declaration

Transitiontransitions[]= {  {inputPredicate,0,1,nullptr,EventOnActionChanged},// State-0 - NextF = 0, NextT = 1  {inputPredicate,1,0,nullptr,EventOnActionChanged}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Or,

enumTurnstileState :id_t {LOCKED,UNLOCKED};Transitiontransitions[]= {  {inputPredicate,LOCKED,UNLOCKED,nullptr,EventOnActionChanged},// State-0 - NextF = 0, NextT = 1  {inputPredicate,UNLOCKED,LOCKED,nullptr,EventOnActionChanged}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Sketch

WokwiCoin Operated Turnstile with Predicate and Event

#include"FiniteState.h"#include"RepeatButton.h"#definecoinInputPin      A0  // Define the Coin input pin.#definearmInputPin       A1  // Define the Push input pin.#definelockedStatusPin   7   // Define the Locked state output pin.#defineunlockedStatusPin 6   // Define the Unlocked state output pin.boolinputPredicate(id_tid);// Declare Coin Predicate functionvoidEventOnActionChanged(EventArgse);// Event On Action ChangedenumTurnstileState :id_t {LOCKED,UNLOCKED};Transitiontransitions[]= {  {inputPredicate,LOCKED,UNLOCKED,nullptr,EventOnActionChanged},// State-0 - NextF = 0, NextT = 1  {inputPredicate,UNLOCKED,LOCKED,nullptr,EventOnActionChanged}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatecoinOperatedTurnstile(transitions,numberOfTransitions);// Finite-State Objectuint8_tinputPins[numberOfTransitions]= {coinInputPin,armInputPin};// Declare the input pin arrayuint8_toutputPins[numberOfTransitions]= {lockedStatusPin,unlockedStatusPin};// Declare the output pin arrayRepeatButtonturnstileInputs[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(LOCKED);// 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 and pushing the arm.}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;  }}

Blink

State Diagram

Schematic Diagram

State-Transition Table Table

StateIdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
LED_OFF0-01TurnOffProcess-500TRANS_TIMER
LED_ON1-10TrunOnProcess-1,000TRANS_TIMER

State-Transition Declaration

Transitiontransitions[]= {  {nullptr,0,1,TurnOffProcess,nullptr,500,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1  {nullptr,1,0,TrunOnProcess,nullptr,1000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Or,

enumLedState :id_t {LED_OFF,LED_ON};Transitiontransitions[]= {  {nullptr,LED_OFF,LED_ON,TurnOffProcess,nullptr,500,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1  {nullptr,LED_ON,LED_OFF,TrunOnProcess,nullptr,1000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Sketch

WokwiBlink

#include"FiniteState.h"voidTrunOnProcess(id_tid);// Declare Turn LED On Process functionvoidTurnOffProcess(id_tid);// Declare Turn LED Off Process functionenumLedState :id_t {LED_OFF,LED_ON};Transitiontransitions[]= {  {nullptr,LED_OFF,LED_ON,TurnOffProcess,nullptr,500,TRANS_TIMER},// State-0 - NextF = 0, NextT = 1  {nullptr,LED_ON,LED_OFF,TrunOnProcess,nullptr,1000,TRANS_TIMER}// State-1 - NextF = 1, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStateblinkFS(transitions,numberOfTransitions);// Finite-State Objectvoidsetup() {pinMode(LED_BUILTIN,OUTPUT);// Set the LED_BUILTIN pin modeblinkFS.begin(LED_OFF);// FSM begins with Initial Transition Id 0}voidloop() {blinkFS.execute();// Execute the FSM}voidTrunOnProcess(id_tid) {digitalWrite(LED_BUILTIN,HIGH);// Turn on the LED.}voidTurnOffProcess(id_tid) {digitalWrite(LED_BUILTIN,LOW);// Turn off the LED.}

Debounce

State Diagram

Schematic Diagram

State-Transition Table Table

StateIdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
RELEASED0ButtonPredicate01ReleasedProcess---
DEBOUNCE_T1ButtonPredicate02--10TRUE_TIMER
PRESSED2ButtonPredicate32PressedProcess---
DEBOUNCE_F3ButtonPredicate02--10FALSE_TIMER

State-Transition Declaration

#definedebounce 10                                                             // Debounce Delay 10 millisecondsTransitiontransitions[]= {  {ButtonPredicate,0,1,ReleasedProcess},// State-0 - NextF = 0, NextT = 1  {ButtonPredicate,0,2,nullptr,nullptr,debounce,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2  {ButtonPredicate,3,2,PressedProcess},// State-2 - NextF = 3, NextT = 2  {ButtonPredicate,0,2,nullptr,nullptr,debounce,FALSE_TIMER}// State-3 - NextF = 0, NextT = 2};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Or,

enumDebounceState :id_t {RELEASED,DEBOUNCE_T,PRESSED,DEBOUNCE_F};#definedebounce 10                                                             // Debounce Delay 10 millisecondsTransitiontransitions[]= {  {ButtonPredicate,RELEASED,DEBOUNCE_T,ReleasedProcess},// State-0 - NextF = 0, NextT = 1  {ButtonPredicate,RELEASED,PRESSED,nullptr,nullptr,debounce,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2  {ButtonPredicate,DEBOUNCE_F,PRESSED,PressedProcess},// State-2 - NextF = 3, NextT = 2  {ButtonPredicate,RELEASED,PRESSED,nullptr,nullptr,debounce,FALSE_TIMER}// State-3 - NextF = 0, NextT = 2};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.

Sketch

WokwiDebounce

#include"FiniteState.h"#definebuttonPin A0  // Define the Button input pin.#defineledPin    7   // Define the LED output pin.boolButtonPredicate(id_tid);// Declare Read Button Predicate functionvoidReleasedProcess(id_tid);// Declare Released Process functionvoidPressedProcess(id_tid);// Declare Pressed Process functionenumDebounceState :id_t {RELEASED,DEBOUNCE_T,PRESSED,DEBOUNCE_F};#definedebounce 10             // Debounce Delay 10 millisecondsTransitiontransitions[]= {  {ButtonPredicate,RELEASED,DEBOUNCE_T,ReleasedProcess},// State-0 - NextF = 0, NextT = 1  {ButtonPredicate,RELEASED,PRESSED,nullptr,nullptr,debounce,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2  {ButtonPredicate,DEBOUNCE_F,PRESSED,PressedProcess},// State-2 - NextF = 3, NextT = 2  {ButtonPredicate,RELEASED,PRESSED,nullptr,nullptr,debounce,FALSE_TIMER}// State-3 - NextF = 0, NextT = 2};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatedebounceFS(transitions,numberOfTransitions);// Finite-State ObjectboolbuttonState;voidsetup() {pinMode(buttonPin,INPUT_PULLUP);// Set the Button input modepinMode(ledPin,OUTPUT);// Set the LED output pin modedebounceFS.begin(RELEASED);// FSM begins with Initial Transition Id 0}voidloop() {debounceFS.execute();// Execute the FSMdigitalWrite(ledPin,buttonState);// Set LED with the button State.}boolButtonPredicate(id_tid) {return !digitalRead(buttonPin);// Read Button value.}voidReleasedProcess(id_tid) {buttonState= false;// Set the Button state with false value.}voidPressedProcess(id_tid) {buttonState= true;// Set the Button state with true value.}

Analog High-Alarm

State Diagram

Schematic Diagram

State-Transition Table Table

StateIdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
NORMAL0AnalogPredicate01NormalProcess---
PRE_ALARM1AnalogPredicate02PreAlarmProcess-3,000TRUE_TIMER
HIGH_ALARM2AnalogPredicate20HighAlarmProcess---

State-Transition Declaration

#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);// Calculate the number of transitions.

Or,

enumAnalogState :id_t {NORMAL,PRE_ALARM,HIGH_ALARM};#definealarmDelay 3000                                                                     // Define alarm dalayTransitiontransitions[]= {  {AnalogPredicate,NORMAL,PRE_ALARM,NormalProcess},// State-0 - NextF = 0, NextT = 1  {AnalogPredicate,NORMAL,HIGH_ALARM,PreAlarmProcess,nullptr,alarmDelay,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2  {AnalogPredicate,HIGH_ALARM,NORMAL,HighAlarmProcess}// State-2 - NextF = 2, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(transitions,numberOfTransitions);// Finite-State Object

Sketch

WokwiAnalog High-Alarm

#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 FunctionenumAnalogState :id_t {NORMAL,PRE_ALARM,HIGH_ALARM};#definealarmDelay 3000                                                                     // Define alarm dalayTransitiontransitions[]= {  {AnalogPredicate,NORMAL,PRE_ALARM,NormalProcess},// State-0 - NextF = 0, NextT = 1  {AnalogPredicate,NORMAL,HIGH_ALARM,PreAlarmProcess,nullptr,alarmDelay,TRUE_TIMER},// State-1 - NextF = 0, NextT = 2  {AnalogPredicate,HIGH_ALARM,NORMAL,HighAlarmProcess}// State-2 - NextF = 2, NextT = 0};constuint8_tnumberOfTransitions=sizeof(transitions) /sizeof(Transition);// Calculate the number of transitions.FiniteStatefiniteStateMachine(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(NORMAL);// 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}

References


[8]ページ先頭

©2009-2025 Movatter.jp