Understanding state-full programming methods
A straightforward approach that enforces discipline with preparation, planning, and documenting.
When considering the solution to a programming task, there is generally no shortage of approaches. These typically range from the mundane to the extremely complicated. There is one approach to consider when solving a problem and that is through the use of a state machine.
The basis of a state machine is in fundamental theory of computation. The specific construct is a deterministic finite acceptor. We won't get into the arcane mathematics, but a basic understanding is in order. The basic elements are:
1. An understanding of the starting point or condition
2. What all of the intermediary steps / states are
3. What the conditions are to transition to the next step / state, and
4. What constitutes the end point(s).
What should be apparent from this is that the problem has to be considered fully and outlined before any work can be done. This is one of the key points of this type of programming in that it enforces preparation, planning, and documenting. The development process is as simple as following the four elements outlined above.
There are some key elements to keep in mind:
In a state machine there can be any number of states; as many as required to complete the task. This characteristic alone necessitates the use of integer-based states; the best analog is a recipe, such as baking a cake.
The machine can only be in one state at a time. As in following a recipe, you typically perform one step after another. You never hear of baking the cake at the same time as adding the ingredients.
Each state can transition to any other state, providing the transition is clearly defined. This is the real power of the construct: loops and jumps can be performed as well as single steps. As in baking a cake, add one egg, mix well, add a second egg, mix well, and add a third egg, mix for 60 seconds. Some steps are repeatable until a different transition is encountered.
Once the endpoint has been reached, the only viable next state is to start over at the beginning.
While automation programming is not quite the same thing as baking a cake, the basic concepts apply. Consider the control of a set of pumps used to pump down a sump:
1. At Low Level, turn on Pump #1
2. At Mid Level and Pump #1 On, turn On Pump #2
3. At Hi Level and Pump #2 On, Turn On Pump #3
4. At Mid level and Pump #3 On, Turn Off Pump #3
5. At Low Level and Pump #2 On, Turn Off Pump #2
6. At Low-Low Level and Pump #1 On, Turn Off Pump #1
The solution of this problem starts out with clearly defining the states and what are the conditions that will cause them to change. The basic states for the sump example are contained in Table 1.
Once the states have been defined, the next step is to work out the criteria that cause the states to change. The transition criteria are contained in Table 2.
It should be clear that each state has specific criteria, or inputs, that cause the machine to change or advance. In fact, using the initial criteria, we don’t even have to concern ourselves with whether or not the pumps are running – at this point we don’t really care; that is taken for granted by the state machine.
At this point we are almost ready to begin programming the state machine. However, before we do that we have to plan for some registers and flags that we’ll need. Some of these are required because of the way that a typical automation controller runs its program, from the top down.
The first register is CURRENT_STATE. This is exactly what it says, where the machine is currently. The next register is NEXT_STATE. This is the state that we want to transition to. Finally, there is a flag called NEW_STATE, this is a bit used to signal that we have moved into a new state. This is not strictly required for our example, but it is extremely helpful with larger machines.
The following is a ladder logic representation of the above example. I’ve over-simplified some things, such as the levels and there isn’t any code to check for valid numbers, but that’s not required for the example.
This example covers all of the basics: initial state, intermediate states, and transitions. I’m sure that you may have noticed that there isn’t an end state. For this specific example it wasn’t required. That is one of the advantages of a state machine; you don’t necessarily have to have an end.
While this example covers a very basic system, nothing inherent in the construct limits it to this use. The example is also limited in that it doesn’t illustrate the actual connection between the states and the field devices it controls but that should be easily addressed. This concept can, and has, been expanded all the way to recipe handling with hundreds of states. The only limitation that it has is the imagination of the programmer.
This post was written by Jeff Monforton. Jeff is a senior engineer at MAVERICK Technologies, a leading system integrator providing industrial automation, strategic manufacturing, and enterprise integration services in the manufacturing and process industries. MAVERICK delivers expertise and consulting in a wide variety of areas including industrial automation controls, distributed control systems, manufacturing execution systems, operational strategy, and business process optimization. The company provides a full range of automation and controls services – ranging from manufacturing plant energy efficiency to data historians and continuous improvement solutions. Additionally MAVERICK offers industrial and technical staffing services, placing on-site automation, instrumentation and controls engineers.