All posts by Ant

State Machine Tutorial Pt/2

State Machine tutorial part 2 of 3.

Is this part the C programming code for the basic state machine diagram shown in part 1. All the code presented here was written using the open source software Eclipse IDE, this can be downloaded from here.

Starting at the top of the code and working down, all the main elements will be explained. The complete code can be downloaded at the bottom of this article.

Variables

Firstly we need to define the variables for the state machine. Enum is used instead of another variable type, as it allows a type with a restricted set of values.  So we therefore have enum states and enum events, each with their own set of restricted values, what can also be noted is the states and events correspond directly with those found in the state machine diagram in part 1.  The code excerpt below shows the code for the variables.

There is one global variable used in this basic example, Current_State which is used to store the current state machine state outside the state machine function.  The Current_State variable is set to the S_OFF state from the beginning, this enables a predictable outcome when the program is first run.  This variable can be seen in the code extract below.

Function Prototypes

These are used to provide the compiler with the name and arguments of the functions used in the program, they must appear before the function is used in the program.  Each of these functions will be explained in more detail further down this tutorial.

 Main Function

This is where the main program code to be executed is written.  The main is quite short and consists of a continuous while loop, which contains the StateMachine function call.

 ReadKeyInput Function

The ReadKeyInput function takes a value entered by a user and then passes this to the StateMachine function.  The ReadKeyInput function uses a local char variable called input, the scanf function forms part of the C library functions and allows user input via the keyboard which is stored in the char variable input.  The variable is then used in the switch case statement, to return an event type pending on the user input.  The code snippet below shows the entire ReadKeyInput function.

 StateMachine Function

This as it’s name suggests contains the main state machine structure, based around a switch case statement.  When an event is passed to this function by the ReadKeyInput function, firstly a local variable called Next_State is assigned the value held in the variable Current_State, the switch case is then used using the Current_State variable.  So if S_OFF is the value assigned to the Current_State variable, the switch case will open the first case in the sequence which is S_OFF.

Now if the user has entered the number 2 on the keyboard, the event E_ON will be generate by the ReadKeyInput function, this will therefore match up with the event logic inside the nested switch case statement contained within the S_OFF case inside the StateMachine function.  Then the Next_State variable will be assigned the S_ON state.  If key numbers 1 or 2 are pressed E_OFF or E_START will be generated by the ReadKeyInput function, neither of these are valid arguments for the nested switch case statement contained within the S_OFF case, so there will be no change of state and the code performs as per the state machine diagram.  The same logic follows for the S_ON and S_PROCESS cases inside the StateMachine function.  The StateMachine function code can be seen below.

The final piece of code at the bottom of the StateMachine function allows some additional functionality, firstly the if (Next_State != Current_State) uses the ‘not equal to’ operator, so if there is a state transition, some code can be executed when exiting the current state and entering the next state.

The last statement if ( event != E_MAX) ActionWhileInState( Current_State ); runs the ActionWhileInState function as long as the event is not equal to E_MAX.

UponEnter Function

This function allows custom code to used to execute when entering a new state, the function uses a switch case which is passed the Next_State variable value.  The function can be seen below in the code excerpt.

ActionWhileInState Function

This function allows custom code to used to execute while in the current state, the function uses a switch case which is passed the Current_State variable value.  The function can be seen below in the code excerpt.

UponExit Function

This function allows custom code to used to execute when exiting the current state, the function uses a switch case which is passed the Current_State variable value.  The function can be seen below in the code excerpt.

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, as well as the ActionWhileInState function.  If the same number is entered on the keyboard, then no transition occurs and the ActionWhileInState function is only called.  Also the number 4 was entered at the very end, but no transition occurred as this is not a valid argument.

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, 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 Zip

Further improvements can still be made to this code but this forms a good starting point in understanding the state machine structure.  In part 3 of this tutorial some of the code improvements will be shown.

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.

State Machine Tutorial Pt/1

State Machine tutorial part 1 is the first post in a series of 3.

A state machine or as it is also known a finite state machine (FSM), is a model used to design computer programs and sequential logic circuits. The machine can only be in one state at a time, this is known as the current state.  Changes from one state to another are brought about by an event or certain condition, this brings about a transition into a new state.

State machines are found in many devices, some we come across in our every day lives, for example a microwave oven, dishwasher and washing machine. All three of these devices have a standby state where they are waiting for input from a user, the devices will then switch to an active state performing some task, when the task is completed an event is triggered (usually determined by a timer), the device will switch to a new state or possibly back to standby and the user may be alerted by the transition to the new state.

State machines can be very simply with just a few states, or have many different states with many transitions between them.

So to sum up, a state machine is a device that stores the status of something at a particular time, can operate on an input to change the status and/or cause an action or output to take place for any given change.

Further reading on state machines can be found here

Basic State Machine Example

Over the next few tutorials a basic state machine will be explained, using C code that is portable and gives a good basic structure which can be built upon.  This can then be used used to form simple microcontroller embedded systems.  A further example will also be shown based on the Texas Instruments MSP430G223x device, which allows human interaction with a basic interface.

State Machine Project Tutorial C Code

