PLC Simulator
dialects
timers
edge detection
ton
rtrig
tof
cheat sheet
iec
allen bradley
siemens
mitsubishi

PLC Dialect Cheat Sheet: TON, R_TRIG, TOF Across 8 Dialects

By PLC Simulation Software12 min read

PLC Dialect Cheat Sheet: TON, R_TRIG, TOF Across 8 Dialects

PLC dialect cheat sheet comparing TON, R_TRIG and TOF idioms across 8 PLC dialects

Three of the most-searched PLC programming questions come down to the same thing: "how do I write a TON in Mitsubishi?", "what is the Allen-Bradley R_TRIG syntax?", "how does a TOF work in Siemens?" The logic is identical across all vendors. The notation is not. This reference gives you the canonical idiom for each, dialect by dialect, with the actual code.

The snippets below are sourced from the simulator's curriculum starters and briefings for lessons 7 (R_TRIG), 8 (TON), and 9 (TOF). You can work through each lesson interactively at /learn/dialects/<dialect>/<lesson> — the links are included in each section.


TON — On-Delay Timer

A TON (timer on-delay) starts counting when its input goes TRUE. Its output (the done bit, .Q) goes TRUE only if the input has been TRUE continuously for at least the preset duration. If the input drops before the preset elapses, the accumulator resets to zero. This is the standard "delay-before-action" building block — warn before starting a conveyor, debounce a noisy sensor, hold an alarm state for a minimum time.

Every dialect in the curriculum has a native on-delay timer. The differences are in the call shape and, importantly, in the preset units.

IEC 61131-3

VAR
  ENABLE   AT %I0.0 : BOOL;
  WARN_LAMP AT %Q0.0 : BOOL;
  T_WARN   : TON;
END_VAR

