Structured Text and the Other IEC Languages

Structured Text, function block, SFC and instruction list, with one example written several ways.

The five languages

The IEC 61131-3 standard defines five programming languages, three graphical and two text. A project can mix them, choosing each for what it does best.

LanguageStyleBest forWeak at
Ladder diagram (LD)Graphical: contacts and coilsDiscrete logic, interlocks, anything an electrician must troubleshootMath, loops, strings, long sequences
Function block diagram (FBD)Graphical: blocks joined by wiresAnalog processing, PID loops, signal conditioningComplex branching
Structured text (ST)Text, Pascal-likeMath, arrays, loops, strings, reusable blocks, data handlingQuick visual fault-finding by non-programmers
Sequential function chart (SFC)Graphical: steps and transitionsStep-by-step machine sequences and batchHeavy computation (the actions are written in another language)
Instruction list (IL)Text, assembly-likeSmall code; some older systemsDeprecated in the third edition (2013); avoid in new work

One problem, five ways

A motor that starts on Start, holds itself, and stops on Stop, overload or emergency stop, written each way.

Ladder

See the start/stop rung on Ladder Logic in Practice.

Structured text

Motor_Run := (Start_PB OR Motor_Run) AND Stop_OK AND Overload_OK AND EStop_OK;

Function block diagram

An OR block (Start_PB, Motor_Run) feeding an AND block with Stop_OK, Overload_OK and EStop_OK, whose output is Motor_Run. The same blocks appear in the signal-processing example below.

Instruction list (deprecated)

LD   Start_PB
OR   Motor_Run
AND  Stop_OK
AND  Overload_OK
AND  EStop_OK
ST   Motor_Run

Sequential function chart

SFC is not used for a single seal-in. It is for sequences: for example, step 10 “Run motor” with the transition “Start pressed”, then step 20 “Stopped” with the transition “Stop pressed”.

Compare the length of the text version with the ladder one. Both are correct; choose the one the people who maintain the machine can read.

Structured Text basics

