Using a State Machine to control output

BlackBamba

Member
Join Date
Jul 2018
Location
Haifa
Posts
22
Hello all,
been reading in the forum for a few years I guess, but a first time poster. :)

I'm in the midst of converting parts of my own system to state machine design. It's a plc controling a production line. This thing is working but I want to reduce the number of possible errors (I did have "race condition" on some occasions) and make debugging easier. I also have quite a bit of output sets/resets (lots of sequences...) that I now try to consolidate into pos coils (with a seal-in when necessary).

I ran into this dilemma:

A device has 6 states, each associated with one of the bits S100,S200,S300,S400,S500,S600. The bits are mutually exclusive of course.

The natural progression of the states is from S100 to S600 oridinally. Then looping back to S200.

Suppose I have an actuator AA starting on S400 and turning off on S600.
S100 is the OFF state of the device (all outputs including AA are off).

I'm trying to decide what is the better CONVENTION for my project: to use just the states in which a the output should be toggled (as in rung 1); or to plot the complete "truth table" onto the rung (rung 2). This FSM is fairly simple but others FSMs in the project have many more states, 20-30 would be normal.

Would love to hear opinions on this matter.
view


Outputs.gif
 
Welcome to forum

You can search state machine posts from forum

bit and integer method are discussed:
http://www.plctalk.net/qanda/showthread.php?t=1931
Thanks for the welcome.

I'm not sure how your reply relates to my question, as it's not about integers vs bits for states?



Still, since you mentioned that, I'll just add that I use integers (CurrentState, NewState) and the bits are just for convenience and readability.
 
My best advice is to separate your STATE engine from what they control -- i.e, the outputs.

Think in terms of STATES and TRANSITIONS. If you are in State X, what state(s) can you transition to, and by what condition?

After you have a functional state engine, THEN you can answer the simple question of "What states drive a particular output?"

You seem to be doing this, but it bares re-iteration.


In your example then, you only want AA on in states 4 and 5, so I would make the code even simpler than your two examples:
    S400             AA
-----| |-----+------( )
|
S500 |
-----| |-----+



IMO, including all the "Not in State" 1, 2, 3 and 6 doesn't add any value.

It can be a little tricky when using coils to ensure that ONE AND ONLY ONE bit is on at a time. You might set the coil for one State while the previous state will not unseal until the next scan. This leaves a whole scan where you are in two states simultaneously, which can be undesirable.

One method to make states mutually exclusive is to make each state a bit in the same word, and use contacts to be in a state, but move integers (rather than coils) to transition from one state to another, like so:
    InState.1    Go_1_to_2    +--- MOV --+
------| |------+----| |-------| 2 |
| | InState |
| +----------+
| Go_1_to_3 +--- MOV --+
+----| |-------| 4 |
| InState |
+----------+




Another methodology is to use latches and unlatches, unlatching the state that you are in and latching the state you going to:
    S400          Go_4_to_5   S400    S500
------| |------+----| |--------(U}----(L)-
|
| Go_4_to_6 S400 S600
+----| |--------(U}----(L)-



Good luck!
 
To specifically answer your question:

Originally posted by BlackBamba:

I'm trying to decide what is the better CONVENTION for my project: to use just the states in which a the output should be toggled (as in rung 1); or to plot the complete "truth table" onto the rung (rung 2). This FSM is fairly simple but others FSMs in the project have many more states, 20-30 would be normal.

Presumably the reason you are implementing this as a state machine is that you CANNOT be in multiple states concurrently. If your state machine ends up in multiple states concurrently your state driver is defective. Given that, the example with the "off" state interlocks is horribly redundant.

If you do have a situation where you can be in multiple states at once, that situation is not a good fit for a state machine. At the very least this would indicate that a single state machine should be split into multiple state machines with interlocks between them.

Keith
 
My best advice is to separate your STATE engine from what they control -- i.e, the outputs.

Think in terms of STATES and TRANSITIONS. If you are in State X, what state(s) can you transition to, and by what condition?

After you have a functional state engine, THEN you can answer the simple question of "What states drive a particular output?"

