Structured text sequencing

However you can still use a If-Then to step through a sequence and then enable outputs based on the sequence value at the end.

If the action is based on a sequence, then a sequence makes sense. For example, if level is between A and B, and goes to between B and C, the next step is starts, but if the level goes back between A and B, we don't go back to the previous step, but stay in the current step, a sequence

If the action was determine by the state of the of the system, such as level between A and B, then using a sequence complicates things. Using Flag to indicate a state may make sense. Like in the 4 line example, the Active state isn't needed, and the logic could be done in 3 lines, but it might not be as easy to follow.

Valve33 := Valve34 := Pump:= Auto & not Alarm & (Level > Low)
Valve60 := Valve61 := Auto & not Alarm & (Level > Low) & (Level < Med)
valve50 := Auto & not Alarm & (Level > Medium) & (Level < High)

My suggestion was more pointed to the practice of using If-Then on Boolean assignments.

IF (Thirsty and Have_Water) then Take_A_Drink := True
Else Tank_a_Drink := False

or

IF (Thirsty and Have_Water) then Take_a_Drink := True
IF (Not Thirsty) then Take_a_Drink := False
IF (Not Have_Water) then Take_a_Drink := False

It is much simpler and more direct
Take_a_Drink :=( Thirsty and Have_Water)
 
If the action is based on a sequence, then a sequence makes sense. For example, if level is between A and B, and goes to between B and C, the next step is starts, but if the level goes back between A and B, we don't go back to the previous step, but stay in the current step, a sequence

If the action was determine by the state of the of the system, such as level between A and B, then using a sequence complicates things.

+1 one on the above. In my experience though sequences are the more common situation unless it's a really, really simple process.
 
Ditto, shooter's boolean formula suggestion and CASE statements.

When not using a real time operating system I always used case or switch statements.
When using case statements you don't need to use one shots. However, I use a variable I call state or xxx_state where xxx is the name of the state machine. I also keep a last_state variable. This allows me to check for two things.
1 Do something special when I enter the state from another state by comparing the state and last_state at the beginning of the state. If different I execute the code and set last_state to state. This is kind of like a one shot.
At the end of the case or state I check again if state not equal to last_state. This allows me to exit code when exiting the state. This again prevents the need for one shots. However, don't update last_state with state until entering the next state.
This effectively adds an on_enter and on_exit section for each state or case.
I find this to be very flexible.

It is possible to have states that only execute for one scan but that just adds more cases or states.

Another handy trick is to put the state in an array or shift register so you can see if the sequence of states is executing the way you want.
 
Ditto, shooter's boolean formula suggestion and CASE statements.

When not using a real time operating system I always used case or switch statements.
When using case statements you don't need to use one shots. However, I use a variable I call state or xxx_state where xxx is the name of the state machine. I also keep a last_state variable. This allows me to check for two things.
1 Do something special when I enter the state from another state by comparing the state and last_state at the beginning of the state. If different I execute the code and set last_state to state. This is kind of like a one shot.
At the end of the case or state I check again if state not equal to last_state. This allows me to exit code when exiting the state. This again prevents the need for one shots. However, don't update last_state with state until entering the next state.
This effectively adds an on_enter and on_exit section for each state or case.
I find this to be very flexible.

It is possible to have states that only execute for one scan but that just adds more cases or states.

Another handy trick is to put the state in an array or shift register so you can see if the sequence of states is executing the way you want.

I do the same with last_state.

I also use the detection of a new state to restart a sequence timer. That is used to detect if a step in the sequence doesn't complete in the allowed time. That way you can automatically issue a timeout alarm and stop the sequence or execute some kind of shutdown state.

I also use the time it takes for every step in the sequence and save it in an array. Either just to know how long something takes but also with some filtering/averaging to calculate estimated time to completion. This is especially useful for cyclic processes that takes hours to complete. Or in machines where you want something to happen 1500 milliseconds before you reached some state.

