structured text

{{Short description|Programming language for programmable logic controllers}}

{{For|the lightweight text markup languages|StructuredText|reStructuredText}}

Structured text, abbreviated as ST or STX, is one of the five languages supported by the IEC 61131-3 standard, designed for programmable logic controllers (PLCs).{{cite web |last1=Bacidore |first1=Mike |title=Should I limit programming to ladder logic or use all standards within IEC 61131? |url=https://www.controldesign.com/articles/2018/should-i-limit-programming-to-ladder-logic-or-use-all-standards-within-iec-61131/ |date=16 May 2018 |website=Control Design}}{{cite web |last1=Stevic |first1=Tom |title=A very short history of PLC programming platforms |url=https://www.controldesign.com/articles/2017/a-very-short-history-of-plc-programming-platforms/ |date=5 May 2017 |website=Control Design}} It is a high level language that is block structured and syntactically resembles Pascal, on which it is based.{{cite journal |last1=Roos |first1=Nieke |title=Programming PLCs using Structured Text |publisher=Department of Computing Science, University of Nijmegen|citeseerx=10.1.1.49.2016 }} All of the languages share IEC61131 Common Elements. The variables and function calls are defined by the common elements so different languages within the IEC 61131-3 standard can be used in the same program.

Complex statements and nested instructions are supported:

  • Iteration loops (REPEAT-UNTIL; WHILE-DO)
  • Conditional execution (IF-THEN-ELSE; CASE)
  • Functions (SQRT(), SIN())

Sample program

(* simple state machine *)

TxtState := STATES[StateMachine];

CASE StateMachine OF

1: ClosingValve();

StateMachine := 2;

2: OpeningValve();

ELSE

BadCase();

END_CASE;

Unlike in some other programming languages, there is no fallthrough for the CASE statement: the first matching condition is entered, and after running its statements, the CASE block is left without checking other conditions.

=Additional ST programming examples=

// PLC configuration

CONFIGURATION DefaultCfg

VAR_GLOBAL

b_Start_Stop : BOOL; // Global variable to represent a boolean.

b_ON_OFF : BOOL; // Global variable to represent a boolean.

Start_Stop AT %IX0.0:BOOL; // Digital input of the PLC (Address 0.0)

ON_OFF AT %QX0.0:BOOL; // Digital output of the PLC (Address 0.0). (Coil)

END_VAR

// Schedule the main program to be executed every 20 ms

TASK Tick(INTERVAL := t#20ms);

PROGRAM Main WITH Tick : Monitor_Start_Stop;

END_CONFIGURATION

PROGRAM Monitor_Start_Stop // Actual Program

VAR_EXTERNAL

Start_Stop : BOOL;

ON_OFF : BOOL;

END_VAR

VAR // Temporary variables for logic handling

ONS_Trig : BOOL;

Rising_ONS : BOOL;

END_VAR

// Start of Logic

// 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;

END_PROGRAM

== Function block example ==

//=======================================================================

// Function Block Timed Counter : Incremental count of the timed interval

//=======================================================================

FUNCTION_BLOCK FB_Timed_Counter

VAR_INPUT

Execute : BOOL := FALSE; // Trigger signal to begin Timed Counting

Time_Increment : REAL := 1.25; // Enter Cycle Time (Seconds) between counts

Count_Cycles : INT := 20; // Number of Desired Count Cycles

END_VAR

VAR_OUTPUT

Timer_Done_Bit : BOOL := FALSE; // One Shot Bit indicating Timer Cycle Done

Count_Complete : BOOL := FALSE; // Output Bit indicating the Count is complete

Current_Count : INT := 0; // Accumulating Value of Counter

END_VAR

VAR

CycleTimer : TON; // Timer FB from Command Library

CycleCounter : CTU; // Counter FB from Command Library

TimerPreset : TIME; // Converted Time_Increment in Seconds to MS

END_VAR

// Start of Function Block programming

TimerPreset := REAL_TO_TIME(in := Time_Increment) * 1000;

CycleTimer(

in := Execute AND NOT CycleTimer.Q,

pt := TimerPreset);

Timer_Done_Bit := CycleTimer.Q;

CycleCounter(

cu := CycleTimer.Q,

r := NOT Execute,

pv := Count_Cycles);

Current_Count := CycleCounter.cv;

Count_Complete := CycleCounter.q;

END_FUNCTION_BLOCK

References