Basic Structured Text Programming
By Mequonite
Structured Text (ST)
PLC programmers have traditionally developed applications using Ladder Logic. PLC manufactures have controllers capable of accepting programs written in the 5 recognized standards as specified in Part 3 of the IEC 61131. The five supported languages are:
- Ladder diagram (LD), graphical
- Function block diagram (FBD), graphical
- Structured text (ST), textual
- Instruction list (IL), textual
- Sequential function chart (SFC), graphical
Structured Text (ST) is a high level textual language that is a Pascal like language. It is based on the IEC 61131-3 standard, which standardizes programming languages for programmable controllers (PLC). Structured Text is very flexible and intuitive for writing control algorithms.
Structured Text uses operators such as logical branching, multiple branching, and loops. People trained in computer programming languages often find it the easiest language to use for programming control logic. When symbolic addressing is used, ST programs resemble sentences, making it highly intelligible to beginner users as well.
Benefits of Structured Text
- People trained in computer languages can easily program control logic
- Tag Structure UDT (User Defined Tags), local variables and other ST programming conventions make the programs easy to understand
- Programs can be created in any text editor
- State-Model or Power Programming is easily entered with the Case statement
This article presents a very common programming technique often incorporated in a typical PLC program. The method is for creating a Toggle On / Toggle Off control with a single input. The traditional Ladder Diagram technique for this sequence is shown in the graphic below. The Structured Text method is presented below. Start_Stop is the single input, ON_OFF is the output that will Toggle ON / Toggle OFF. The other tags are local symbols used to help support the logic. The tag or symbol ONS_Trig is known as a one shot operator. A one shot is true for only one scan while the control or operand is maintained true.
Basic Structured Text (ST) Example:
// Start of Logic <-- Programming remark initiated with the double // slash
// Catch the Rising Edge One Shot of the Start_Stop input
ONS_Trig := Start_Stop AND NOT Rising_ONS;
// Main Logic for Run_Contact -- Toggle ON / Toggle OFF ---
ON_OFF := (ONS_Trig AND NOT ON_OFF) OR (ON_OFF AND NOT ONS_Trig);
// Rising One Shot logic
Rising_ONS := Start_Stop;
Ladder Diagram version of the Toggle routine
Comments
What's up with all this one-shot-trigger-rising-edge stuff?
IF s_s THEN
IF o_o THEN o_o:= TRUE;
ELSE o_o:=FALSE;
ENDIF;
ENDIF;
If that ain't all there is to it, what am I missing?
Or rather:
IF s_s THEN
IF o_o THEN o_o:= FALSE;
ELSE o_o:=TRUE;
ENDIF;
ENDIF;
You know what I meant. :)
Hey K.I.S.S -
The reason for the "rising edge trigger stuff" is that, in your example, if s_s is true for more than one scan (which it would be if tied to a pushbutton, lets say) then your logic would flip flop as long as s_s is true. The oneshot logic triggers the output once (and seals in) for the first s_s true scan.... and turns off the output on the next s_s true scan. Get it?
The chatter resulting from K.I.S.S. logic is a classic mistake. TDOT clearly understands how automation systems can easily be broken with goofy code.
I think I've got it. I totally missed the real time aspect of PLC programming. Just to make sure I did get it and to maybe help those like me I renamed the variables in the structured text. Some programmers have come into PLC programming without ever seeing an oscilloscope, a coil or a contact. I know the veterans are shrieking in horror, but you know we are out there.
ONS_Trig -> ButtonPushed (abstracted logical button function)
Start_Stop -> Button (1=currently being physically pushed, input)
Rising_ONS -> AlreadyPushed (previous scan state)
ON_OFF -> On (0=off, output)
ButtonPushed := Button AND NOT AlreadyPushed;
On:= (ButtonPushed AND NOT On) OR (NOT ButtonPushed AND On);
AlreadyPushed := Button;
It almost reads like prose, doesn't it?
Thanks for helping me with this. Even if I didn't get it quite right, your responses have helped me think about it.
Post more stuff. How about something on debounce or alarm ack handshaking between PLC and HMI or anything on how PLC and HMI programs split up the work and keep in sync.
ST Programming allows for style in tag naming as well as logical technique. K.I.S.S. recoded the example with a commone VB coding style using leading character capitalization with merged words. This convention works well! Thanks for the update (AlreadyPushed :)
Hi Mequonite,
It seems that you know alot about the PLCs and ST. I want to write a program in st to control an end-effector. It is very difficult for me to start with st. I have 2 amplifiers from Beckhoff. I could give a simple movement to my motors through a simple program from beckhoff but I even have problems to reproduce that program myself. I am really confused.
I really appreciate if you can help me. thanks in advance
Regards
There are many techniques for motor axis motion with ST. I prefer to create a simple case statement that reflects the status of the motor. The idea is to trigger the Beckhoff motion commands at the start of each status state. Here is an example I use with Siemens controllers:
FUNCTION_BLOCK FB100 // Tech CPU Basic Axis Motion Block
VAR_INPUT
Axis_Num : INT; // Axis Number from Technology Controller
Estop_Okay : BOOL; // Signal to Enable Axis or Remove Power
Jog_FWD : BOOL; // Run or Jog Forward request bit
Jog_REV : BOOL; // Run or Jog Reverse request bit
Move_ABS : BOOL; // Absolute Positioning Move
Move_REL : BOOL; // Relative Positioning Move
Stop_Now : BOOL; // Set Stop Now to Stop Axis at any time
Home_Axis : BOOL; // Reference Axis to Encoder Homing Position
Tech_Error : BOOL; // Technology Fault bit from Axis TO
Clear_Fault : BOOL; // Reset Axis Faults
Params : BasicDynamics; // Structure of Dynamic Parametes for Velocity & Position
END_VAR
VAR_OUTPUT
AxisState : INT;
Enabled : BOOL;
Faulted : BOOL;
Warning : BOOL;
Moving : BOOL;
Target_Reached : BOOL;
END_VAR
// MC_Power --- Axis Enable ---
AxisPower(Axis := Axis_Num // IN: INT
// MC_Reset --- Acknowledge Axis errors ---
AxisReset(Axis := Axis_Num // IN: INT
IF NOT Estop_Okay THEN
AxisState := 0;
END_IF;
IF Faulted THEN
AxisState := 20;
END_IF;
IF AxisState AxisStateMem THEN
AxisStateMem := AxisState;
StateUpdate := TRUE;
ELSE
StateUpdate := FALSE;
END_IF;
// Axis State Model of Operation
CASE AxisState OF
0 : // Axis at ESTOP or Disabled
IF Enabled THEN
AxisState := 1;
END_IF;
1 : // Axis is Ready to accept command
// Request to Jog or Run Axis with MC_Velocity
2..3 : // Axis is in a Jog or Run State
IF StateUpdate OR (AxisVelocity.Busy AND JogVelocity Params.Velocity) THEN
JogTrig := TRUE;
JogVelocity := Params.Velocity;
ELSE
JogTrig := FALSE;
END_IF;
// MC_MoveVelocity --- Jog or Run Axis at Velocity Setpoint ---
AxisVelocity(Axis := Axis_Num // IN: INT
4 : // Axis is Commanded to an Absolute Move
// MC_MoveAbsolute --- Absolute Axis Move ---
ABSMove(Axis := Axis_Num // IN: INT
IF Stop_Now THEN
AxisState := 6;
END_IF;
5 : // Axis is Commanded to a Relative Move
// MC_MoveRelative --- Absolute Axis Move ---
RELMove(Axis := Axis_Num // IN: INT
6 : // Axis is Commanded to a STOP
// MC_Stop --- Reference Axis position ---
AxisStop(Axis := Axis_Num // IN: INT
IF AxisStop.Done THEN
AxisState := 1;
END_IF;
7..10 : // Axis is Commanded to a Automatic Machine State
;
19 : // Axis is Commanded to Reference the Encoder
// MC_Home --- Reference Axis position ---
HomingActive(IN := NOT StateUpdate// IN: BOOL
IF HomingActive.Q (* AND AxisHome.Done *)THEN
AxisState := 1;
END_IF;
20 : // Axis is Reported to be Faulted
IF Enabled OR NOT ESTOP_Okay THEN
AxisState := 0;
END_IF;
ELSE:
// Statements_ELSE
;
END_CASE;
// One Shot Control Bits
Jog_ONS := Jog_FWD OR Jog_REV;
Move_ABS_ONS := Move_ABS;
Move_REL_ONS := Move_REL;
Stop_Now_ONS := Stop_Now;
Home_Axis_ONS := Home_Axis;
FaultTimed(IN := (Estop_Okay AND NOT Enabled) OR Tech_Error// IN: BOOL
,PT := T#500ms// IN: TIME
);
IF FaultTimed.Q THEN
Faulted := TRUE;
ELSE
Faulted := FALSE;
END_IF;
END_FUNCTION_BLOCK
Thanks Mequonite,
I hope I can handle it although I think it is too far. Thank you very much for your useful information.
Can you tell me how can I couple two or three motors with each other?
If I had more questions can I ask you?
Regards
I'm wondering how can we program complex Ladder sequences (Interlocking/Priorities) in terms of Structured Text.
I've been programming PLC in Ladder ever since and just started learning Structured Text. I'm having trouble interpreting Ladder sequence into Structured Text. Can anyone provide a link of a helpful ST programming manual?
Thanks very much,
Andrei
Philippines
Hi Mequonite,
Currently existing PLC is S5 & Hw is 101U.
Can you explain me couple of instructions.
what is mean by
L IW 0
L KM 11000000 00000011
AW
T FW 34
L FW 34
L FW 36
>
Can you help in following Program which is in Siemens S5. This program having some instructions which is new for me. Please explain me the meaning of
L FY 9
L FY 34
L FY 10
L FY 35
and
L C 1
L DW 17
!=F
= F 37.0
nicomp 2 years ago
Very cool. Brings back memories of long hours doing start-ups in warehouses and DCs.