Finite state machine practical example

Finite state machine practical example

This is is the second article about the usage of the finite state machine concept in PLC programming. In the first article FSM concept is introduced with a simple example to demonstrate how it can be applied to solve PLC programming challenges. In this article, there is a more practical example of using the FSM concept in PLC programming with an emphasis on how to do more work with fewer lines of code.

The common way of thinking for beginners to this concept and programming, in general, is that every actuator has to have one or more FSM states or one or more separate lines of code responsible for its control. This way of thinking leads to repeating code where actually only parameters are different, and adding more actuators requires adding more lines of code to the control algorithm itself. Also if some changes need to be implemented to logic that drives the actuator those changes have to be implemented in multiple places. Besides the fact that programmer time is wasted for the task of repeating the code, adding more code increases the probability of having bugs, thus the time needed to test and debug the program also increases.

There are certainly cases where every actuator has unique control action associated with it, in that case putting all of the code together will have a negative effect on program complexity, efficiency, and reusability. A better way of thinking when deciding about FSM implementation is to design FSM in such a way that the number of states is directly proportional to the number of DIFFERENT actions that the control system needs to execute. If some action requires different actuators or different parameters it doesn't necessarily mean that it is a different or unique control action.

In the example below there is a basic implementation for the ingredient measurement system with 1 to 10 actuators, and 1 to 10 steps that define which actuator is to be used and what amount is to be dosed over that actuator.

No alt text provided for this image
No alt text provided for this image

Text file with the code and example with simulation code in TIA Portal 15.1 can be downloaded here.

The above example executes the measurement of 1 to 10 ingredients using one actuator at the time. State 0 is there only as a starting point because #State will be 0 when the program is first executed. In state 10 control system is waiting for start command to become active. After #Start becomes true #StepPointer variable is initialized to 1 to avoid addressing outside of recipe array boundaries. And FSM is transitioning to state 20 in which recipe array is traversed to find a step to be executed, which means the recipe step that has set amount and actuator number. If the step is found then #ReferenceAmount variable is initialized to the current value on the scale. In case that end of the recipe array is reached the number of repetitions is decremented and FSM is transitioned to state 50 to empty the scale.

In state 30 single line of code is used to activate appropriate actuator to get the desired amount of ingredient into scale. When the desired amount of ingredient is on the scale actuator is stopped and FSM transitions to state 40. In state 40 after stabilization time runs out the loaded amount of ingredient is added to product totalizer. This is a state where all other possible post-action calculations can be added, such as overshoot compensation, ingredient consumption logging (prepare data for archive), etc. From this state FSM is transitioned back to state 20 to look for the next recipe step to be executed.

In the state 50 unloading actuator is activated until the scale is emptied. When the scale is empty FSM is transitioning to state 60 where the control system is waiting for the unloading actuator to deactivate and the scale to stabilize before transitioning to state 100 if there are no more repetitions or to state 20 to repeat recipe steps.

Bit #BatchFinished is used as a handshake with the next processing stage, and it is supposed to be reset by the control logic of that next stage when the next stage is ready to receive the next batch.

This is one example of a control program where the number of states is completely independent of the number of actuators or the number of steps to be executed. In case that new actuators have to be added or more recipe steps have to be added no code change is needed, just array boundaries might need to be changed if arrays need to be extended. This way program is made reusable for handling any number of actuators or recipe steps. And that is useful not just because of time saved for writing code but also for time saved for not having to debug additional code. No code no errors.

However, there is more space to improve the re-usability of the code depending on the capabilities of the PLC platform being used. If it is supported by platform array boundaries can be checked at runtime and not defined by constants at compile time. So, the size of the recipe and actuator arrays in the block interface could be determined at runtime and not hard-coded in the block interface itself. If these two functions are supported by the platform then the possibility to write reusable blocks is even greater, because the block interface could accept arrays of any size. In the case of Siemens, indirect addressing is different across different PLC types so for the sake of simplicity and easier portability to other platforms arrays with hardcoded limits are used. This yields conclusion that in the case of PLC programming, a compromise needs to be made between cross-platform or cross-type compatibility and code reusability.

This code is just a basic implementation of the ingredient dosing algorithm with the FSM concept. Here are a few ideas on how the above code can be further improved:

  • Two dosing speeds to increase the precision of dosing.
  • Overshoot/undershoot compensation.
  • Add scale ID to the recipe steps in order to enable multiple instances of the block to process the same recipe array.
  • Separate archive entry for every ingredient that is used
  • Monitoring of scale increment to detect lack of material

So to wrap up, these are the different actions that have one or more corresponding FSM states in the example code above:

  • FSM initialization
  • Waiting for start
  • Traversing recipe to find the step to execute and prepare variables
  • Dosing set amount over the desired doser (not some specific doser, rather optionally chosen doser)
  • Scale stabilization and post-dosing calculations
  • Emptying of the scale
  • Ending of the production


Thank you for reading the article. Feel free to share the article and your questions, opinions, or suggestions in the comment section or by message.

Use constants not pure numbers for states.

Like
Reply

This is a great post. I am teaching myself ST and totally understand what's happening here.

Well done. Good structure and good use of comments. I wish all code was this easy to read. One suggestion ... you might think about using Enumerations for the state names ... much easier to manage and understand and reduces the chance of bugs.

Like
Reply

Off topic maybe, but why do these variables start with #?. What it means when there is just a variable name ?

Like
Reply

Very useful. I will go over your code this weekend . Thanks for sharing your ideas.

To view or add a comment, sign in

More articles by Bojan Terzija

Others also viewed

Explore content categories