27 Feb 2017

C Notes: Finite State Machine. Interactive Traffic Light. C10

This explanation applies to Chapter 10 of Online Course:
Embedded Systems - Shape The World UT.6.03X


By the way the course is going right now on the edX Platform. Search "Embedded Systems - Shape The World UT.6.10x and UT.6.20x"

Chapter 10 is very interesting, but in the same time and a bit difficult to understand at first look. I spent about two weeks to connect all threads into the one. So, save you time with my explanation.
I refer to TExaSware\C10_TableTrafficLight please open in Keil to have a full code.

Some tip: If you do not understand what is a struct or some basics of C - Zybooks is an awesome helper to grow up with C. Use a free opportunity until the course is active.

1. Firstly we made a struct State

struct State { 
   unsigned long Out; 
   unsigned long Time; 
   unsigned long Next[4];
};

... and then define a new data type STyp.

For what? Because we have a couple states of the machine that will use a complex data structure: Out, Time and Next[4] array.

typedef const struct State STyp; 

// Make a new constant (stored in ROM) data type based on struct State and give a type name STyp.

2. Define names of states by the sequence: 0, 1, 2, 3 and so on. 

We give names because it easy to work with, then compiler will replace names with digits. First of all you should understand table 10.2 So, you may do not have any questions here. Take a pen and redraw logic by yourself ref to professors exp.

Why do we need it at all? How it will connect, you will understand soon.

#define goN 0 
#define waitN 1 
#define goE 2 
#define waitE 3

3. Here we make a software FSM data structure from data graph or our table 10.2 It based on STyp data type, see above. See lectures 10.3 - 10.4

STyp FSM[4] = { 
    {0x21,3000,{goN,waitN,goN,waitN}}, // output, delay, next state 
    {0x22, 500,{goE,goE,goE,goE}}, 
    {0x0C,3000,{goE,goE,waitE,waitE}}, 
    {0x14, 500,{goN,goN,goN,goN}}
};

4. Here is an FSM engine. We starting from goN state.

S = goN; // Start 
while(1) { 
    LIGHT = FSM[S].Out; // set lights 
    SysTick_Wait10ms(FSM[S].Time); 
    Input = SENSOR; // read sensors 
    S = FSM[S].Next[Input]; 
}

5. Firstly we need set an output based of state. 
*** Output = g(CurrentState ) Introduction to FSMs. ***

This code doing it. But how?

LIGHT = FSM[S].Out; // set lights

// Go to FSM array into [goN] into Out and assign Out value to the LIGHT.
// It takes a "0" element from STyp FSM [4] array, because goN is defined as "0" before.
// Do not forget S = goN;

STyp FSM[4]={ 
{0x21,3000,{goN,waitN,goN,waitN}} // Output value, delay value, next states

// Move data into the port and fire the LEDs! Out value of variable is 0x21

6. Next, let's feed the SysTick timer to make 30ms pause between states.

SysTick_Wait10ms(FSM[S].Time);

// The same principle, just now do it for the argument of the function. Go into FSM[goN] and get Time value which is "3000"

7. Read inputs. 

Input = SENSOR; // read sensors PE0, PE1: 00, 01, 10, 11

// Assume we got "00" from SENSOR and placed into Input;
// Move ahead.

8. Finally, FSM defines a new state based on our accepted table/graph logic and place into variable S next state. Most interesting part of a magic with FSM!

S = FSM[S].Next[Input];

// Go to FSM[0] into Next[0x00]. // "00" we got before from input. Buttons were not pressed.
// New State is goN which is defined as "0" // 00 in binary or 0x01

9. New state is function from: where we is and what we have on input. 
*** NextState= f(CurrentState ,Input) Introduction to FSMs. ***

// Assume we got "01"
// New State is waitN which is defined as "1" // 01 in binary or 0x01

// Assume we got "10"
// New State is goE which is defined as "2" // 10 in binary or 0x02

// Assume we got "11"
// New State is waitE which is defined as "3" // 11 in binary or 0x03

That is fin, "ifless" code. 

Vita!

No comments:

Post a Comment

Popular Posts