plc programming languages

iec 61131-3

ladder logic

5 Types of PLC Programming Languages Explained

‌
Five types of PLC programming languages shown as flat vector icons representing IEC 61131-3 standard

The IEC 61131-3 standard defines five PLC programming languages, and every serious PLC engineer needs to know all five even if they spend 90% of their time in one of them. Different vendors support different subsets, different tasks inside the same project call for different languages, and you will absolutely inherit code written in a language you have never touched. Here is a clear breakdown of what each one is, what it looks like, and when it is actually the right tool.

The IEC 61131-3 Standard: Why It Matters

Before IEC 61131-3 was published in 1993, every PLC vendor had their own proprietary language. Siemens had STEP, Allen-Bradley had relay ladder and 6200 Series instruction sets, Modicon had Concept. If you changed brands you basically started from scratch. The standard introduced a common programming model with five languages: Ladder Diagram (LD), Structured Text (ST), Function Block Diagram (FBD), Sequential Function Chart (SFC) and Instruction List (IL). IL was officially withdrawn in the 2013 edition, but you will still find it in legacy code and some older controllers, so it is worth knowing.

Not every platform supports all five. Siemens TIA Portal supports LD, FBD, STL (their IL variant), SCL (their ST variant) and GRAPH (their SFC variant). Rockwell Studio 5000 supports LD, ST, FBD and SFC but not IL. CODESYS supports all five plus CFC (Continuous Function Chart), which is a vendor extension. Check your platform's manual before you plan a project structure.

Ladder Diagram (LD): The Default for a Reason

Ladder Diagram is the most widely used PLC language in North America and still dominant globally in discrete manufacturing. It was designed to look like relay logic drawings so that electricians already familiar with control schematics could read and maintain PLC code without learning to program. Two vertical rails represent power rails. Between them you draw rungs containing contacts (inputs, conditions) and coils (outputs, actions).

Ladder is genuinely excellent for discrete I/O control, interlocks, sequences with many parallel conditions, and anything where you need an electrician or maintenance tech to troubleshoot live without a laptop. The graphical online view shows you exactly which contacts are energised in real time. That alone saves hours of fault-finding on the floor. It gets unwieldy fast when you need maths, string handling, or nested logic with many variables. Anything involving floating-point arithmetic in Ladder is painful.

TOF Fan Purge Delay After Motor Stop (CODESYS / Generic). Ladder logic (3 rungs): Rung 0: examine if Motor_Run_Cmd is on (XIC), then energize output Motor_Output (OTE). Rung 1: examine if Motor_Run_Cmd is on (XIC), then TOF on Purge_Timer. Rung 2: examine if Purge_Timer.Q is on (XIC), then energize output Purge_Fan_Output (OTE). When Motor_Run_Cmd drops, the TOF timer holds Purge_Timer.Q TRUE for 30 seconds, keeping the purge fan running after the motor stops. The fan output de-energises automatically once the delay expires. This is a classic post-run ventilation interlock used in enclosed motor starters and paint booths.

TOF Fan Purge Delay After Motor Stop (CODESYS / Generic)Ladder logic
Toggle inputs
Rung 0
Ladder logic rung: examine if Motor_Run_Cmd is on (XIC), then energize output Motor_Output (OTE) examine if Motor_Run_Cmd is on (XIC), then energize output Motor_Output (OTE) XIC Motor_Run_Cmd Motor_Run_Cmd Motor_Run_Cmd OTE Motor_Output Motor_Output Motor_Output
Rung 1
Ladder logic rung: examine if Motor_Run_Cmd is on (XIC), then TOF on Purge_Timer examine if Motor_Run_Cmd is on (XIC), then TOF on Purge_Timer XIC Motor_Run_Cmd Motor_Run_Cmd Motor_Run_Cmd TOF Purge_Timer 30000 0 TOFTimerPurge_TimerPurge_TimerPreset3000030000Accum00
Rung 2
Ladder logic rung: examine if Purge_Timer.Q is on (XIC), then energize output Purge_Fan_Output (OTE) examine if Purge_Timer.Q is on (XIC), then energize output Purge_Fan_Output (OTE) XIC Purge_Timer.Q Purge_Timer.Q Purge_Timer.Q OTE Purge_Fan_Output Purge_Fan_Output Purge_Fan_Output
energizedTip: click a contact in the diagram to flip its bit.
When Motor_Run_Cmd drops, the TOF timer holds Purge_Timer.Q TRUE for 30 seconds, keeping the purge fan running after the motor stops. The fan output de-energises automatically once the delay expires. This is a classic post-run ventilation interlock used in enclosed motor starters and paint booths.