You seem to be doing this, but it bares re-iteration.


In your example then, you only want AA on in states 4 and 5, so I would make the code even simpler than your two examples:
    S400             AA
-----| |-----+------( )
|
S500 |
-----| |-----+


I would agree with the advice here. No need for the extra, simpler is better. With integers, it could allow you do to ranges, where it is active from greater than or equal to state 400 to less than or equal to state 500.

However, it also might not mean much to someone who isn't familiar with the state machine/sequence. Good comments are probably your friend; especially if the states end up getting changed but you miss this line of code and it doesn't work right later on.
 
Thanks for the welcome.

I'm not sure how your reply relates to my question, as it's not about integers vs bits for states?



Still, since you mentioned that, I'll just add that I use integers (CurrentState, NewState) and the bits are just for convenience and readability.

Since you use integer for states allready, then it isn't possible that you have two different states on same time like on using only bits. This is why I linked post.

Simpler is best so method which Aardwizz alleready posted, there is no need to look invididual state bits on every rung. You allready do it on integer side.
 
One possible argument for individual bits rather than a changing integer - in many cases the bits can be separately commented whereas the different values in an integer may not.
 
One possible argument for individual bits rather than a changing integer - in many cases the bits can be separately commented whereas the different values in an integer may not.

In some systems (I know I've done it in TIA Portal), you can declare constants, and give those constants names/comments. The nice thing about constants is they get inserted directly by the compiler, so you don't have to worry about memory.

You can make a constant "Step 1" with the value 100, "Step 2" with the value 200, etc. Then when you're doing comparisons, OP's logic would show as:

Code:
CurrentStep > "Step 4" AND CurrentStep < "Step5"
with the actual values and comments hovering appropriately. It ends up being just as easy to follow. If your PLC doesn't have constants, you could create a tag for each step, but that wastes memory.
 
Cheers, thanks for all the replys!
I'll try to further explain my reasoning.

In your example then, you only want AA on in states 4 and 5, so I would make the code even simpler than your two examples:
 S400 AA
-----| |-----+------( )
|
S500 |
-----| |-----+



IMO, including all the "Not in State" 1, 2, 3 and 6 doesn't add any value.

It can be a little tricky when using coils to ensure that ONE AND ONLY ONE bit is on at a time. You might set the coil for one State while the previous state will not unseal until the next scan. This leaves a whole scan where you are in two states simultaneously, which can be undesirable.

Good luck!

So, there's a subtility here: S500 should not energize the output - but should allow it go stay ON if was was energized before.
But, this is not a guard for the transition. So that's why I used AA as a seal-in for S400 in the first example.
And this is what calls for the "not in this state" contacts.


The other example covers this with the AA contact+S500 contact.


Not sure about why you consider it difficult to have exactly one state bit on. I use integers to move between states like I said in my reply to Lare above. After NewState is moved to CurrentState on every scan, I have an EQ_INT(CurrentState,100) to de/energize S100, EQ_INT(CurrentState,200) to de/energize S200 and so on.

To specifically answer your question:

Presumably the reason you are implementing this as a state machine is that you CANNOT be in multiple states concurrently. If your state machine ends up in multiple states concurrently your state driver is defective. Given that, the example with the "off" state interlocks is horribly redundant.

If you do have a situation where you can be in multiple states at once, that situation is not a good fit for a state machine. At the very least this would indicate that a single state machine should be split into multiple state machines with interlocks between them.

Keith

The states are changed with an integer as I mentioned above. The bits are only for convenience.

I see what you mean about the "off" state contacts being redundant but they actually have a purpose:
Ease of real-time troubleshooting.
This actually saves setting up watchs. You can see how the state machine progresses and what effect it has on the output. It may not be useful for very quick devices but in many cases it would be easier to follow the state changes this way than to go back and forth between the SM code and the output code.

A State Machine may make debugging harder for people that did not create it...

I'm not sure why you think so, but... part of what I'm trying to do is help someone else SEE and understand what's happening.
That's why I was thinking about including all state-bits in one place, as a visual aid.

I would agree with the advice here. No need for the extra, simpler is better. With integers, it could allow you do to ranges, where it is active from greater than or equal to state 400 to less than or equal to state 500.

However, it also might not mean much to someone who isn't familiar with the state machine/sequence. Good comments are probably your friend; especially if the states end up getting changed but you miss this line of code and it doesn't work right later on.


Generally speaking, a SM makes the code longer. Better arranged in the majority of cases; but still longer = more difficult to see the complete picture. So it's not a strict "simpler is better" anyway. In much the same way, I think, having some "extra" contacts may make the rung busy but also make following the logic easier - especially when troubleshooting in real time.


One possible argument for individual bits rather than a changing integer - in many cases the bits can be separately commented whereas the different values in an integer may not.

So, with the combo integers+bits I enjoy both easy state-exclusivity, comments for the state bits, and a bonus: when debugging it's an instant to halt the SM at a certain state - I simplt force-off that state bit. As all rungs within the SM use the state bit for evaluation (the integers are only used to "select" the current state-bit!), this will stop the state code (actions, transitions) from evaluating to true.
 
Cheers, thanks for all the replys!
I'll try to further explain my reasoning.

So, there's a subtility here: S500 should not energize the output - but should allow it go stay ON if was was energized before.

But, this is not a guard for the transition. So that's why I used AA as a seal-in for S400 in the first example.
And this is what calls for the "not in this state" contacts.

Can you add extra state, Go to state S500 if output was "On" and directly to state S501 (added state) if output was "Off"
Then from S500 and S501 go to state S600?
 
Can you add extra state, Go to state S500 if output was "On" and directly to state S501 (added state) if output was "Off"
Then from S500 and S501 go to state S600?


Sure I can, but I'm not sure what's the benefit of that? essenitally we're duplicating a state here, with all its actions and transitions. Weighting that against an extra contact or two in the output control rung, I think I prefer the second option.


Unless I'm missing the point of what you meant.
 
One method to make states mutually exclusive is to make each state a bit in the same word, and use contacts to be in a state, but move integers (rather than coils) to transition from one state to another, like so:
    InState.1    Go_1_to_2    +--- MOV --+
------| |------+----| |-------| 2 |
| | InState |
| +----------+
| Go_1_to_3 +--- MOV --+
+----| |-------| 4 |
| InState |
+----------+



By the way, while I think this is a neat trick, it certainly requires using 2 integers otherwise you could end up with the next state (or even states) executing on the same scan.


My other problem with this approach is that it's great if your solution works 100% first time and never needs adding any new states between exisitng ones. So it's a sort of handicapped integer-based method.
 
Sure I can, but I'm not sure what's the benefit of that? essenitally we're duplicating a state here, with all its actions and transitions. Weighting that against an extra contact or two in the output control rung, I think I prefer the second option.


Unless I'm missing the point of what you meant.

sure there is much same between those to states. (only decision if output is on or off is different)
But it is easier to read afterwards and you don't need make set/reset latches for bits, like you need if your S500 state behaves differently depending of earlier outputs states.

I understand that one state have outputs allways same way and if outputs are different at different time and depending of different things, then there is more than one state
 
Last edited:

Similar Topics

Is there a way to know which is the primary and secondary chassis through gsv? I have read that "PhysicalChassis" (Chassis A/Chassis B) is an...
Replies
2
Views
2,206
Hi guys, In this project we have a PLC for each room monitoring the status of different devices,so there is seven rooms and seven PLCs. Currently...
Replies
2
Views
1,814
May I know how to read the coupler state, whether it is in Idle or in active mode using dot net. What variable I should read? Any sample I can...
Replies
0
Views
1,349
Hello. I am new to expressions in FTView. I am replacing a GOT with a panelview and am trying to drive a multi-state indicator with a expression...
Replies
2
Views
5,165
Dear all Could any one help me. If I have a system to control, and all i know form that system is those state space equation, can any one Help...
Replies
0
Views
1,904
Back
Top Bottom