Structured Text

Write PLC programs in IEC 61131-3 Structured Text with the code editor

Syntax Overview

Structured Text (ST) is a high-level, text-based PLC programming language defined by IEC 61131-3. Its syntax resembles Pascal, making it approachable for anyone with experience in conventional programming. Statements are terminated with semicolons, and blocks of code are enclosed between keyword pairs like IF...END_IF or FOR...END_FOR.

The Sim Assist code editor provides syntax highlighting, real-time error checking, and autocompletion for all IEC 61131-3 keywords, standard functions, and your project's declared variables.

Variable Declarations

Variables are declared in a dedicated block at the top of your program, between keyword pairs that define their scope:

VAR
    motorRunning : BOOL := FALSE;
    partCount    : INT  := 0;
    temperature  : REAL;
END_VAR

VAR_INPUT
    startButton  : BOOL;
    speedSetpoint : REAL;
END_VAR

VAR_OUTPUT
    conveyorSpeed : REAL;
    alarmActive   : BOOL;
END_VAR
  • VAR — Local variables, visible only inside the current program or function block.
  • VAR_INPUT — Values received from outside (bound to simulation sensors or passed by a calling block).
  • VAR_OUTPUT — Values sent outward (bound to simulation actuators or returned to a calling block).

Data Types

Sim Assist supports all standard IEC 61131-3 elementary data types:

TypeDescriptionExample
BOOLBooleanTRUE, FALSE
INT16-bit signed integer42, -7
DINT32-bit signed integer100000
REAL32-bit floating point3.14, -0.5
LREAL64-bit floating point2.718281828
TIMEDurationT#500ms, T#2s, T#1m30s
STRINGText string'Hello'
BYTE8-bit unsigned16#FF
WORD16-bit unsigned16#ABCD

Control Structures

IF / THEN / ELSE

IF temperature > 80.0 THEN
    alarmActive := TRUE;
    conveyorSpeed := 0.0;
ELSIF temperature > 60.0 THEN
    conveyorSpeed := speedSetpoint * 0.5;
ELSE
    alarmActive := FALSE;
    conveyorSpeed := speedSetpoint;
END_IF;

CASE

CASE machineState OF
    0: (* Idle *)
        motorRunning := FALSE;
    1: (* Running *)
        motorRunning := TRUE;
    2: (* Faulted *)
        motorRunning := FALSE;
        alarmActive := TRUE;
END_CASE;

FOR Loop

FOR i := 0 TO 9 DO
    buffer[i] := 0;
END_FOR;

WHILE Loop

WHILE sensorValue < threshold DO
    adjustOutput();
END_WHILE;

REPEAT Loop

REPEAT
    attempts := attempts + 1;
UNTIL attempts >= maxRetries
END_REPEAT;

Function and Function Block Calls

Call standard functions directly by name:

result := ADD(a, b);
clampedValue := LIMIT(minVal, inputVal, maxVal);

Function blocks must be instantiated as variables and then called:

VAR
    delayTimer : TON;
    isDelayed  : BOOL;
END_VAR

delayTimer(IN := startButton, PT := T#3s);
isDelayed := delayTimer.Q;

Example Program

The following program controls a conveyor that starts when a button is pressed, runs for 10 seconds, counts the parts detected by a sensor, and stops automatically:

PROGRAM ConveyorControl
VAR_INPUT
    startButton : BOOL;
    partSensor  : BOOL;
END_VAR
VAR_OUTPUT
    conveyorMotor : BOOL;
    totalParts    : INT;
END_VAR
VAR
    runTimer    : TON;
    partEdge    : R_TRIG;
END_VAR

(* Start the timer when the button is pressed *)
runTimer(IN := startButton, PT := T#10s);

(* Motor runs while timer is active but not yet elapsed *)
conveyorMotor := runTimer.IN AND NOT runTimer.Q;

(* Count rising edges from the part sensor *)
partEdge(CLK := partSensor);
IF partEdge.Q THEN
    totalParts := totalParts + 1;
END_IF;

END_PROGRAM

On this page