If you have large sequences I also recommend to program in single-stepping in the sequence. So the sequence executes one step and then stops. That's very good for debugging new sequence programs. I use that a lot for complex process control where you want something to happen and then check that everything worked as it should before moving on. When using integers for sequence step it's also easy to set to manually set it to some step and run it from there.

PS. I'm going to steal you idea of putting the state in an array or shift register to see how the sequence of states is executing. That's like an execution stack in a debugger.
 
Last edited:
I do the same with last_state.

I also use the detection of a new state to restart a sequence timer. That is used to detect if a step in the sequence doesn't complete in the allowed time. That way you can automatically issue a timeout alarm and stop the sequence or execute some kind of shutdown state.

I also use the time it takes for every step in the sequence and save it in an array. Either just to know how long something takes but also with some filtering/averaging to calculate estimated time to completion. This is especially useful for cyclic processes that takes hours to complete. Or in machines where you want something to happen 1500 milliseconds before you reached some state.

If you have large sequences I also recommend to program in single-stepping in the sequence. So the sequence executes one step and then stops. That's very good for debugging new sequence programs. I use that a lot for complex process control where you want something to happen and then check that everything worked as it should before moving on. When using integers for sequence step it's also easy to set to manually set it to some step and run it from there.

PS. I'm going to steal you idea of putting the state in an array or shift register to see how the sequence of states is executing. That's like an execution stack in a debugger.

Hello Pete,

can you give me an example for the time measuring?
And what do you mean with single stepping? To have the opportunity to manual go to the next step?

greets from germany
 
do not use else as ladder does not know this.
Not true! A rung of ladder inherently includes the Else condition.
For this rung:

Input Output
---] [-----------------( )-


The equivalent IF/THEN/ELSE is:
If Input = True
Output := True
Else
Output := False
End If

Omit the Else statement and the result is this rung:

Input Output
---] [-----------------(L)-

 
Last edited:
Not true! A rung of ladder inherently includes the Else condition.
For this rung:

Input Output
---] [-----------------( )-


The equivalent IF/THEN/ELSE is:
If Input = True
Output := True
Else
Output := False
End If

Omit the Else statement and the result is this rung:

Input Output
---] [-----------------(L)-


I may be missing something... but isn't this

Input Output
---] [-----------------( )-


described by:
Code:
Output := Input
 
Yes it is, but to get the same result when you program it using the IF/THEN, you must include the ELSE condition.

But why would you, if you have direct assignment? The only thing I can think of is really to allow for better visualization, or entering a block of instructions dependent on value instead of assigning a value dependent on another.

Don't get me wrong, it's possible to see it that way, but it doesn't make it right. This reminds me of a job interview I had recently where there was no if instruction allowed and the only thing I had to test values was a for loop.
 
I wasn't making a comment about anyone's programming style. I was responding to shooter's statement that "ladder doesn't know Else" in reference to several previous posts giving examples of IF/THEN/Else construction.
Whenever I have rendered Boolean expressions in VB I have used the direct assignment. It executes significantly faster than IF/THEN/ELSE.
 

Similar Topics

I have an expression in a structured text routine of a Logix controller that looks more or less like the following: ResultInteger := Integer1 *...
Replies
13
Views
359
Good evening. I display the step number of a SFC on a display. Sometimes, on a trip, it goes quickly through many steps and I need to prove to...
Replies
1
Views
105
I am trying to set up a piece of equipment with a Horner HE-X4R. I'd like to use structured text and so far I'm just trying to get a basic On/off...
Replies
0
Views
59
Good morning. I'm doing a rehab and I need to recycle some part of the old code that won't change and that I need. This is a calculation that...
Replies
22
Views
1,331
I'm writing some structured text that's handling a data structure that comes from a PC. The PC structure is in the "new" LREAL 64-bit floating...
Replies
3
Views
478
Back
Top Bottom