T_WARN(IN := ENABLE, PT := T#3s);

WARN_LAMP := T_WARN.Q;

T#3s is a typed TIME literal — the unit is on the page, which makes misreading the preset substantially harder. T_WARN is a named function-block instance; you can have many timers without any risk of address collision.

Allen-Bradley (Studio 5000 / RSLogix)

TAG ENABLE   I:0/0 BOOL
TAG WARN_LAMP O:0/0 BOOL
TAG T_WARN   TON

TON T_WARN IN:ENABLE PT:3000

XIC T_WARN.Q OTE WARN_LAMP

PT is in milliseconds — 3000 means 3 seconds. The instance is declared as a TON tag. The done bit is read as T_WARN.Q, which you examine with a standard XIC contact.

Siemens (TIA Portal SCL)

VAR
  ENABLE   AT %I0.0 : BOOL;
  WARN_LAMP AT %Q0.0 : BOOL;
  T_WARN   : TON;
END_VAR

T_WARN(IN := ENABLE, PT := T#3s);

WARN_LAMP := T_WARN.Q;

Siemens SCL in TIA Portal (S7-1200/1500) uses the same IEC-compatible function-block call. The named-argument form IN := and PT := with a T# literal is standard across IEC-compliant environments.

Mitsubishi (GX Works — IL mnemonics)

VAR
  ENABLE   AT %I0.0 : BOOL;
  WARN_LAMP AT %Q0.0 : BOOL;
  T_WARN   : TON;
END_VAR

LD  X0
OUT T1 K30

LD  T1
OUT Y0

Mitsubishi has no TON function block. Instead, T1 is a numbered timer device. OUT T1 K30 drives the timer's IN from whatever is on the rung — here LD X0 (ENABLE) — and sets a preset of K30. On the default 100 ms timer base, K30 = 30 × 100 ms = 3 seconds. The timer's done bit is read as a plain contact: LD T1. The classic gotcha: K30 is 3 seconds, not 30 seconds and not 30 milliseconds. The unit is a memorised convention, not something the syntax tells you.

Schneider (Unity Pro / EcoStruxure — SCL)

VAR
  ENABLE   AT %I0.0 : BOOL;
  WARN_LAMP AT %Q0.0 : BOOL;
  T_WARN   : TON;
END_VAR

T_WARN(IN := ENABLE, PT := T#3s);

WARN_LAMP := T_WARN.Q;

Unity Pro and EcoStruxure both support IEC 61131-3 Structured Text. The TON call is identical to the IEC form.

Delta (WPLSoft — IL mnemonics)

LD  X0
TMR T1 K30

LD  T1
OUT Y0

Delta's TMR instruction is the timer call — syntactically equivalent to Mitsubishi's OUT T<n> for this purpose. K30 is again 30 × 100 ms = 3 seconds on the default 100 ms base. The done bit is read as LD T1.

Omron (CX-Programmer — IL mnemonics)

VAR
  ENABLE   AT %I0.0 : BOOL;
  WARN_LAMP AT %Q0.0 : BOOL;
  T_WARN   : TON;
END_VAR

LD      ENABLE
TIM 1 #30

LD      T1
OUT     WARN_LAMP

Omron uses TIM as the timer instruction. The preset uses a # prefix (#30) rather than a K prefix, but the base is still 100 ms — so #30 = 3 seconds. The done-bit contact is T1.

Instruction List (IEC IL)

VAR
  ENABLE   AT %I0.0 : BOOL;
  WARN_LAMP AT %Q0.0 : BOOL;
  T_WARN   : TON;
END_VAR

CAL T_WARN(IN := ENABLE, PT := T#3s)

LD   T_WARN.Q
ST   WARN_LAMP

IEC IL uses CAL to call a function block with named arguments, then LD/ST to move the output to a coil.

TON Quick Reference

| Dialect | Timer call | Preset format | Done-bit read | |---|---|---|---| | IEC 61131-3 | T_WARN(IN := ENABLE, PT := T#3s) | Typed TIME literal | T_WARN.Q | | Allen-Bradley | TON T_WARN IN:ENABLE PT:3000 | Integer milliseconds | T_WARN.Q (via XIC) | | Siemens SCL | T_WARN(IN := ENABLE, PT := T#3s) | Typed TIME literal | T_WARN.Q | | Mitsubishi | OUT T1 K30 | K × 100 ms | LD T1 | | Schneider | T_WARN(IN := ENABLE, PT := T#3s) | Typed TIME literal | T_WARN.Q | | Delta | TMR T1 K30 | K × 100 ms | LD T1 | | Omron | TIM 1 #30 | # × 100 ms | LD T1 | | Instruction List | CAL T_WARN(IN := ENABLE, PT := T#3s) | Typed TIME literal | T_WARN.Q (via LD/ST) |

At a glance, the same on-delay timer in every dialect:

Comparison table of the TON on-delay timer call, preset format and done-bit read across PLC dialects

Practice TON across all dialects: IEC lesson 8, Allen-Bradley lesson 8, Siemens lesson 8, Mitsubishi lesson 8, Delta lesson 8, Omron lesson 8.


R_TRIG — Rising-Edge Detector

An R_TRIG (rising-edge trigger) produces a one-scan TRUE pulse the moment its input transitions from FALSE to TRUE. Even if the input stays TRUE for multiple scans, the output is only TRUE on the first scan of that transition. This is the building block for counting events, incrementing registers on a single button-press, and preventing double-triggers on held inputs.

IEC, Allen-Bradley, Siemens, Schneider, and Instruction List all expose R_TRIG as a named function-block instance with a .Q output. Mitsubishi, Delta, and Omron have no atomic rising-edge instruction. In those dialects, the one-shot is synthesised from two rungs and a history bit.

Edge detection is where vendor naming diverges most — R_TRIG/F_TRIG in IEC, ONS/OSR in Allen-Bradley, and P/N edge contacts in Siemens:

Comparison table of rising and falling edge detection — R_TRIG F_TRIG vs ONS OSR vs P N edge contacts across PLC dialects

IEC 61131-3

VAR
  BUTTON      AT %I0.0 : BOOL;
  COUNT_PULSE AT %Q0.0 : BOOL;
  EDGE_DET    : R_TRIG;
END_VAR

EDGE_DET(CLK := BUTTON);

| EDGE_DET.Q | := COUNT_PULSE ;

Declare EDGE_DET as an R_TRIG instance, call it with CLK := BUTTON, read the pulse via EDGE_DET.Q. The function block manages the history bit internally.

Allen-Bradley (Studio 5000 / RSLogix)

TAG BUTTON      I:0/0 BOOL
TAG COUNT_PULSE O:0/0 BOOL
TAG EDGE_DET    R_TRIG

R_TRIG EDGE_DET CLK:BUTTON

XIC EDGE_DET.Q OTE COUNT_PULSE

TAG EDGE_DET R_TRIG declares the instance. The instruction R_TRIG EDGE_DET CLK:BUTTON calls it. XIC EDGE_DET.Q OTE COUNT_PULSE reads the done bit on a standard rung.

Siemens (TIA Portal SCL)

VAR
  BUTTON      AT %I0.0 : BOOL;
  COUNT_PULSE AT %Q0.0 : BOOL;
  EDGE_DET    : R_TRIG;
END_VAR

EDGE_DET(CLK := BUTTON);

COUNT_PULSE := EDGE_DET.Q;

Same IEC-compatible form as the IEC starter. Siemens TIA Portal supports R_TRIG natively.

Mitsubishi (GX Works — synthesised from primitives)

Mitsubishi GX-IL has no R_TRIG instruction. The synthesis: a rising edge of BUTTON is the scan where BUTTON is TRUE and its previous-scan value (PREV_BTN) is FALSE.

VAR
  BUTTON      AT %I0.0 : BOOL;
  COUNT_PULSE AT %Q0.0 : BOOL;
  PREV_BTN    AT %M0.0 : BOOL;
END_VAR

; Rung 1: pulse = BUTTON AND NOT (previous BUTTON)
LD   X0
ANI  PREV_BTN
OUT  Y0

; Rung 2: capture this scan's BUTTON into PREV_BTN for the next scan
LD   X0
OUT  PREV_BTN

Rung order is load-bearing. The pulse rung must execute while PREV_BTN still holds the previous scan's value. If you write rung 2 first, PREV_BTN already matches X0 by the time the pulse comparison runs, and COUNT_PULSE never fires. ANI is the AND-inverse (AND NOT) instruction.

Schneider (Unity Pro / EcoStruxure — SCL)

VAR
  BUTTON      AT %I0.0 : BOOL;
  COUNT_PULSE AT %Q0.0 : BOOL;
  EDGE_DET    : R_TRIG;
END_VAR

EDGE_DET(CLK := BUTTON);

COUNT_PULSE := EDGE_DET.Q;

Unity Pro SCL supports R_TRIG natively with the standard IEC call form.

Delta (WPLSoft — synthesised from primitives)

Delta WPLSoft has no R_TRIG instruction. The synthesis pattern is mnemonic-for-mnemonic identical to Mitsubishi:

VAR
  BUTTON      AT %I0.0 : BOOL;
  COUNT_PULSE AT %Q0.0 : BOOL;
  PREV_BTN    AT %M0.0 : BOOL;
END_VAR

; Rung 1: pulse = BUTTON AND NOT (previous BUTTON)
LD   X0
ANI  PREV_BTN
OUT  Y0

; Rung 2: latch this scan's BUTTON into PREV_BTN (must come AFTER rung 1)
LD   X0
OUT  PREV_BTN

Same two-rung structure, same ANI for AND-NOT, same scan-order constraint.

Omron (CX-Programmer — synthesised from primitives)

Omron CX-Programmer has no R_TRIG instruction. Same two-rung approach, but Omron uses symbolic variable names and AND NOT (two words) rather than ANI:

VAR
  BUTTON      AT %I0.0 : BOOL;
  COUNT_PULSE AT %Q0.0 : BOOL;
  PREV_BTN    AT %M0.0 : BOOL;
END_VAR

; Rung 1: pulse = BUTTON AND NOT (previous BUTTON)
LD       BUTTON
AND NOT  PREV_BTN
OUT      COUNT_PULSE

; Rung 2: refresh the history bit AFTER the pulse rung has fired
LD   BUTTON
OUT  PREV_BTN

The logic is identical to Mitsubishi and Delta. The surface forms differ: AND NOT instead of ANI, symbolic names instead of device addresses.

Instruction List (IEC IL)

VAR
  BUTTON      AT %I0.0 : BOOL;
  COUNT_PULSE AT %Q0.0 : BOOL;
  EDGE_DET    : R_TRIG;
END_VAR

CAL EDGE_DET(BUTTON)

LD   EDGE_DET.Q
ST   COUNT_PULSE

R_TRIG Quick Reference

| Dialect | Mechanism | Key instruction | History bit managed by | |---|---|---|---| | IEC 61131-3 | Native FB | EDGE_DET(CLK := BUTTON) | FB internals | | Allen-Bradley | Native FB | R_TRIG EDGE_DET CLK:BUTTON | FB internals | | Siemens SCL | Native FB | EDGE_DET(CLK := BUTTON) | FB internals | | Mitsubishi | Synthesised | LD X0 / ANI PREV_BTN / OUT Y0 | M-device relay (M0) | | Schneider | Native FB | EDGE_DET(CLK := BUTTON) | FB internals | | Delta | Synthesised | LD X0 / ANI PREV_BTN / OUT Y0 | M-device relay (M0) | | Omron | Synthesised | LD BUTTON / AND NOT PREV_BTN / OUT COUNT_PULSE | Work-bit relay | | Instruction List | Native FB | CAL EDGE_DET(BUTTON) | FB internals |

The defining behaviour of any rising-edge detector — a single one-scan pulse per FALSE→TRUE transition, no matter how long the input is held:

R_TRIG rising-edge one-shot timing diagram showing a single-scan Q pulse on each rising edge of CLK

In ladder, the synthesised one-shot is a normally-open input contact in series with a normally-closed history bit:

Ladder rung for a synthesised rising-edge one-shot with a BUTTON contact and a normally-closed PREV_BTN history bit driving COUNT_PULSE

Practice R_TRIG across all dialects: IEC lesson 7, Allen-Bradley lesson 7, Siemens lesson 7, Mitsubishi lesson 7, Delta lesson 7, Omron lesson 7.


TOF — Off-Delay Timer

A TOF (timer off-delay) works the inverse of a TON. When its input goes TRUE, its output goes TRUE immediately. When the input drops to FALSE, the output stays TRUE for the full preset duration before going FALSE. If the input returns to TRUE during the hold window, the timer resets and the output remains TRUE — no gap in output. This pattern is used wherever you need a hold-open window: an automatic door that stays open for 5 seconds after the last person passes, a lubrication pump that runs for 10 seconds after the machine stops, a fan that keeps running after the motor cuts out.

IEC, Allen-Bradley, Siemens, Schneider, and Instruction List all expose TOF as a named function-block instance. Mitsubishi, Delta, and Omron synthesise TOF from three rungs: a self-sealing latch, an output mirror, and a conditionally-gated on-delay timer.

IEC 61131-3

VAR
  OCCUPANCY AT %I0.0 : BOOL;
  DOOR_OPEN AT %Q0.0 : BOOL;
  T_DOOR    : TOF;
END_VAR

T_DOOR(IN := OCCUPANCY, PT := T#5s);

| T_DOOR.Q | := DOOR_OPEN ;

Declare T_DOOR as TOF, call with IN := and PT := T#5s. The .Q output is TRUE as long as OCCUPANCY has been TRUE recently — it drops 5 seconds after the last FALSE-to-TRUE-back-to-FALSE transition.

Allen-Bradley (Studio 5000 / RSLogix)

TAG OCCUPANCY I:0/0 BOOL
TAG DOOR_OPEN O:0/0 BOOL
TAG T_DOOR    TOF

TOF T_DOOR IN:OCCUPANCY PT:5000

XIC T_DOOR.Q OTE DOOR_OPEN

PT:5000 is 5 000 milliseconds = 5 seconds.

Siemens (TIA Portal SCL)

VAR
  OCCUPANCY AT %I0.0 : BOOL;
  DOOR_OPEN AT %Q0.0 : BOOL;
  T_DOOR    : TOF;
END_VAR

T_DOOR(IN := OCCUPANCY, PT := T#5s);

DOOR_OPEN := T_DOOR.Q;

Mitsubishi (GX Works — synthesised from three rungs)

GX-IL has no TOF instruction. The synthesis uses a self-sealing M-device latch, a native on-delay timer T0 (100 ms base, K50 = 5 seconds), and three rungs.

VAR
  OCCUPANCY AT %I0.0 : BOOL;
  DOOR_OPEN AT %Q0.0 : BOOL;
  LATCH     AT %M0.0 : BOOL;
END_VAR

; Rung 1: latch = (LATCH AND NOT T0.Q) OR OCCUPANCY
LD   M0
ANI  T0
OR   X0
OUT  M0

; Rung 2: DOOR_OPEN mirrors the latch
LD   M0
OUT  Y0

; Rung 3: T0 runs only when LATCH is on AND OCCUPANCY has gone away
LD   M0
ANI  X0
OUT  T0 K50

How the three rungs interact: while OCCUPANCY (X0) is TRUE, the OR X0 in rung 1 forces LATCH on regardless of T0. When OCCUPANCY drops, the latch self-seals via LD M0 until T0's done bit rises and the ANI T0 breaks it. Rung 3 starts T0 counting only when LATCH is on AND OCCUPANCY is off — the ANI X0 gate is critical. Without it, T0 would start counting the moment OCCUPANCY went TRUE, T0's done bit would rise mid-presence, and ANI T0 in rung 1 would break the latch seal while the person is still in the doorway.

Schneider (Unity Pro / EcoStruxure — SCL)

VAR
  OCCUPANCY AT %I0.0 : BOOL;
  DOOR_OPEN AT %Q0.0 : BOOL;
  T_DOOR    : TOF;
END_VAR

T_DOOR(IN := OCCUPANCY, PT := T#5s);

DOOR_OPEN := T_DOOR.Q;

Delta (WPLSoft — synthesised from three rungs)

Delta WPLSoft has no TOF instruction. Structure identical to Mitsubishi; the only difference is TMR T0 K50 instead of OUT T0 K50 on rung 3.

VAR
  OCCUPANCY AT %I0.0 : BOOL;
  DOOR_OPEN AT %Q0.0 : BOOL;
  LATCH     AT %M0.0 : BOOL;
END_VAR

; Rung 1: latch = (LATCH AND NOT T0.Q) OR OCCUPANCY
LD   M0
ANI  T0
OR   X0
OUT  M0

; Rung 2: DOOR_OPEN mirrors the latch
LD   M0
OUT  Y0

; Rung 3: TMR runs only during the off-delay window
LD   M0
ANI  X0
TMR  T0 K50

TMR is Delta's timer instruction; K50 is 50 × 100 ms = 5 seconds. Otherwise the pattern is mnemonic-for-mnemonic the same as Mitsubishi.

Omron (CX-Programmer — synthesised from three rungs)

Omron CX-Programmer has no TOF instruction. Same three-rung structure; differences are symbolic variable names, AND NOT (two words), and TIM 0 #50 for the timer call (# prefix, still 100 ms base).

VAR
  OCCUPANCY AT %I0.0 : BOOL;
  DOOR_OPEN AT %Q0.0 : BOOL;
  LATCH     AT %M0.0 : BOOL;
END_VAR

; Rung 1: latch = (LATCH AND NOT TIM0.Q) OR OCCUPANCY
LD       LATCH
AND NOT  TIM0
OR       OCCUPANCY
OUT      LATCH

; Rung 2: DOOR_OPEN mirrors the latch
LD   LATCH
OUT  DOOR_OPEN

; Rung 3: TIM 0 runs only when LATCH is on AND OCCUPANCY has gone away
LD       LATCH
AND NOT  OCCUPANCY
TIM      0 #50

Note: TIM0 (no space) on rung 1 is the contact reference for the done bit; the timer call on rung 3 is the two-token form TIM 0 #50.

Instruction List (IEC IL)

VAR
  OCCUPANCY AT %I0.0 : BOOL;
  DOOR_OPEN AT %Q0.0 : BOOL;
  T_DOOR    : TOF;
END_VAR

CAL T_DOOR(IN := OCCUPANCY, PT := T#5s)

LD   T_DOOR.Q
ST   DOOR_OPEN

TOF Quick Reference

| Dialect | Mechanism | Preset | Output | |---|---|---|---| | IEC 61131-3 | Native FB | PT := T#5s | T_DOOR.Q | | Allen-Bradley | Native FB | PT:5000 (ms) | T_DOOR.Q (via XIC) | | Siemens SCL | Native FB | PT := T#5s | T_DOOR.Q | | Mitsubishi | 3-rung synthesis (latch + mirror + gated TON) | OUT T0 K50 (K × 100 ms) | M0 latch → Y0 | | Schneider | Native FB | PT := T#5s | T_DOOR.Q | | Delta | 3-rung synthesis (latch + mirror + gated TMR) | TMR T0 K50 (K × 100 ms) | M0 latch → Y0 | | Omron | 3-rung synthesis (latch + mirror + gated TIM) | TIM 0 #50 (# × 100 ms) | LATCHDOOR_OPEN | | Instruction List | Native FB | PT := T#5s | T_DOOR.Q (via LD/ST) |

Native function block in four dialects, three-rung latch synthesis in the other three:

Comparison table of the TOF off-delay timer as a native function block versus a three-rung latch synthesis across PLC dialects

Practice TOF across all dialects: IEC lesson 9, Allen-Bradley lesson 9, Siemens lesson 9, Mitsubishi lesson 9, Delta lesson 9, Omron lesson 9.


The Synthesis Pattern — Why It Matters

The three dialects that synthesise R_TRIG and TOF — Mitsubishi, Delta, and Omron — collectively cover a large share of the Asia-Pacific market. If you work in Japanese, South-East Asian, or Australian manufacturing, you will encounter these platforms. Understanding the synthesis patterns does two things.

First, it gives you a transferable mental model. An R_TRIG function block is just a pair of rungs with a history bit. A TOF function block is a self-sealing latch, an output mirror, and a conditionally-gated on-delay timer. When you understand the decomposition, you can reconstruct it in any dialect — or debug it when someone else's implementation has a subtle scan-order error.

Second, it gives you insight into why scan order is not a stylistic preference. In the Mitsubishi and Delta R_TRIG synthesis, swapping the two rungs means the history bit is updated before the comparison, and the pulse never fires. In the TOF synthesis, removing the ANI X0 gate from rung 3 means the timer starts counting during occupancy, not after it — and the output drops mid-presence. These are not edge cases. They are the core of what makes PLC programming different from writing a function in Python.

Beyond Timers — Counters and Latches

The same naming divergence applies to the other two instruction families you reach for constantly. Counters (CTU up, CTD down) are largely consistent across IEC-style dialects but become numbered devices in Mitsubishi:

Comparison table of CTU up-counter and CTD down-counter instructions across IEC, Allen-Bradley, Siemens and Mitsubishi

Set, reset and latch operations are the other family worth keeping on hand — note that Allen-Bradley uses OTL/OTU rather than the IEC S/R coils:

Comparison table of set, reset and latch instructions across IEC, Allen-Bradley, Siemens and Mitsubishi PLC dialects

Using This Cheat Sheet

A few habits keep you from the classic cross-dialect mistakes when reading these tables:

Checklist of tips for reading the PLC dialect cheat sheet — time base, done bit, synthesised instructions and address styles

Where to Learn

The Coding Tutor covers all three primitives — TON in lesson 8, R_TRIG in lesson 7, TOF in lesson 9 — across all eight dialects. Each lesson gives you a scenario, a starter, and a live I/O model that grades your solution.

Open the Coding Tutor →

The dialect comparison matrix shows how all eight dialects render the same program side by side — a useful companion to the per-lesson practice.

Share:X / TwitterLinkedIn

Practice this yourself in the simulator

3 scenarios free — no install, no credit card. Write real ladder logic against a live machine model.

Try the simulator free →

Related articles

plc programming
encoder

PLC Encoder Programming Examples: Delta, Siemens, Allen-Bradley, Mitsubishi

Practical PLC encoder programming examples for Delta, Siemens S7-1200, Allen-Bradley CompactLogix, and Mitsubishi FX. Covers high-speed counter setup, quadrature mode, homing, and position-based output control in each dialect.

June 12, 2026 · 12 min read
hmi
allen bradley

FactoryTalk View Tutorial: What It Is, What It Costs, and How to Learn HMI Free

Learn what FactoryTalk View ME, SE and Studio are, why the download hunt is frustrating, which concepts transfer to any HMI, and how to build those skills free in your browser.

June 11, 2026 · 11 min read
hmi
siemens

WinCC Tutorial: The Confusing Siemens HMI Family Explained Clearly

WinCC Classic, WinCC Unified, WinCC OA, and WinCC TIA-integrated — which one should you care about? This honest guide untangles the Siemens HMI family and shows how to learn the transferable skills free.

June 11, 2026 · 10 min read