Tics Realtime -----


 
- - - - -

Understanding State Machines

With a simple example, this article describes how state machines can be effectively applied in real-time multi-tasking applications.

A Simple State Machine Example

Consider a lamp controlled by a momentary contact switch. (A momentary contact switch is a spring loaded button switch that makes the connection when pressed and breaks the connection when released.) When the button is pressed the first time, the lamp should turn on, and, when pressed the second time the lamp should turn off. This apparently simple behavior is a bit involved and can be described in a table as shown below.

Current State	Condition		Action		Next State

0		Button down		Lamp on		1
1		Button up		None		2
2		Button down		Lamp off	3
3		Button up		None		0

The states have the following meanings:

  • 0 - Button is up and lamp is off.
  • 1 - Button is down and lamp is on.
  • 2 - Button is up and lamp is on.
  • 3 - Button is down and lamp is off.

The state machine remains in the current state until a condition is met, at which time an action is taken, and a state transition is made to a new state (the "new state" may be the current state also). This may be coded as follows.

void taskA(void)
{
	int state;
	int condition;
	typeMsg * msg;

	while (TRUE) {
		msg = waitMsg(ANY_MSG);
		condition = msg->msgNum;
		freeMsg(msg);

		switch (state) {

		case 0:
			if (condition ==  BUTTON_DOWN) {
				lampOn();
				state = 1;
			}
			break;

		case 1:
			if (condition ==  BUTTON_UP) {
				state = 2;
			}
			break;

		case 2:
			if (condition ==  BUTTON_DOWN) {
				lampOff();
				state = 3;
			}
			break;

		case 3:
			if (condition ==  BUTTON_UP) {
				state = 0;
			}
			break;
		}
	}
}

taskA receives a message from another task when a change in button status occurs and reacts according to the state table. One may ask why taskA does not poll the switch itself thus eliminating the need for a special task that polls the switch. The answer is that taskA could simply poll the switch, but it would then have to debounce the switch also. Using a separate task to poll the switch also handles the debouncing problem and makes taskA easier to read. The debounce task is also a state machine and its state table is shown below.

Current State	Condition		Action		Next State

0		Button down		pause		1
1		Button down		sendMsg	2
1		Button up		None		0
2		Button up		pause		3
3		Button up		sendMsg	0
3		Button down		None		2

The states have the following meanings:

  • 0 - Button is up.
  • 1 - Button state is in transition (unknown).
  • 2 - Button is down.
  • 3 - Button state is in transition (unknown).

The states 0 and 2 are absolute states in which the button is either up or down. States 1 and 3 are transition states in which the position of the button switch after a delay determines whether the switch has settled into position or not. The implementation of the debounce task is shown below.

extern typeTcb TcbA;

void taskB(void)
{
	int state = 0;

	while (TRUE) {

		switch (state) {

		case 0:
			if (buttonDown()) {
				pause(100L);
				state = 1;
			} else {yield();}
			break;

		case 1:
			if (buttonDown()) {
				sendMsg(makeMsg(TcbA, BUTTON_DOWN));
				state = 2;
			}
			else state = 0;
			break;

		case 2:
			if (buttonUp()) {
				pause(100L);
				state = 3;
			} else {yield();}
			break;

		case 3:
			if (buttonUp()) {
				sendMsg(makeMsg(TcbA, BUTTON_UP));
				state = 0;
			}
			else state = 2;
			break;
	}
}

General Application

Certain applications need to know where they are in a sequence of operations and it is applications like these that require state logic. Even if the formal state machine approach shown above is not employed, some form of state machine logic must be used otherwise errors will result. State machines are a must in applications like communications, robotics, process control and the like, since each of these involve a sequence of operations. State machines become indispensible when handling error conditions and recovery procedures because a knowledge of the machine state is required to effect said procedures properly.


We welcome comments. Let us know what subjects you would like written up. Send comments to Mike@TicsRealtime.com

Copyright © 1992-2004, Tics Realtime