Learn PLCs free

OpenPLC Structured Text Reference

OpenPLC compiles IEC 61131-3 Structured Text via the Matiec compiler. The supported subset is large but not 100% — this reference lists what works, what is partial, and what is unsupported. Use it as a quick lookup before porting commercial Structured Text into OpenPLC.

Supported data types

BOOL, BYTE, WORD, DWORD, LWORD
SINT, USINT, INT, UINT, DINT, UDINT, LINT, ULINT
REAL, LREAL
TIME, DATE, TIME_OF_DAY, DATE_AND_TIME
STRING (max 80 chars), WSTRING
ARRAY [..] OF <basetype>
STRUCT (declared in DUT)
ENUM (typed)

Operators

Arithmetic:  + - * / MOD **
Comparison:  = <> < > <= >=
Logical:     AND OR XOR NOT
Bitwise:     AND OR XOR NOT (on integer types)
Shift:       SHL SHR ROL ROR (function-call style)
Assignment:  := (in code), => (output assignment in FB calls)

Control flow

IF cond THEN ... ELSIF cond2 THEN ... ELSE ... END_IF;
CASE var OF
  1: ...
  2,3,4: ...
  5..10: ...
  ELSE ...
END_CASE;
FOR i := 1 TO 10 BY 1 DO ... END_FOR;
WHILE cond DO ... END_WHILE;
REPEAT ... UNTIL cond END_REPEAT;
EXIT;       (* break out of loop *)
RETURN;     (* return from function or program *)

Standard function blocks (built-in)

  • Timers: TON, TOF, TP, RTC
  • Counters: CTU, CTD, CTUD
  • Edge detection: R_TRIG, F_TRIG
  • Bistable: SR (set-dominant), RS (reset-dominant)
  • Math: ABS, SQRT, LN, LOG, EXP, SIN, COS, TAN, ASIN, ACOS, ATAN
  • Selection: SEL, MIN, MAX, LIMIT, MUX
  • String: LEN, LEFT, RIGHT, MID, CONCAT, INSERT, DELETE, REPLACE, FIND

Known limits vs full IEC 61131-3

  • No object-oriented extensions (METHOD, INTERFACE, classes from 2013 revision). Function blocks only, no inheritance.
  • STRING max 80 characters by default. WSTRING for Unicode.
  • No POINTER or REF_TO types — pure value semantics throughout.
  • Limited multi-tasking — Matiec generates single-task code; multiple POUs run sequentially in the configured task period.
  • Some math functions return slightly different types than CODESYS or TIA Portal — check the result type when porting code.

Worked example: 3-stage state machine

PROGRAM main
VAR
    Step       : INT := 0;
    StartBtn   : BOOL;
    StopBtn    : BOOL;
    OutputA    : BOOL;
    OutputB    : BOOL;
    Timer1     : TON;
END_VAR

CASE Step OF
    0:  (* IDLE *)
        OutputA := FALSE;
        OutputB := FALSE;
        IF StartBtn THEN Step := 1; END_IF;

    1:  (* PHASE A *)
        OutputA := TRUE;
        Timer1(IN := TRUE, PT := T#5s);
        IF Timer1.Q THEN
            Step := 2;
            Timer1(IN := FALSE);
        END_IF;

    2:  (* PHASE B *)
        OutputA := FALSE;
        OutputB := TRUE;
        Timer1(IN := TRUE, PT := T#3s);
        IF Timer1.Q THEN
            Step := 0;
            Timer1(IN := FALSE);
        END_IF;
END_CASE;

(* Stop button always returns to IDLE *)
IF StopBtn THEN Step := 0; END_IF;
END_PROGRAM

Related guides