The image above shows a basic state machine diagram, with the following specification:

  • There are 3 states S_OFF, S_ON and S_PROCESS.  The states are prefixed with an ‘S’ as I find this makes the code easier to understand later.
  • There are 3 events E_OFF, E_ON and E_START.  Again these are prefixed but with an ‘E’.
  • There are 4 transitions shown by the green arrows, these also indicate the direction which determines how the state machine structure functions.

S_OFF has 3 transitions attached to it’s state.  It can only move to the S_ON state via the E_ON event, the other 2 transitions are triggered by the E_OFF event, which causes a transition from either S_ON or S_PROCESS into the S_OFF state.    So it is not possible for the S_OFF state to move to the S_PROCESS state.

S_ON has 3 transitions attached to it’s state.  The E_ON event causes a transition from the S_OFF state into the S_ON state.  The E_OFF event causes a transition from the S_ON state into the S_OFF state, and the E_START event brings about a transition to the S_PROCESS state.

S_PROCESS has 2 transitions attached to it’s state.  It can only move to the S_OFF state via the E_OFF event.  The other transition is from the S_ON state via the E_START event.  So it is not possible for the S_PROCESS state to move to the S_ON state.

This example should illustrate the basic mechanism of a state machines logical process, it also aims to show the power of a state machine diagram which can be very useful when constructing the code around the system.

State machines inherently promote good design techniques, so when designing an application think about the states and events you will use.

In the next part of this tutorial we will dive into the C programming code using this basic example for the system.

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.

Microcontroller GPIO Protection Tutorial

Microcontroller GPIO protection is an essential element of any circuit design.

GPIO ports generally have maximum voltage and current ratings, if these are exceeded it can result in the microcontroller being damaged or completely destroyed.

Therefore it is important to use external circuitry to protect the ports from excessive voltage, or excessive current being sourced from a pin.

The principles used in this post are for the MSP430G2231, however they can be applied to Arduino, Raspberry Pi and other microcontrollers, by taking into account the voltage and current specifications for each microcontroller, then changing the zener diode and resistor value accordingly.

Over Voltage Protection

This is fairly easy to achieve with some basic external components, to explain this a simple example will be used based on the Texas Instruments MSP430G2231.  The maximum ratings for the integrated circuit need to be determined, this information can be obtained from the devices datasheet, MSP430G2231 datasheet can be found here.

The image below shows an extract from the MSP430G2231 datasheet, the maximum voltage rating can clearly be seen as 4.1V, there is also a cautionary warning which should be noted.

Microcontroller GPIO Protection Tutorial

Now lets assume we are using one of the ports as an ADC input for a sensor, the voltage range for the ADC input on the MSP430G range is 0V to 3V.  So now we know the operating range and the maximum voltage, we can design some simple interface circuitry to ensure the microcontroller is protected.

The schematic diagram below shows a basic circuit which could be used to protect against over voltage.

The main components here that provide the over voltage protection, are D1 and R3.  D1 is a 3V3 Zener diode, which clamps the voltage if it exceeds 3.3V.  R3 has a dual purpose firstly if the voltage exceeds 3.3V the excess voltage will be dropped across the resistor, as the diode will have 3.3V across it i.e. over voltage is 5V, R3 will have 1.7V across it and D1 will have the remaining 3.3V across it.  R3 also acts as a current limit resistor, and Ohm’s Law can be used to calculate the maximum current with a known voltage.  Something to note here is the zener diode will take approximately 5mA of current in normal operation, this is less than ideal for battery operated applications.

Microcontroller GPIO Protection Tutorial

The other components R1, R2 and the opamp are here to simulate a dummy sensor input.  However by designing a circuit using a single rail to rail opamp, the output of the opamp cannot exceed it’s rail to rail voltage, so with a supply of 0 to 3.3V the output cannot exceed 3.3V.  Therefore using a rail to rail opamp in a configuration similar to the one shown, can eliminate the need for the zener diode altogether.

Over Current Protection

Over current protection as with over voltage protection, is quite simple to achieve.  Again it is best to consult the datasheet for the device to determine the current ratings, as can be seen below in an extract from the MSP430G2231 datasheet.

Microcontroller GPIO Protection Tutorial

So the maximum recommended current that can be sourced or sunk is 6mA, and the total maximum current for all ports is 48mA (MSP430G2231 has 10 GPIO pins in total).  There are some further graphs shown in the datasheet, these show that it is possible to source 8mA from a GPIO pin, but the voltage on this pin will drop to approximately 2.7V as a result of the high current.  I would not recommend placing a load which draws 8mA, especially not on more than 1 pin, I always try to keep the current drawn from a GPIO around 1mA in most circumstances.  We can also see the voltage from the GPIO pins will be 3V.

By placing a resistor directly connected to the GPIO pin before any additional circuitry, we can limit the amount of current being sourced from the pin.  This resistor can be calculated by taking the 3V provided by the GPIO pin, lets assume we want to limit the current to 1mA, this gives us a value of 3kΩ the nearest standard value (going up) is therefore 3.3kΩ. This calculation can also be reversed and used to prevent excessive currents being sunk by the microcontroller.

3V rated at 1mA is not going to give much scope for driving external circuitry i.e. an LED or a relay, so it is best to use this to drive a transistor, using the transistor as a switch.

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.