ST Language Basics

Structured Text (ST) is a high-level, text-based programming language defined in the IEC 61131-3 standard. If you've ever written code in Pascal, C, or a similar procedural language, ST will feel familiar right away. It's the go-to choice for complex algorithms, math-heavy calculations, and data processing. Tasks that would be awkward to express in graphical languages like Ladder Diagram or Function Block Diagram.

Editor showing a simple Structured Text program with the Variables Table

Introduction to Structured Text

ST gives you a full-featured programming environment with support for:

  • Arithmetic and logical operations
  • Control flow structures (IF/THEN/ELSE, CASE, loops)
  • Function and function block calls
  • Complex expressions and calculations
  • Comments for code documentation

Variables in Structured Text

Before you write any ST code, you need to define the variables your program will use in the Variables Table. The Autonomy Edge IDE uses a dual-part structure for ST programming:

  1. Variables Table: Where you declare all variables with their names, types, and classes.
  2. Code Editor: Where you write the actual ST code that uses those variables.

Variables table showing local variables defined for a temperature control program

For detailed information about variable classes (Local, Input, Output, In-Out, External, Global, Temp) and data types, see the Variables and Data Types section.

Tip: When creating Programs (as opposed to Functions or Function Blocks), you should typically use the Local variable class. Input and Output classes are more appropriate for Functions and Function Blocks where parameters need to be passed between POUs (see Program Organization Units (POUs)).

Basic Syntax

Assignment Statements

The assignment operator in ST is := (colon-equals). It assigns a value to a variable.

code
variable_name := expression;

Examples:

code
temperature := 25.5; counter := counter + 1; running := TRUE; result := (value1 + value2) * 3;

Comments

ST supports two types of comments:

Single-line comments (using //):

code
counter := counter + 1; // Increment the counter

Multi-line comments (using (* ... *)):

code
(* This is a multi-line comment that can span multiple lines for detailed explanations *) timer(IN := enable, PT := T#5s);

Statements and Semicolons

Every statement in ST must end with a semicolon (;). You can put multiple statements on the same line, but it's best practice to keep one statement per line for readability.

Operators

ST provides a full set of operators for arithmetic, comparison, logical, and bitwise operations.

Arithmetic Operators

OperatorDescriptionExample
+Additionresult := a + b;
-Subtractionresult := a - b;
*Multiplicationresult := a * b;
/Divisionresult := a / b;
**Exponentiationresult := a ** 2;
MODModulo (remainder)result := a MOD 10;

Example:

code
temp_error := setpoint - sensor_temp; power_level := (error * gain) / 100; index := (counter + 1) MOD 1000;

Comparison Operators

OperatorDescriptionExample
=Equal toIF value = 100 THEN
<>Not equal toIF status <> OK THEN
<Less thanIF temp < 0.0 THEN
>Greater thanIF temp > 50.0 THEN
<=Less than or equalIF count <= 10 THEN
>=Greater than or equalIF level >= threshold THEN

Logical Operators

OperatorDescriptionExample
ANDLogical ANDIF enable AND ready THEN
ORLogical ORIF alarm OR warning THEN
XORLogical exclusive ORIF input1 XOR input2 THEN
NOTLogical negationIF NOT running THEN

Operator Precedence (highest to lowest):

  1. Parentheses ( )
  2. Function calls
  3. Exponentiation **
  4. Negation -, NOT
  5. Multiplication *, Division /, MOD
  6. Addition +, Subtraction -
  7. Comparison <, >, <=, >=, =, <>
  8. Boolean AND, XOR, OR

Example:

code
IF (sensor_temp > 50.0) OR (sensor_temp < 0.0) THEN alarm := TRUE; END_IF;

Bitwise Operators

OperatorDescriptionExample
SHLShift leftresult := value SHL 2;
SHRShift rightresult := value SHR 1;
ROLRotate leftresult := value ROL 3;
RORRotate rightresult := value ROR 2;

Control Structures

ST provides several control structures for managing program flow.

IF/THEN/ELSE Statement

The IF statement lets you conditionally execute blocks of code.

Basic IF:

code
IF condition THEN // statements END_IF;

IF/ELSE:

code
IF condition THEN // statements when TRUE ELSE // statements when FALSE END_IF;

IF/ELSIF/ELSE:

code
IF condition1 THEN // statements for condition1 ELSIF condition2 THEN // statements for condition2 ELSIF condition3 THEN // statements for condition3 ELSE // statements when all conditions are FALSE END_IF;

Example. Temperature Control:

code
IF enable THEN temp_error := setpoint - sensor_temp; IF timer.Q THEN heater_on := TRUE; cooler_on := FALSE; ELSIF temp_error < -2.0 THEN heater_on := FALSE; cooler_on := TRUE; ELSE heater_on := FALSE; cooler_on := FALSE; END_IF; ELSE heater_on := FALSE; cooler_on := FALSE; END_IF;

CASE Statement

The CASE statement provides multi-way selection based on a selector value.

code
CASE selector OF value1: // statements for value1 value2, value3: // statements for value2 or value3 value4..value6: // statements for range value4 to value6 ELSE // statements for all other values END_CASE;

Example:

code
CASE state OF 0: // Idle state motor_on := FALSE; ready := TRUE; 1: // Starting state motor_on := TRUE; ready := FALSE; 2: // Running state motor_on := TRUE; ready := TRUE; ELSE // Error state motor_on := FALSE; ready := FALSE; alarm := TRUE; END_CASE;

FOR Loop

The FOR loop repeats a block of code a specific number of times.

code
FOR counter := start_value TO end_value BY step DO // statements END_FOR;

The BY step part is optional (default is 1).

Example:

code
FOR i := 0 TO 9 DO buffer[i] := 0; // Initialize array elements END_FOR; FOR index := 10 TO 0 BY -1 DO countdown[index] := index; // Count down END_FOR;

WHILE Loop

The WHILE loop repeats as long as a condition is TRUE. The condition is checked before each iteration.

code
WHILE condition DO // statements END_WHILE;

Example:

code
WHILE (counter < 100) AND (NOT done) DO counter := counter + 1; IF process_item(counter) THEN done := TRUE; END_IF; END_WHILE;

REPEAT/UNTIL Loop

The REPEAT loop executes at least once and repeats until a condition becomes TRUE. The condition is checked after each iteration.

code
REPEAT // statements UNTIL condition END_REPEAT;

Example:

code
REPEAT value := read_sensor(); attempts := attempts + 1; UNTIL (value > 0) OR (attempts >= 10) END_REPEAT;

EXIT Statement

The EXIT statement immediately terminates the innermost loop (FOR, WHILE, or REPEAT).

code
FOR i := 0 TO 99 DO IF buffer[i] = target THEN found_index := i; EXIT; // Stop searching END_IF; END_FOR;

RETURN Statement

The RETURN statement exits a function or function block immediately. For functions, it returns the function's value.

code
IF error_condition THEN RETURN; // Exit early END_IF;

Function and Function Block Calls

ST lets you call functions and function blocks to perform operations and manage complex logic.

Function Calls

Functions return a single value and can be used directly in expressions.

code
result := ABS(value); // Absolute value max_value := MAX(a, b, c); // Maximum of values length := LEN(text_string); // String length

Function Block Calls

Function blocks are called with named parameters and maintain internal state between calls.

Basic syntax:

code
function_block_instance(parameter1 := value1, parameter2 := value2);

Example with TON (Timer On-Delay):

code
timer(IN := (temp_error > 2.0), PT := T#5s); IF timer.Q THEN // Timer has elapsed heater_on := TRUE; END_IF;

In this example:

  • timer is the function block instance (declared as type TON in the Variables Table)
  • IN and PT are input parameters
  • Q is an output accessed using dot notation (timer.Q)

Time Literals

ST supports time literals for specifying durations:

code
T#5s // 5 seconds T#100ms // 100 milliseconds T#1m30s // 1 minute 30 seconds T#2h15m // 2 hours 15 minutes T#1d12h // 1 day 12 hours

Example:

code
timer(IN := start_signal, PT := T#5s); delay_time := T#250ms;

Best Practices

  1. Use meaningful variable names: Choose descriptive names that indicate the variable's purpose.
  2. Add comments: Document complex logic and non-obvious operations.
  3. Keep expressions simple: Break complex calculations into multiple steps for clarity.
  4. Use parentheses: Make operator precedence explicit in complex expressions.
  5. Consistent indentation: Indent code blocks within control structures for readability.
  6. One statement per line: Avoid cramming multiple statements on one line.
  7. Initialize variables: Set appropriate initial values in the Variables Table.
  8. Use appropriate data types: Choose the smallest data type that meets your needs.

What's Next?