Pointer tutorial image

State Machine Tutorial Pt/3

State Machine tutorial part 3.

In this third part of the state machine tutorial some improvements to the C programming code shown in part 2 will be made, the code is still based on the state machine diagram shown in part 1.

Removing the Global Variable

The first improvement will remove the global variable Current_State, using this as a local variable in the main function.  Firstly we have to declare the function prototype for the StateMachine function as follows:

The main function needs to change, so the function call for StateMachine function reflects the change in the function prototype, so it has 2 parameters.

Addtionally a local variable to main is declared enum states Current_State = S_OFF;

Now the StateMachine function has 2 parameters,  enum events event and enum states Current_State;

The enum events event parameter relates to the returned value from the ReadKeyInput function, this is called by the StateMachine function as per the previous code example.

The enum states Current_State parameter returns the value of the Next_State variable inside the StateMachine function.  There is a return Next_State; statement at the end of the StateMachine function, the only other change is to the StateMachine function declaration as with the function prototype ensuring the parameters match.

LookUp Table Structure Improvement

A lookup table contains predefined values, and is often used as it saves valuable clock cycles that would otherwise be spent carrying out a calculation.  In this instance the lookup table is used to simplify the functions called, when a transition from or to a state and when the same state is selected.

There will be individual functions available for execution when entering, exiting and while-in a state.  This makes for a cleaner layout and removes the additional switch case statements in the UponEnter, UponExit and ActionWhileInState functions.  Pointers are used to bring this about as well as a typedef statement.  The code excerpt below shows the 9 additional function prototypes that will be used.

The next step is to set-up the typedef and pointer that will be used with the lookup table.

The line starting with typedef is a typedef for a function pointer, the function this pointer points to expects no parameters and not returning anything to be exact.

The 3 lines that follow are the function pointers, one for each state.  These hold arrays of data that correspond to each state, and point to individual functions that will be actioned when a state transition or the same state is selected.

The third piece of code relevant to this lookup table is found at the bottom of the StateMachine function.

There are 3 function calls at the end of the StateMachine function;

UponExit[Current_State]();  UponEnter[Next_State]();  ActionWhileInState[Current_State]();

So for example the line UponExit[Current_State](); calls the function pointer UponExit[Current_State]();  points to either;

State_Exit_OFF if Current_State is 0  enum states { S_OFF == 0

State_Exit_ON if Current_State is 1  enum states { S_ON == 1

State_Exit_PROCESS if Current_State is 2  enum states { S_PROCESS == 2

There is also an additional else statement that allows ActionWhileInState function, to only be called if the Next_State is equal to the Current_State.

The process that is happening here can be illustrated in a simple table, showing the function/s called depending on the state transition:

State Machine Project Tutorial C Code

State Machine output

The image below is a screen capture of the console window in Eclipse, this shows the output from the state machine code as numbers are entered from the keyboard.  As shown in the diagram when a transition occurs the UponExit and UponEnter functions are called, but if the same number is entered on the keyboard, then no transition occurs and the ActionWhileInState function is only called.

State Machine Project Tutorial C Code

Complete State Machine C Code

The link below contains the zip file with the full state machine C code covered in this third tutorial, there is a small advert page first via Adfly, which can be skipped and just takes a few seconds, but helps me to pay towards the hosting of the website.

State Machine v1.2

I would also like to take this opportunity to give a big thanks to Roadrunner84 from the www.43oh.com forums, he has been very helpful and clearly possess a great understanding of the C language.

I take great care when writing all the tutorials and articles, ensuring all the code is fully tested to avoid issues for my readers.  All this takes time and a great deal of work, so please support the site by using the Adfly links etc.  If you have found this useful or have any problems implementing, please feel free to leave a comment and I will do my best to help.

One thought on “State Machine Tutorial Pt/3

  1. Akshay Immanuel D

    Another simpler alternative:

    void (* StateController)(void);
    void state1(void);
    void state2(void);

    void main()
    {
    StateController=&state1; //initial state
    while(1)
    {
    (* StateController)();
    }
    }

    void state1(void)
    {
    //do something in state1
    if(if you need to go to state 2 and state 1 related function is complete)
    StateController=&state2;
    else
    StateController=&state1; //im using an else only to show no transition
    }

    void state2(void)
    {
    //do something in state2
    //Keep changing function direction based on state transition
    StateController=&state1;
    }

    You can build on this.

    Reply

Leave a Reply