Off-delay: keep going after the signal drops
An air heater in a drying tunnel has a 12 kW element bank and a fan blowing across it. When the heater switches off, the elements are still glowing. Stop the fan at the same moment and the heat soaks into the housing, the over-temperature thermostat trips, and in a bad case the insulation on the element terminals cooks. The rule in the manual is simple: the fan keeps running for two minutes after the heater stops. That is an off-delay, and the timer for it is TOF.
TOF has the same four pins as the TON from chapter 9 — IN, PT, Q, ET — but it times the other edge:
- While
INis TRUE,Qis TRUE andETisT#0s. There is no delay on the way in. - When
INgoes FALSE,ETstarts counting.Qstays TRUE untilETreachesPT, then goes FALSE. - If
INcomes back TRUE beforePTruns out,ETreturns to zero andQsimply stays TRUE. The run-on starts again from the next falling edge.
Here is the heater fan, with 5 s instead of two minutes so you don't have to wait:
PROGRAM Main
VAR
Heater : BOOL; (* the heater contactor command, from elsewhere in the program *)
FanRunOn : TOF;
Fan : BOOL; (* output: fan contactor *)
END_VAR
FanRunOn(IN := Heater, PT := T#5s);
Fan := FanRunOn.Q;
END_PROGRAMSwitch Heater on: the fan starts on the same scan. Switch it off: the fan carries on, ET climbs, and 5 s later the fan stops. Switch the heater back on half-way through the run-on and watch ET drop to zero while the fan never hesitates.
If you have built this in ladder with a TON and an inverted contact, notice the identity: a TOF's Q is exactly NOT of a TON's Q when the TON is fed NOT IN. "The fan may stop once the heater has been off for 5 s" is an on-delay on heater off. Both are correct; the TOF says what you mean in one line, which is the better reason to use it.
What a TOF will not do for you
An off-delay lives in the CPU's memory, and that has three consequences people learn the hard way.
It does not survive a power cut. On start-up every TOF begins with Q FALSE. If the supply drops while the heater is on, the fan stops with it and does not run on when power returns — the program has no idea the elements were hot. Where the run-on protects equipment, back it up with something physical: a thermostat on the housing that runs the fan above 60 °C, wired so it works whatever the PLC thinks.
It must not delay a stop that should be immediate. The fan's motor-protection breaker and the emergency stop must kill it now, not five seconds from now. Gate the output, not the timer input: Fan := FanRunOn.Q AND NOT FanOverload;. The run-on keeps timing in the background, but the contactor drops.
It holds the output on through every short dip. That is usually the point, and occasionally a trap. A TOF on a "carton present" signal holds the belt running while cartons arrive closer together than PT; it also hides a photo-eye that chatters. Know which one you are building.
Pulse timer: exactly this long
The third timer answers a different question again: when this happens, do something for exactly this long. A grease button on a press gives one 1 s shot of lubricant per press, however long the fitter leans on it. A reject station fires a 150 ms air blast to knock a bad bottle off the conveyor. A horn gives a 3 s burst when a batch completes. That is the pulse timer, TP.
- On a rising edge of
IN,Qgoes TRUE andETstarts counting. Qstays TRUE untilETreachesPT— whateverINdoes in the meantime. Releasing the button does not cut the pulse short; holding it does not stretch it.- After the pulse,
ETstays atPTwhileINis still TRUE, and returns to zero onceINis FALSE. Only then can a new rising edge start a new pulse.
PROGRAM Main
VAR
GreaseBtn : BOOL; (* input: push button *)
Shot : TP;
GreasePump : BOOL; (* output: lubrication pump *)
END_VAR
Shot(IN := GreaseBtn, PT := T#1s);
GreasePump := Shot.Q;
END_PROGRAMTap GreaseBtn and release it at once: the pump still runs for a full second. Press and hold it: the pump stops after a second while the button is still held, and nothing more happens until you let go and press again.
The IEC 61131-3 standard is explicit about one more case: a rising edge that arrives while a pulse is running is ignored. The pulse finishes at its original time; it is not restarted or extended. That is what makes TP safe for metering — a fitter jabbing the button five times in a second still gets one shot. This page's engine deviates here and restarts the pulse on a re-press, so do not use the live example to test it; on CODESYS, TwinCAT or an S7-1500 the re-trigger is ignored.
A pulse is only as precise as the scan. A 150 ms TP on a 10 ms task gives 150 to 160 ms; on a 100 ms task it gives 200 ms. For a reject blast on a line doing 30,000 bottles an hour, where the gap between bottles is 120 ms, that difference decides whether you knock off one bottle or two. Short pulses belong in a fast task or on an output card with pulse-train or cam functions.
A flasher from two timers
Every alarm beacon, every "machine running" lamp on a stack light and every HMI warning icon flashes. Some controllers give you a ready-made clock — a Siemens CPU has a configurable clock memory byte whose bit 5 toggles at 1 Hz, and the CODESYS Util library has a BLINK block — but you should be able to build one, because Studio 5000 has neither and because you will want flash rates of your own.
The classic flasher is two TONs that hand over to each other:
PROGRAM Main
VAR
Enable : BOOL; (* input: flashing wanted *)
OffTime : TON; (* times the dark half *)
OnTime : TON; (* times the lit half *)
Beacon : BOOL; (* output: beacon lamp *)
END_VAR
OffTime(IN := Enable AND NOT OnTime.Q, PT := T#500ms);
OnTime(IN := OffTime.Q, PT := T#500ms);
Beacon := OffTime.Q;
END_PROGRAMFollow one cycle. With Enable on, OffTime runs while the lamp is dark. When it finishes, OffTime.Q lights the beacon and starts OnTime. When OnTime finishes, its Q takes OffTime's input away, OffTime resets, the lamp goes dark — and on the next scan OnTime loses its input too, resets, and gives OffTime its input back. Round it goes. Each timer's Q is fed back into the other's IN, and that feedback is the whole trick.
Step through it and count: each half lasts its preset plus about one scan, because each reset costs a scan. On this page's 100 ms scan that is visible; on a 10 ms task a "500 ms" half is 510 ms and nobody will ever notice. Different presets give different duty cycles — 200 ms on and 800 ms off reads as "warning", 500/500 as "fault", and many plants define exactly that in their HMI standard.
The self-resetting single timer
You can get a regular tick out of a single TON by feeding its own output back into its input:
PROGRAM Main
VAR
Pulse : TON;
Tick : BOOL; (* TRUE for exactly one scan per period *)
Beacon : BOOL;
Ticks : DINT;
END_VAR
Pulse(IN := NOT Pulse.Q, PT := T#500ms);
Tick := Pulse.Q;
IF Tick THEN
Beacon := NOT Beacon; (* toggle on every tick: 50 % duty flasher *)
Ticks := Ticks + 1;
END_IF;
END_PROGRAMWhen the timer finishes, Q is TRUE for one scan. On the next call IN is NOT TRUE, so the timer resets; on the call after that IN is TRUE again and it starts over. The result is a one-scan Tick — exactly what you want to step a counter, sample an analog value or toggle a lamp.
Notice the cost: two scans per period, one to reset and one to restart. The period is PT plus two scans, not PT. For a flasher that does not matter. For anything that counts time it does. Use this tick to build a seconds counter on a 10 ms task and every "second" lasts 1.02 s; after an hour the counter reads 3,529 instead of 3,600, more than a minute slow. On a 100 ms task it is ten minutes an hour. Running-hours meters, totalisers and shift timers should accumulate real elapsed time or read the controller's clock (chapter 16), never count self-reset ticks.
Choosing between TON, TOF and TP
All three timers take the same pins. The difference is which question they answer, and almost every timing requirement in a specification is one of these sentences:
| The spec says | Timer | Example |
|---|---|---|
| "…only if it has lasted X" | TON | Low level for 3 s trips the pump |
| "…after X, start…" | TON | Conveyor starts 2 s after the horn |
| "…keep … for X after it stops" | TOF | Fan runs 2 min after the heater |
| "…for exactly X when…" | TP | 1 s grease shot per press |
| "…for X after the last…" | TOF on the event | Belt sleeps 4 s after the last carton |
| "…every X…" | TON with feedback | 1 Hz beacon |
The same input trace through all three, with PT = 300 ms (three scans):
| Scan | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| IN | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| TON.Q | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |
| TOF.Q | 0 | 1 | 1 | 1 | 1 | 1 | 0 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 1 | 0 |
| TP.Q | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
Read it row by row. The TON ignores the two-scan blip completely and only switches after the input has been on for three scans. The TOF follows every rise at once and adds three scans to every fall. The TP turns each rising edge into exactly three scans and ignores how long IN stays on.
One row of the decision table deserves a closer look. A TOF fed by a short event becomes a retriggerable one-shot: every new event restarts the run-on, so Q stays on until the events stop. Roller conveyors with 24 V motor-driven rollers use exactly this to sleep a zone when no cartons arrive:
PROGRAM Main
VAR
CartonEye : BOOL; (* input: photo-eye at the zone entry *)
Sleep : TOF;
Belt : BOOL; (* output: zone motor *)
END_VAR
Sleep(IN := CartonEye, PT := T#4s); (* every carton restarts the run-on *)
Belt := Sleep.Q;
END_PROGRAMToggle CartonEye every couple of seconds and the belt never stops; leave it alone and the belt sleeps 4 s after the last carton cleared the eye. A TP cannot do this — it would ignore the cartons that arrive during its pulse. When a requirement says "after the last one", reach for a TOF; when it says "exactly once per trigger", reach for a TP.
Next: counting things
Timers measure how long. The next question on every machine is how many: how many cartons in this layer, how many strokes since the last die change, how many bottles left in the batch. Chapter 11 covers the IEC counters CTU, CTD and CTUD, and the one rule that matters more than any of their pins: count edges, not scans.