Structured Text (ST): The Engineer's Favourite

Structured Text looks like Pascal or a simplified version of C. It uses variables, assignments, IF/THEN/ELSE, CASE statements, FOR loops, WHILE loops, and function calls. If you have ever written any high-level code, ST will feel immediately familiar. Most modern platforms use it: Siemens calls their version SCL, Beckhoff TwinCAT uses it natively in TwinCAT 3 alongside C++, and CODESYS ST is the closest thing to a universal implementation.

analog_scaling.st
(* Scale a 0-27648 raw integer from a 4-20 mA input to engineering units *)
(* Raw_Count is INT, Scaled_Value is REAL *)

VAR
    Raw_Count   : INT   := 0;
    Scaled_Value: REAL  := 0.0;
    EU_Low      : REAL  := 0.0;    (* e.g. 0.0 bar *)
    EU_High     : REAL  := 10.0;   (* e.g. 10.0 bar *)
    Raw_Low     : REAL  := 0.0;    (* 0 counts = 4 mA *)
    Raw_High    : REAL  := 27648.0; (* 27648 counts = 20 mA, S7 convention *)
END_VAR

(* Linear interpolation *)
Scaled_Value := EU_Low + ((INT_TO_REAL(Raw_Count) - Raw_Low) / (Raw_High - Raw_Low)) * (EU_High - EU_Low);

(* Clamp to valid range *)
IF Scaled_Value < EU_Low THEN
    Scaled_Value := EU_Low;
ELSIF Scaled_Value > EU_High THEN
    Scaled_Value := EU_High;
END_IF;

That code would take a dozen rungs in Ladder with MOV, CPT, and comparison instructions scattered everywhere. In ST it is six meaningful lines. ST is the right choice for recipe management, PID tuning logic, protocol parsers, mathematical transformations, and any algorithm with more than a couple of branches. If you are scaling analog signals, the analog scaling calculator can verify your EU_Low and EU_High numbers before you key them into code.

The downside: an electrician on the shop floor at 2 AM cannot read it without training, and going online in ST does not give you the same visual feedback as Ladder. For anything safety-critical or where maintenance staff need to trace logic without a programmer present, Ladder still wins on accessibility.

Function Block Diagram (FBD): Signals Flowing Left to Right

FBD represents logic as a network of interconnected function blocks, where outputs of one block feed inputs of the next. It is the natural language for process engineers who think in terms of signal flow, PID loops, and instrumentation diagrams. A PID block has inputs for setpoint, process variable, and tuning parameters, and an output for control value. You wire them together graphically. Siemens uses FBD extensively in process applications; Omron Sysmac Studio supports it well for motion profiles.

FBD shines in continuous process control: flow, temperature, pressure, level loops. It also works well for signal conditioning chains, where you might pass a raw analog value through a scaling block, then a limit alarm block, then a PID block. The graphical wiring makes the signal path obvious. It gets cluttered fast when you have complex discrete interlocks mixed in. Most engineers use FBD for the continuous parts and Ladder or ST for the discrete parts within the same project.

Function Block Diagram FBD showing analog scaling feeding PID controller in a PLC programming language example
FBD represents signal flow as connected blocks, making it ideal for continuous process control loops.

Sequential Function Chart (SFC): Built for State Machines

SFC is modelled after Grafcet, a French graphical specification language from the 1970s. You define steps (states) and transitions (conditions that move from one step to the next). Each step contains actions written in any of the other languages. SFC is the single best tool for multi-step sequences: filling machines, washing cycles, injection moulding cycles, test rigs, pick-and-place routines.

A typical SFC for a washing machine might have steps like: Wait For Start, Fill Tank, Heat Water, Wash, Drain, Rinse, Spin. Each transition between steps has a condition: tank_full, temp_reached, drain_empty, and so on. You can see the active step highlighted in the editor during online monitoring, which makes it very easy to identify exactly where a cycle is stuck. Siemens GRAPH and Rockwell SFC both implement this well. CODESYS SFC is particularly clean.

