Structured Text (SCL)
SCL (Structured Control Language) is Siemens’ text language. In the IEC 61131-3 standard it is called ST (Structured Text). It resembles programming languages such as Pascal and is ideal for what is awkward in ladder logic: calculations, chained comparisons, working through lists of data or programming a sequence with many steps. A good PLC programmer uses LAD for the signal logic that the plant technician must be able to follow, and SCL for calculations and complex sequences.
The basics: assignments and expressions
Every statement ends with a semicolon, and assignment is written with :=. Global tags go in double
quotes and the block’s local variables start with a hash sign:
"Conveyor_Motor" := "Start" AND NOT "Stop_Pressed";
#Average := (#Value1 + #Value2) / 2.0;
// This is a single-line comment
(* And this is a multi-line comment *)
- Logic operators:
AND,OR,XOR,NOT. - Comparisons:
=,<>,<,>,<=,>=. Careful: comparison is=and assignment is:=. - Arithmetic:
+,-,*,/,MOD(remainder) and**(power).
#Average := #Total / 4; with
an integer #Total gives an integer result: 7 / 4 = 1, not 1.75. To get decimals you have to work with Real
numbers, for example converting with INT_TO_REAL or dividing by 4.0 with Real variables.IF: decisions
IF #Temperature > 80.0 THEN
"Fan" := TRUE;
ELSIF #Temperature < 70.0 THEN
"Fan" := FALSE;
END_IF;
This example is a hysteresis: the fan starts above 80 °C and does not stop until it drops below 70 °C. Between 70 and 80 °C no branch runs and the fan keeps its state. That stops it from starting and stopping constantly when the temperature hovers around a single value.
CASE: step sequences
CASE chooses a block of statements according to the value of an integer variable. It is the clearest way to program a sequence in SCL: each step is a number, and each step has its actions and its condition to move on.
CASE #Step OF
0: // Idle
IF "Start" AND "Gripper_Open" THEN
#Step := 10;
END_IF;
10: // Lower the gripper
"Gripper_Lower" := TRUE;
IF "Gripper_Down" THEN
#Step := 20;
END_IF;
20: // Close the gripper
"Gripper_Close" := TRUE;
IF "Gripper_Closed" THEN
#Step := 30;
END_IF;
ELSE
#Step := 0;
END_CASE;
In each scan only the current step runs. While the gripper has not reached the bottom, the program enters step 10, checks the sensor and leaves, and the rest of the program keeps working. Numbering in tens leaves room to add steps in between without renumbering everything.
"Gripper_Lower" := TRUE and no other step sets it to FALSE, the gripper stays down forever. A clean way
is to calculate the outputs separately from the step: "Gripper_Lower" := #Step = 10 OR #Step = 20;Loops: FOR, WHILE and REPEAT
// Find the maximum value in an array of 10 temperatures
#Maximum := #Temperatures[0];
FOR #i := 1 TO 9 DO
IF #Temperatures[#i] > #Maximum THEN
#Maximum := #Temperatures[#i];
END_IF;
END_FOR;
Loops are for working through data that is already in memory, such as an array, and they finish in the same scan. They are never used to wait for an input to change: inside the loop the inputs are not updated, the scan gets longer and the PLC ends up in STOP for exceeding the maximum cycle time.
- FOR: a known number of iterations.
- WHILE: repeats while the condition is true; it may not run at all.
- REPEAT … UNTIL: repeats until the condition is true; it runs at least once.
Timers and counters in SCL
The same IEC timers and counters as in LAD are used, by calling their instance. Inside an FB, the most convenient way is to declare them as static variables (multi-instance):
// In the FB's Static section: T_Wait : TON_TIME;
#T_Wait(IN := "Part_Present", PT := T#2s);
IF #T_Wait.Q THEN
"Pusher" := TRUE;
END_IF;
The timer instruction must run every scan, not inside an IF that is sometimes false; otherwise the timer stops updating and behaves strangely.
Reusable blocks
SCL shines in reusable FBs: a “Motor” or “Valve” block with its own inputs, outputs, alarms and memory, called once for each piece of equipment. The interface is declared in sections:
| Section | What for |
|---|---|
| Input | Data the block receives: start, stop, sensors |
| Output | Data the block returns: output to the contactor, alarm |
| InOut | Data the block reads and modifies |
| Static | The FB’s own memory between scans: states, timers |
| Temp | Working variables that are not kept between scans |
LAD or SCL?
- LAD: signal logic, interlocks, start and stop, everything the maintenance technician has to follow with the machine running.
- SCL: calculations, scaling, recipes, array handling, long sequences with CASE and reusable blocks.
Many good programs combine both: equipment blocks in SCL and the machine logic in LAD, calling those blocks.
Typical mistakes in SCL
- Confusing
=(compare) with:=(assign). - Dividing integers and expecting decimals.
- Waiting inside a loop for an input to change.
- Writing an output only inside an IF and having it get stuck.
- Calling a timer only sometimes, inside an IF.
- Using Temp variables as memory between scans.
Summary
- SCL is Siemens’ Structured Text (ST in IEC 61131-3). Assignment with
:=, comparison with=. - IF for decisions, CASE for step sequences, FOR/WHILE/REPEAT for working through data, never for waiting.
- IEC timers are called every scan, preferably as multi-instances inside the FB.
- Static keeps memory between scans; Temp does not.
- LAD for the logic that is troubleshot on the plant floor; SCL for calculations and complex sequences.
Test what you have learned
36 practical questions with explained answers. Free, no sign-up.
Start the test