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

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

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 condition for the next state is determined by the Predicate function's return value.

Not-Used Timer Next-State Flow

Typical Not-Used Timer State Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateCallbackFunction01ProcessCallbackFunctionEventCallbackFunction--
1PredicateCallbackFunction10ProcessCallbackFunctionEventCallbackFunction--

State-Transition Table -> Transition Declaration

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

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.

Transition-Timer Next-State Flow

Typical Transition-Timer State Diagram

|

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0nullptr01ProcessCallbackFunctionEventCallbackFunction3,000TRANS_TIMER
1nullptr10ProcessCallbackFunctionEventCallbackFunction5,000TRANS_TIMER

State-Transition Table -> Transition Declaration

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

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.

Predicate-Timer Next-State Flow

Typical Predicate-Timer State Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateCallbackFunction01ProcessCallbackFunctionEventCallbackFunction3,000PREDIC_TIMER
1PredicateCallbackFunction10ProcessCallbackFunctionEventCallbackFunction5,000PREDIC_TIMER

State-Transition Table -> Transition Declaration

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

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.

False-Timer Next-State Flow

Typical False-Timer State Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateCallbackFunction10ProcessCallbackFunctionEventCallbackFunction3,000FALSE_TIMER
1PredicateCallbackFunction01ProcessCallbackFunctionEventCallbackFunction5,000FALSE_TIMER

State-Transition Table -> Transition Declaration

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

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.

True-Timer Next-State Flow

Typical True-Timer State Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0PredicateCallbackFunction01ProcessCallbackFunctionEventCallbackFunction3,000TRUE_TIMER
1PredicateCallbackFunction10ProcessCallbackFunctionEventCallbackFunction5,000TRUE_TIMER

State-Transition Table -> Transition Declaration

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

Example

Fan Control With A Thermostat

State Diagram

Wiring Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0FanStartPredicate01StartFanProcess---
1FanStopPredicate10StopFanProcess---

State-Transition Table -> Transition Declaration

Transitiontransitions[]= {  {FanStartPredicate,0,1,StartFanProcess},// State-0 - NextF = 0, NextT = 1  {FanStopPredicate,1,0,StopFanProcess}// State-1 - NextF = 1, NextT = 0};

Sketch

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

Traffic Light

Traffic Light with Customized Timer (NOT_USED)

State Diagram

Wiring Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0DelayTimePredicate01nullptrEventOnActionChanged--
1DelayTimePredicate12nullptrEventOnActionChanged--
2DelayTimePredicate20nullptrEventOnActionChanged--

State-Transition Table -> Transition Declaration

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

Sketch

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

Traffic Light with Transition Timer (TRANS_TIMER)

State Diagram

Wiring Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0nullptr01nullptrEventOnActionChanged5,000TRANS_TIMER
1nullptr12nullptrEventOnActionChanged10,000TRANS_TIMER
2nullptr20nullptrEventOnActionChanged3,000TRANS_TIMER

State-Transition Table -> 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};

Sketch

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

Coin Operated Turnstile

Coin Operated Turnstile with Predicate and Process

State Diagram

Wiring Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0CoinPredicate01LockedProcess---
1PushPredicate10UnlockedProcess---

State-Transition Table -> Transition Declaration

Transitiontransitions[]= {  {CoinPredicate,0,1,LockedProcess},// State-0 - NextF = 0, NextT = 1  {PushPredicate,1,0,UnlockedProcess}// State-1 - NextF = 1, NextT = 0};

Sketch

#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.}

Coin Operated Turnstile with Predicate and Event

State Diagram

Wiring Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0inputPredicate01nullptrEventOnActionChanged--
1inputPredicate10nullptrEventOnActionChanged--

State-Transition Table -> 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};

Sketch

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

Blink

State Diagram

Wiring Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0nullptr01TurnONnullptr500TRANS_TIMER
1nullptr12TurnOFFnullptr1,000TRANS_TIMER

State-Transition Table -> Transition Declaration

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

Sketch

#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.}

Debounce

State Diagram

Wiring Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0ReadButton01Released---
1ReadButton02nullptrnullptr10TRUE_TIMER
2ReadButton32Pressed---
3ReadButton02nullptrnullptr10FALSE_TIMER

State-Transition Table -> Transition Declaration

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

Sketch

#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.}

Analog High-Alarm

State Diagram

Wiring Diagram

State-Transition Table

IdPredicateNext State - FNext State - TProcessEventDelay Time (mS)Timer Type
0AnalogPredicate01NormalProcess---
1AnalogPredicate02PreAlarmProcessnullptralarmDelayTRUE_TIMER
2AnalogPredicate20HighAlarmProcess---

State-Transition Table -> Transition Declaration

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

Sketch

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

References


[8]ページ先頭

©2009-2025 Movatter.jp