Draw control logic as ladder rungs — it compiles to Structured Text and runs on the controller.
How it works
A ladder POU is stored as an ordinary Structured Text file: the diagram model rides in a
leading comment marker (*@LADDER … *) and the compiled ST is the body. Because the file is
valid ST, everything else in the IDE — compile, download, upload, sync, rename — works on it unchanged.
Open the POU and the IDE shows this graphical editor; press Show ST to see the generated code.
Quick start
Create a ladder program: New program → Ladder Program (LD).
Press + Rung to add a rung.
Drag a part from the Parts palette onto the rung (or click a part to add it to the last rung).
Pick the variable for each element (type a new name, or choose a declared one from the list).
Add an output coil on the right.
Press Add missing declarations to declare any new variables, then Build / Download.
Toolbar
Button
What it does
+ Rung
Adds a new empty rung at the bottom.
Declarations…
Edits the program's VAR … END_VAR block directly.
Add missing declarations
Scans the diagram and declares any referenced variable
(as BOOL) and any function-block instance (with the right type) that isn't declared yet.
Show ST
Toggles a live view of the generated Structured Text.
? Help
Opens this page.
live status (top-right)
When online: 🟢 online · N symbols · X/Y matched
tells you live data is arriving and how many of this diagram's variables were found on the controller.
Parts & palette
The Parts row holds every element type. Two ways to use it:
Drag a chip onto a rung branch to drop it there.
Click a chip to add it to the last rung.
Either way the element editor opens pre-set to that part, so you only pick the variable.
Contacts
Part
Symbol
Conducts when…
Normally open (NO)
─] [─
its variable is TRUE
Normally closed (NC)
─]/[─
its variable is FALSE
Rising edge (P)
─]P[─
the variable goes FALSE→TRUE (one scan)
Falling edge (N)
─]N[─
the variable goes TRUE→FALSE (one scan)
Contacts in a row are ANDed (series); parallel branches are ORed. Edge contacts compile to
R_TRIG / F_TRIG instances automatically.
Compare box
─[ a > b ]─ conducts when the comparison is true. Operators:
>, <, >=, <=, =, <>.
Either side can be a variable or a literal (e.g. level > 20000).
Function block box
─[ TON ]─ The rung power to the left drives the block's input pin; the block's
output pin continues the rung. Extra outputs (like a timer's ET) can be sent to variables.
Pick a Standard block from the dropdown and the pins fill in for you, or choose
Custom / library block… for your own function block (e.g. MOTOR_DOL, a PID).
IEC 61131-3 standard blocks
Block
Purpose
Inputs
Outputs
TON
On-delay timer
IN, PT
Q, ET
TOF
Off-delay timer
IN, PT
Q, ET
TP
Pulse timer
IN, PT
Q, ET
CTU
Count up
CU, R, PV
Q, CV
CTD
Count down
CD, LD, PV
Q, CV
CTUD
Count up/down
CU, CD, R, LD, PV
QU, QD, CV
R_TRIG
Rising-edge detect
CLK
Q
F_TRIG
Falling-edge detect
CLK
Q
RS
Reset-dominant latch
S, R1
Q
SR
Set-dominant latch
S1, R
Q
Blocks chain: one block's output can drive the next block's input along the same rung.
Example — a count-up whose Q starts an off-delay timer:
sets the variable TRUE when the rung is true; stays set
Reset (unlatch)
─(R)─
clears the variable FALSE when the rung is true
Rungs, series & parallel
Contacts placed in a row form a series (AND).
Use + parallel branch to add an OR path; branches are ORed to power the coils.
Each rung has ▲ ▼ to reorder and ✕ to delete.
A rung's comment box labels it in the generated ST ((* Rung n: … *)).
Selecting and editing
Click an element or coil to select it; Ctrl+click adds or removes one; Shift+click selects a run on the same line.
Drag a box on empty space to select every element and coil it touches (Ctrl adds to the selection).
Click Rung N to select a whole rung (Ctrl/Shift for several, Ctrl+A all).
Double-click (or Enter) edits; Esc or a click on empty space clears the selection.
Ctrl+C / X / V copy, cut, paste · Ctrl+D duplicate · Del delete · Ctrl+Z / Y undo / redo (also ↶ ↷ in the top bar).
Ctrl+B wraps the selected side-by-side elements in a parallel branch · Insert adds a rung below · ← → step along a line.
Ctrl+F — Find / Replace… a variable across every rung; Replace all is one undoable step.
Right-click an element, coil or rung for its commands: toggle NO/NC, change coil type, add rung above/below, duplicate, edit rung as ST, move, delete.
The clipboard is shared by every ladder POU — copy rungs from one program into another. A pasted edge/one-shot gets its own detector instance.
Ctrl + mouse wheel or the − 100% + buttons zoom the diagram.
Drag one of several selected elements and all of them move.
Math / Move box (MOV, ADD, SUB, MUL, DIV, MOD, CPT) and Limit (LIM) in the parts bar.
In the branch editor choose Branch inside to nest a branch (up to three levels).
+ Rung as text… / Edit rung as text…: XIC Start BST XIC Motor NXB XIC Jog BND XIO Stop OTE Motor — XIC XIO ONS OSF EQU NEQ GRT GEQ LES LEQ LIM TON TOF TP CTU CTD MOV ADD SUB MUL DIV MOD CPT BST NXB BND OTE OTL OTU.
Verify (F7) marks the rungs with errors; clicking a message selects its rung.
Descriptions shows the comment after each declaration above its operand.
Go to… (Ctrl+G), Fold all / ▾ per rung, Print / PDF….
Cross reference… (right-click) and Find in all programs search the whole project.
In an ST program, View as ladder draws it as a read-only ladder with live values; statements with no exact ladder form stay as ST rungs. Convert to ladder POU… writes a new, editable ladder copy.
Online: Download changes (online) — the controller keeps running — or Discard changes.
The + on a branch adds an element; + coil adds an output.
Edit a rung as Structured Text
Double-click a rung (or press its ST… button) to see and edit that rung's Structured Text.
Save as ST turns it into a raw ST rung: it compiles to exactly your text, and the rung shows
as ST with an ST badge. Double-click again to keep editing.
Back to graphical restores the drawn rung and discards the ST.
Use this for logic that is awkward to draw — a CASE, a loop, arithmetic — right next to your ladder.
A raw ST rung is your responsibility to declare: Add missing declarations can't read
variables out of free-form ST, so declare those in Declarations… or in Global Variables.
Variables & globals
Every variable field offers a picker — the POU's own declared variables plus the project
Global Variables — so you choose instead of retyping.
Global variables (declared in the Global Variables file, VAR_GLOBAL … END_VAR)
are prepended to every POU, so you use them by name directly — no re-declaration.
Add missing declarations declares any drawn contact/coil (as BOOL) and any block
instance (with its type) that isn't declared yet.
%-addresses (like %IX0.0, %QW0) come from the device tree — declare an
alias AT %… in the POU and use the alias in the ladder.
Online monitoring
Go Online and the ladder animates from the running controller:
The energised path glows green — the left rail, then along each wire up to the first open contact,
through to the coil when the rung has power.
Each contact/coil shows its live value; a conducting element lights up.
Right-click → Set value… writes or forces a variable on the running controller (uses the same
write/force dialog as the variables pages; a %-address is forced, a plain variable is written).
The live status readout (top-right) confirms data is arriving and how many of the diagram's
variables were found — if it says 0/… matched, download this program.
Setting a value or forcing an output changes a running machine immediately. Make sure it is safe.
Tips
Press Show ST while you build to learn how each rung compiles.
Seal-in (motor latch): Start in parallel with the motor coil's own contact, and Stop (NC) in series.
Avoid variable names that collide with library block members (start, stop, reset…) at program scope; prefer distinct names like StartPB.
A rung with no coil is legal — it still runs its function blocks (e.g. a timer feeding a compare on another rung).