State Machine for Embedded Systems

State Machine for Embedded Systems

Hello guys! In today's article, we will be talking about state machines, exciting right? well, that is not all, we will look at its implementation on an embedded device, an Arduino Uno to be precise! If you are not familiar with the Arduino Uno development board, I will advise you to learn about it here before going further. let us get started already!

What is a state machine?

Let us define what a state is, to have a better understanding of the answer to the question asked. A state models a situation in the execution of a state machine behavior during which some invariant conditions hold.

a simple state.JPG

Fig 1: A State

A state machine is a software model of computation, and it comprises a finite number of states, hence it is also called a finite state machine(Finite State Machine). State machines are stable in more than one state, and transition from one state to the other. Umm is it not the same with flowcharts? Ermm it is more advanced than that, let us say state machines naturally encapsulate action groups, flowcharts don’t, a single state can have multiple events and transitions, each checking a completely different condition.

In simpler terms, it means a state machine can have multiple states (ON event, OFF event, CHECKMAIL event etc.) this series of events can transition from one event to the other while meeting respective conditions assigned to it. State machines are deployed when building complex systems with several functionalities.

Types of state machine

  • Mealy Machines

  • Moore Machines

  • Harel State Charts

  • UML State Machines

Mealy Machines

The mealy machine is defined as a machine whose output is determined by the current state of the machine and its current input. A real-life scenario of this theory of computation in use is our study lamp, which can go from "bright" to "mid" to "dim" and then to "off" all by constantly pressing a single button.

The aforementioned functions of the lamp could be likened to the several states of our mealy machine. Below, is a code demonstration of using a mealy machine on an Arduino Uno to simulate the functionalities of our reading lamp.


//This enum represents the several states of a reading lamp
typedef enum 
{

  LAMP_OFF,
  LAMP_DIM,
  LAMP_MEDIUM,
  LAMP_FULL  
}lamp_state_t;

//initializing our variable of type "lamp_state_t" to its default state ("LIGHT_OFF")
lamp_state_t lamp_curr_state = LAMP_OFF;

//we are going to connect our led(Lamp) to the pin 5 of the arduino uno
#define PIN_LED   5
//we are going to connect our button to the pin 6 
#define PIN_BUTTON  6
#define BUTTON_PRESSED LOW

//Defined macros of the lamp's intensity value
#define  LAMP_OFF_M       0
#define  LAMP_DIM_M       25
#define  LAMP_MEDIUM_M    80
#define  LAMP_FULL_M      255

//function prototypes
void lamp_change_intensity(uint8_t pin,uint8_t intensity);
void lamp_state_machine(void);


void setup() {
  // put your setup code here, to run once:
  Serial.begin(115200);
  pinMode(PIN_BUTTON, INPUT_PULLUP);
}


void loop() {

  // put your main code here, to run repeatedly:
  if(digitalRead(PIN_BUTTON)  == BUTTON_PRESSED){

      lamp_state_machine();
    }

}


void lamp_state_machine(void)
{
  switch(lamp_curr_state)
  {
    case LAMP_OFF:
    {
      lamp_change_intensity(PIN_LED, LAMP_DIM_M);
      lamp_curr_state = LAMP_DIM;
      Serial.println("LAMP_DIM");
      break;
    }

    case LAMP_DIM:
    {
       lamp_change_intensity(PIN_LED, LAMP_MEDIUM_M);
       lamp_curr_state = LAMP_MEDIUM;
       Serial.println("LAMP_MEDIUM");
       break;
    }

    case LAMP_MEDIUM:
    {
       lamp_change_intensity(PIN_LED, LAMP_FULL_M);
       lamp_curr_state = LAMP_FULL;
       Serial.println("LAMP_FULL");
       break;
    }

    case LAMP_FULL:
    {
       lamp_change_intensity(PIN_LED, LAMP_OFF_M);
       lamp_curr_state = LAMP_OFF;
       Serial.println("LAMP_OFF");
      break;
    }
  }

}


void lamp_change_intensity(uint8_t pin,uint8_t intensity)
{
  analogWrite(pin, intensity);
}

Let us break this code down:

The enum here represents the states of our Mealy machine. the next line of code is a variable definition of type "lamp_curr_state", if this does not make much sense you can read up on typedef here for more clarity.

This part of the code runs only once. The first line of code sets the Serial baud rate to 115200 and the following line of code sets our digital pin 6 on the Arduino as a pull-up input pin.

This part of the code runs continuously, the program will constantly check the state of our button to see if it has been pressed. If the condition is true, then we will execute the "lamp_state_machine" function.

The "lamp_state_machine" function will check the current state of the lamp, and run routines that fall under such state. Say if the current state is LAMP_DIM and the button is pressed, the lamp's brightness should increase to medium, after which the lamp's current state is updated to medium.

Conclusion

In summary, the mealy machine checks the current input of the machine with the current state of the machine to determine its output, same with our code demonstration which checks the current input of the lamp i.e. if BUTTON_PRESSED. and the current state of our lamp to determine its output.

in our next article, we will discuss and look at embedded applications of Moore Machines.