ExamRobotic

Structured Text (SCL)

Level: Advanced 5 min read 36 questions

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 *)
Typical mistakeMixing types without converting. #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.

SCL also follows the scan cycleA variable that is only written inside an IF keeps its value when no condition is true. That is useful, as in the hysteresis, but it is also the cause of many outputs that “get stuck”. If an output must be 0 when the condition is not met, you have to write it.

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.

Typical mistakeUsing the same outputs in several steps with loose assignments. If step 10 sets "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.

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:

SectionWhat for
InputData the block receives: start, stop, sensors
OutputData the block returns: output to the contactor, alarm
InOutData the block reads and modifies
StaticThe FB’s own memory between scans: states, timers
TempWorking variables that are not kept between scans
Typical mistakeReading a Temp variable before writing it in the same scan. Temp variables do not keep their value between scans: their initial content is not guaranteed. If something must be remembered, it goes in Static.

LAD or SCL?

Many good programs combine both: equipment blocks in SCL and the machine logic in LAD, calling those blocks.

Typical mistakes in SCL

Summary

Test what you have learned

36 practical questions with explained answers. Free, no sign-up.

Start the test