Where SFC falls down is one-shot or continuous control tasks. There is no benefit running a simple conveyor jog command through an SFC. Use it for things that have a defined start, a sequence of distinct states, and a defined end. For anything cyclical with branching paths, SFC with divergences (AND-splits and OR-splits) is hard to beat. The bottle filling project on this site shows a practical example of a multi-step sequence that maps directly to an SFC structure.

Instruction List (IL): Legacy You Cannot Ignore

IL is a low-level mnemonic language, similar to assembly. You work with a single accumulator and load values into it, then apply operations. A simple AND contact followed by a coil looks like this in IL:

simple_interlock.il
LD    Motor_Enable      (* Load Motor_Enable into accumulator *)
AND   Fault_Clear       (* AND with Fault_Clear *)
ANDN  EStop_Active      (* AND NOT with EStop_Active *)
ST    Motor_Output      (* Store result to Motor_Output *)

IEC 61131-3 deprecated IL in the 2013 edition, and for good reason. It is verbose, hard to read, and provides no debugging advantages over ST. But you will encounter it in Siemens STL (Statement List), older Omron controllers using mnemonic programming, and legacy CODESYS 2.x projects. Knowing how to read it is more important than knowing how to write it. If you are maintaining an IL program and have the option to migrate, ST is almost always the better destination.

Which Language Should You Use: A Practical Guide

LanguageBest ForAvoid WhenVendor Examples
Ladder (LD)Discrete I/O, interlocks, maintenance-readable logicComplex maths, string handling, nested algorithmsStudio 5000, TIA Portal, GX Works, Sysmac
Structured Text (ST)Algorithms, recipes, scaling, data manipulation, loopsSimple on/off logic that electricians must readTwinCAT, CODESYS, SCL in TIA Portal, Studio 5000
Function Block Diagram (FBD)PID loops, signal conditioning, continuous process controlComplex discrete interlocks, large sequential logicTIA Portal, Sysmac, CODESYS, Studio 5000
Sequential Function Chart (SFC)Multi-step sequences, batch processes, state machinesContinuous or simple single-rung controlTIA Portal GRAPH, Studio 5000 SFC, CODESYS
Instruction List (IL)Reading legacy code onlyAny new projectSiemens STL, older CODESYS 2.x
IEC 61131-3 language selection guide for common PLC application types

Mixing Languages in One Project

Every modern platform lets you mix languages within a single project, and you should use that. A well-structured project might use SFC at the top level to control a filling sequence, call Ladder routines for safety interlocks and motor control, use ST functions for scaling and recipe calculations, and use FBD for PID loops. The IEC 61131-3 model calls these Program Organisation Units (POUs): programs, function blocks, and functions. They can be written in different languages and call each other freely.

In Siemens TIA Portal, a typical S7-1500 project might have an OB1 main program in LAD, a filling sequence FB in GRAPH, a PID_Compact instance in FBD, and a scaling function in SCL. In Rockwell Studio 5000, you might have a main routine in Ladder, a motion sequence routine in SFC, and a recipe handler routine in ST. This is completely normal and encouraged. Forcing everything into one language because someone made a blanket rule is how you end up with 800-rung Ladder programs full of CPT instructions trying to do what five lines of ST would do cleanly.

A practical rule I have used for years: put anything a maintenance electrician might need to trace live in Ladder, put anything a control engineer writes once and configures via parameters in ST or FBD, and put anything with a clear start-to-finish sequence in SFC. Your future self and your customer's maintenance team will both thank you.

PLC Programming Languages and the Scan Cycle

Regardless of which language you use, the PLC scan cycle works the same way: read inputs, execute program, write outputs, repeat. The language choice does not change scan behaviour. ST and FBD execute just as deterministically as Ladder. What does change is execution order within a task. In Ladder, rungs execute top to bottom, left to right. In FBD, blocks execute in the order they are wired, which the compiler resolves. In SFC, only the actions associated with the currently active step execute each scan. Understanding this matters when you have cross-language calls and shared variables. See PLC Memory and Addressing Explained for a deeper look at how the CPU handles variable updates across tasks.

Related Blogs