Scan Order and One-Scan Delays
Every so often a program looks completely correct, yet a light comes on one moment "too early", or a step in a sequence seems to get skipped. Almost always the cause is the same: the order in which your rungs or statements run. Get the order wrong and an output can come out one scan late.
This builds on The Scan Cycle — the PLC evaluates your whole program, top to bottom, once per scan.
Order makes a read fresh or stale
As the PLC works down your program, it updates each bit it writes. So a bit is fresh to everything below where it is written, but anything above has already run this scan and saw the value from before. That is invisible — until one rung or statement reads a bit that a later one writes.
When order delays an output
Say Light should simply follow Button, passing through an in-between memory bit called Flag. Here it is wired so the line that reads Flag runs above the line that writes it.
In Ladder Logic — Light's rung is above Flag's rung:
XIC(Flag)OTE(Light);XIC(Button)OTE(Flag)
The same thing in Structured Text — Light := runs above Flag :=:
Light := Flag;
Flag := Button;
Logically Light = Flag = Button, so you would expect the light to come on the instant the button is pressed. It doesn't — it comes on one scan later. Here is why, scan by scan, with the button pressed at scan 2:
| Scan | Button | Flag | Light | What happened |
|---|---|---|---|---|
| 1 | 0 | 0 | 0 | Idle. |
| 2 | 1 (pressed) | 1 | 0 | Flag is set to 1 — but the Light line already ran earlier this scan and read Flag as 0. |
| 3 | 1 | 1 | 1 | The Light line now reads Flag as 1, so Light turns on. |
The key line is scan 2: Light is computed before Flag is updated, so it reads Flag at last scan's value (0) and has to wait a scan to catch up. You will hear this loosely called a scan-order race condition, though here it is perfectly predictable — it comes straight from the top-to-bottom order.
Order decides whether the delay exists
Now flip the order so Flag is written above where it is read.
In Ladder Logic:
XIC(Button)OTE(Flag);XIC(Flag)OTE(Light)
In Structured Text:
Flag := Button;
Light := Flag;
Now Flag is set first, and Light reads the fresh value in the same scan. Light follows the button with no delay:
| Scan | Button | Flag | Light | What happened |
|---|---|---|---|---|
| 1 | 0 | 0 | 0 | Idle. |
| 2 | 1 (pressed) | 1 | 1 | Flag is set to 1; the Light line reads the fresh Flag later the same scan and turns Light on. |
Compare scan 2 with the first example: there Light was still 0, here it is already on. Same logic — one line swapped.
The rule of thumb, whichever language you use:
- A value written above where it is read updates in the same scan.
- A value written below where it is read is one scan behind — read above, written below.
Neither is "wrong" — sometimes a one-scan delay is exactly what you want. The point is to order your rungs or statements so they produce the timing you intend. (This is the companion to "later wins" from The Scan Cycle: there, two places write the same output; here, one place reads what another writes.)
Try it yourself
Build it in the One-Scan Delay exercise: drive one output that follows a button immediately and a second that follows it one scan later — the exact pattern from this page, in Ladder or Structured Text.
To watch the delay happen, use Step instead of Start (you can't catch a single scan at full speed — the simulator runs ten scans a second):
- Click Step in the top toolbar to run exactly one scan and pause.
- Toggle an input (like
Button) in the I/O Panel. - Click Step again and watch the bits update one scan at a time.
In the first example above, you will see Flag turn on the scan you press the button, but Light stay off until the next Step — the one-scan delay, right in front of you.
Step shows you the values at the end of each scan; it runs a whole scan per click, not one rung at a time. So it tells you when a bit changes — count the scans — while the order tells you why.
Summary
- Every scan, your program runs top to bottom. A line reads each value at whatever it holds at the moment that line runs.
- A value written below where it is read is one scan behind; written above, it is fresh in the same scan.
- That is why an output can land one scan late — a one-scan delay caused purely by order, no timer involved.
- The same rule applies to Ladder Logic (rung order) and Structured Text (statement order).
- Use Step to watch the change happen one scan at a time.