ElementSyntaxNotes
Assignmentx := a + b;Assignment uses :=; a single = is a comparison
Comparisona = b, a <> b, a >= bResult is BOOL
LogicAND, OR, XOR, NOTOperate on BOOL or on bit strings
IFIF c THEN … ELSIF d THEN … ELSE … END_IF;The conditions must be BOOL
CASECASE State OF 0: … 10: … ELSE … END_CASE;Ideal for state machines
FORFOR i := 1 TO 10 DO … END_FOR;Counted loop; keep the count small
WHILE, REPEATWHILE c DO … END_WHILE;Dangerous in a scan: an endless loop trips the watchdog
Function block callTimer1(IN := x, PT := T#5s); then Timer1.QInstance-based: each call uses its own data
Comments(* text *) or // textComment the reason, not the code
  • Variables must be declared with a type, in sections (VAR_INPUT, VAR_OUTPUT, VAR, VAR_GLOBAL). Initialize them.
  • Operator precedence: NOT, then multiplication and division, then addition and subtraction, then comparison, then AND, then XOR, then OR. Use brackets to make it obvious.
  • Types must match. Convert with INT_TO_REAL, REAL_TO_INT, DINT_TO_REAL and so on.
  • Edges. Use R_TRIG and F_TRIG blocks: Trig(CLK := Button); IF Trig.Q THEN … END_IF;

Writing a reusable function block

A function block bundles logic and its own memory (its instance variables) so that you can write it once and reuse it for every motor, valve or pump. It is the biggest productivity gain structured text offers. A motor block with a start-up check:

FUNCTION_BLOCK FB_Motor
VAR_INPUT
    Start_Cmd    : BOOL;   (* from the HMI or the sequence *)
    Stop_OK      : BOOL;   (* stop button, wired normally closed *)
    Overload_OK  : BOOL;
    EStop_OK     : BOOL;
    Running_FB   : BOOL;   (* contactor auxiliary contact *)
    Reset        : BOOL;
END_VAR
VAR_OUTPUT
    Run_Out      : BOOL;
    Fault        : BOOL;
END_VAR
VAR
    StartCheck   : TON;
END_VAR

(* run the motor unless something is wrong *)
Run_Out := (Start_Cmd OR Run_Out) AND Stop_OK AND Overload_OK AND EStop_OK AND NOT Fault;

(* fault if the contactor does not confirm within 3 s *)
StartCheck(IN := Run_Out AND NOT Running_FB, PT := T#3s);
IF StartCheck.Q OR NOT Overload_OK THEN
    Fault := TRUE;
END_IF;
IF Reset AND Overload_OK THEN
    Fault := FALSE;
END_IF;
  • Instantiate it once per motor: Pump1 : FB_Motor; Pump2 : FB_Motor; Each has its own timer and fault memory.
  • Call it every scan with its inputs wired, and read its outputs: Pump1(Start_Cmd := HMI_Pump1_Start, …); Q0_0 := Pump1.Run_Out;
  • Fix it once and every motor is fixed. That is the benefit of reusable blocks; Allen-Bradley calls these Add-On Instructions, Siemens calls them FBs, and CODESYS has Function Blocks.
  • Keep I/O out of the block. Pass the tags in and out, so that the block can be tested and reused.

Structured Text examples

Scaling function

FUNCTION Scale : REAL
VAR_INPUT
    Raw, RawMin, RawMax, EuMin, EuMax : REAL;
END_VAR
(* straight line through two points *)
Scale := EuMin + (Raw - RawMin) / (RawMax - RawMin) * (EuMax - EuMin);

Calling it with Raw = 20 736, RawMin = 0, RawMax = 27 648, EuMin = 0, EuMax = 10 returns 7.5. See the analog scaling in Timers, Counters and Data.

Moving average of an analog signal

VAR
    Buf   : ARRAY[0..9] OF REAL;
    Idx   : INT := 0;
    Sum   : REAL;
    Avg   : REAL;
    i     : INT;
END_VAR

Buf[Idx] := Level_m;                  (* newest sample *)
Idx := (Idx + 1) MOD 10;               (* wrap the index 0..9 *)
Sum := 0.0;
FOR i := 0 TO 9 DO
    Sum := Sum + Buf[i];
END_FOR;
Avg := Sum / 10.0;

Worked example: averaging a noisy level

  • Ten samples of a level (m): 4.10, 4.12, 4.09, 4.15, 4.11, 4.13, 4.08, 4.14, 4.10, 4.12.
  • Sum = 41.14 m; average = 41.14 ÷ 10 = 4.114 m, against a spread of 4.08 to 4.15 m in the raw signal.
  • Averaging ten samples reduces random noise by about √10 ≈ 3.2 times, at the cost of a delay of about five samples.
  • The loop runs ten times per scan, which is negligible; a loop of 10 000 iterations could trip the watchdog.

A simple state machine

CASE State OF
    0:  (* idle *)
        Inlet := FALSE; Agitator := FALSE; Outlet := FALSE;
        IF Start AND Level_Low THEN State := 10; END_IF;
    10: (* filling *)
        Inlet := TRUE;
        IF Level_High THEN Inlet := FALSE; State := 20; END_IF;
    20: (* mixing *)
        Agitator := TRUE;
        MixTimer(IN := TRUE, PT := T#120s);
        IF MixTimer.Q THEN Agitator := FALSE; MixTimer(IN := FALSE); State := 30; END_IF;
    30: (* draining *)
        Outlet := TRUE;
        IF Level_Empty THEN Outlet := FALSE; State := 0; END_IF;
    ELSE
        State := 0;
END_CASE;

More on this pattern, with timeouts and faults, is on Sequences and State Machines.

Function Block Diagram

In FBD, blocks (functions and function blocks) are wired together, and data flows from left to right. It suits signal processing, where you see the chain from raw value to alarm.

Level_Raw (INT) from the analog cardINT_TO_REALINOUTSCALEININ_MIN = 0IN_MAX = 27648OUTOUT_MIN = 0, OUT_MAX = 3.0 mGTIN1IN2 = 2.7 mOUTTONINPT = T#5sQHigh_AlarmSignals flow left to right between blocks. The scaled level feeds a comparator, andthe 5 s delay stops a splash from raising the alarm. The same logic in Structured Text:HighTimer(IN := Level_m > 2.7, PT := T#5s); High_Alarm := HighTimer.Q;
A raw analog value is converted, scaled, compared with a limit and delayed by a timer to produce a high-level alarm.
  • Execution order follows the data: a block runs after the blocks that feed it. Some tools let you set the order explicitly; check it when blocks feed back.
  • PID and analog control blocks (PID_Compact in Siemens, PIDE in Logix) are normally used in FBD. See Motors, Drives and PID Control.
  • Limits: large diagrams become tangled; split into smaller blocks.

Sequential Function Chart

An SFC describes a sequence as steps (what the machine does) joined by transitions (conditions that move to the next step). Only the active steps run their actions. It is based on the French GRAFCET standard (IEC 60848).

ElementMeaningExample
StepA state in which the machine does somethingS20 Clamp: close the clamp valve
Initial stepThe step that is active at start-upS0 Idle
TransitionA condition that moves from one step to the nextClamp_Closed AND Part_Present
ActionThe code that runs while a step is activeWritten in ladder, ST or FBD
Branch (selection)Choose one of several pathsGood part or reject part
Parallel branchStart several paths at once and wait for all to finishHeat the tank while filling another

SFC makes a sequence visible to the operator and the maintainer: the active step is highlighted, so you see exactly what the machine is waiting for. If your platform has no SFC, a state machine in ST does the same job.

Instruction List

IL is a low-level text language with one operation per line, like assembly. It was deprecated in the third edition of the standard (2013) and many new platforms do not offer it. You may meet it on older Mitsubishi and Omron programs (the mnemonic form of ladder: LD, AND, OR, OUT). If you inherit IL code, translate it to ladder or ST when you modify it.

Dialects: SCL, Logix ST, CODESYS

PlatformLanguage nameDifferences to watch
SiemensSCL (Structured Control Language)Local variables are prefixed #; global tags are quoted "Tag"; statements end with ;; the timer is an instance data block
Allen-Bradley LogixStructured TextUses :=; no #; tags and AOI instances are referenced directly; some IEC features are missing (check the manual)
CODESYSStructured Text (IEC)The reference dialect: FUNCTION_BLOCK, VAR_INPUT, instances and pointers
Omron SysmacStructured TextIEC compliant; variables with data types and namespaces
Mitsubishi GX WorksSTIEC compliant on the newer series; device addresses allowed
Unitronics UniLogicST/FBD/LDMixes graphical and text; check the supported instructions

Pitfalls and good habits

  • Assignment against comparison. x = 5 tests; x := 5 assigns. A tool should flag the mistake; many do not.
  • Assign each output in one place (one block, one routine). Two writes to the same variable in one scan, with the last one winning, is the text equivalent of a double coil.
  • Keep loops short and bounded. A FOR over 10 items is fine; a WHILE that waits for a sensor stops the scan and trips the watchdog.
  • Initialize variables, and decide which must survive power loss (retentive).
  • Comment intent. Say why (“fault if the contactor does not confirm within 3 s”), not what.
  • Do not use text for what an electrician must see. Interlocks and permissives are easier to fault-find in ladder.
  • Test off-line. Use the simulator and force inputs; ST has no visual power flow, so use the watch window.

Related

FAQ

Which language should I use?

Use ladder for discrete logic and interlocks, structured text for math, data handling and reusable blocks, function block diagram for analog signal chains and PID, and SFC (or a state machine) for sequences. Most real programs mix them.

Is structured text harder than ladder?

It is different: shorter for math and loops, but harder for a maintenance technician to troubleshoot live. If your plant’s staff know only ladder, keep the logic in ladder and use ST for calculations.

What is an Add-On Instruction or function block?

A reusable, tested piece of logic with its own memory and inputs and outputs: a motor, a valve, a PID wrapper. Writing a block once and instantiating it many times keeps the code consistent.

Why does my ST code compile but not work?

Common causes: = used where := was meant, an output written from two places, a variable that is not retentive or not initialized, or a function block that is not called every scan.

Can I convert ladder to structured text?

Often yes, by hand or with a tool, but the result may be harder to read than the original. Convert only where the text form is clearly better.

References

  • IEC 61131-3, Programmable controllers, Part 3: Programming languages, 3rd ed. (2013): LD, FBD, ST, SFC and IL (deprecated).
  • IEC 60848, GRAFCET specification language for sequential function charts.
  • Siemens, SIMATIC S7-1200/1500 Programming Guideline and SCL Programming Language Manual.
  • Rockwell Automation, Logix 5000 Controllers Structured Text Programming Manual (1756-PM007).
  • CODESYS Group, CODESYS Online Help (ST language reference); PLCopen, IEC 61131-3 Programming Languages.
  • Lewis, R., Programming Industrial Control Systems Using IEC 1131-3, IEE.

Last reviewed: October 2026. Instruction names, addresses and data sizes differ by manufacturer: confirm against your controller’s manual, and keep safety functions independent of standard PLC logic.