PLC One-Shot (Rising Edge): ONS, OSR, and Edge Detection
The PLC one-shot explained — rising and falling edge detection, the ONS/OSR/OSF instructions, why you need a one-shot, and ladder examples you can reuse.
A PLC one-shot is one of those instructions that every programmer learns the hard way — usually after discovering their counter incremented 60 times per second instead of once per button press. Once you understand what a one-shot does and why the scan cycle makes it necessary, you will reach for it constantly.
This tutorial covers the concept from first principles, walks through Allen-Bradley ONS/OSR/OSF, Siemens P_TRIG/N_TRIG, and IEC R_TRIG/F_TRIG, and gives you copy-ready ladder examples for the most common use cases.
What Is a One-Shot in PLC Programming?
A one-shot (also called an edge-detect instruction) produces exactly one true scan when its input transitions from false to true (rising edge) or from true to false (falling edge).
That single-scan output then returns to false regardless of whether the input signal remains high. No matter how long the physical input stays energized — milliseconds or hours — the one-shot output is true for one program scan only.
This behavior is rooted directly in how a PLC executes code. During every scan cycle the processor reads all inputs, executes the program from top to bottom, and writes all outputs before repeating. If a contact in your ladder logic is true for 500 ms and your scan time is 10 ms, that rung executes 50 consecutive times. For most logic that is fine, but for instructions that should fire once per event (counters, toggles, sequence triggers) you need to limit execution to a single scan.
A one-shot is the standard solution.
Rising Edge vs Falling Edge
| Term | Also called | Trigger condition |
|---|---|---|
| Rising edge | Leading edge, positive transition | Input goes from 0 → 1 |
| Falling edge | Trailing edge, negative transition | Input goes from 1 → 0 |
Rising edge detection captures the moment a signal turns on. This is the most common case — a button press, a sensor activating, a flag going true.
Falling edge detection captures the moment a signal turns off. Use this when you want to react to the end of an event: a conveyor stopping, a clamp releasing, a cycle completing.
Why You Need a One-Shot
Understanding when to use a one-shot requires thinking in terms of scans, not time. Here are the three situations that almost always require one:
1. Counting events exactly once
If a photoelectric sensor detects a part passing on a conveyor, the sensor input may be true for 50 ms. At a 10 ms scan time that is five consecutive scans. Without a one-shot, a CTU counter instruction would increment five times per part — completely wrong.
Placing a one-shot ahead of the CTU rung ensures the counter advances exactly once per part, on the first scan the sensor goes true.
For a deep dive into counter instructions see the guide to counter programming.
2. Toggling a bit
A single pushbutton should toggle a light on/off. Without a one-shot, every scan while the button is held energizes the toggle logic, flipping the output at full scan-cycle speed — the light flickers faster than the eye can track.
A one-shot restricts the toggle to one execution, so the output changes state exactly once per button press.
3. Triggering a sequence step without repeating
Step-based state machines (where a rung activates Step 2 only when Step 1 completes) can double-fire if the transition condition stays true across multiple scans. A one-shot on the transition rung advances the step pointer once and immediately removes the firing condition, preventing re-entry.
The One-Shot Instructions
Allen-Bradley (Rockwell) — ONS, OSR, OSF
Rockwell's ControlLogix, CompactLogix, and MicroLogix platforms provide three dedicated one-shot instructions.
ONS — One Shot
The ONS instruction is used in series with other contacts on a rung. It does not have a dedicated output coil; it simply blocks rung continuity after the first true scan.
|--[XIC ButtonPress]--[ONS StorageBit]--[CTU Counter1]--|
- Input: rung condition (the contacts to its left)
- Storage bit: a dedicated BOOL tag that stores the previous state; never share this bit with any other instruction
- Output: rung continuity passes through on the first true scan only
ONS is the most compact option when you only need to gate an existing rung.
OSR — One Shot Rising
OSR is a coil instruction that drives a dedicated output bit for one scan on a rising edge of the rung condition.
|--[XIC ButtonPress]--|OSR StorageBit OutputBit|
- Storage bit: holds the previous rung state (do not reuse)
- Output bit: goes true for exactly one scan when the rung transitions false → true
Use OSR when you need a standalone bit that other rungs can reference as a contact.
OSF — One Shot Falling
OSF mirrors OSR but fires on a falling edge (rung transitions true → false).
|--[XIC ConveyorRunning]--|OSF StorageBit OutputBit|
Use OSF to detect the moment a signal drops — a machine stopping, a timer completing, a permissive clearing.
Critical rule for all three: Every ONS, OSR, and OSF instruction requires its own unique storage/output bit. Reusing the same storage bit across two one-shot instructions causes them to interfere with each other and produces unpredictable behavior — one of the most common mistakes in PLC programming.
Siemens — P_TRIG and N_TRIG (TIA Portal / Step 7)
Siemens provides edge-detect function blocks for both LAD (ladder) and FBD (function block diagram).
P_TRIG (positive trigger) — detects rising edge:
CLK Q
P_TRIG
|-----[P_TRIG]----- OutputCoil
ButtonPress
In Structured Text (SCL):
#EdgeBlock_P(CLK := #ButtonPress,
Q => #OneShotOutput);
N_TRIG (negative trigger) — detects falling edge:
#EdgeBlock_N(CLK := #ConveyorRunning,
Q => #FallingEdgeOutput);
Each P_TRIG or N_TRIG block instance must be declared as a separate instance data block (IDB) or local static variable. Sharing one block instance between two signals produces the same interference problem as reusing a Rockwell storage bit.
For more on Siemens programming approaches see the PLC programming languages guide.
IEC 61131-3 — R_TRIG and F_TRIG
The IEC 61131-3 standard defines two function blocks that are vendor-neutral and available in platforms such as CODESYS, Beckhoff TwinCAT, and many others.
R_TRIG (rising trigger):
VAR
EdgeDetector : R_TRIG;
ButtonPressed : BOOL;
CounterEnable : BOOL;
END_VAR
EdgeDetector(CLK := ButtonPressed);
CounterEnable := EdgeDetector.Q;
F_TRIG (falling trigger):
VAR
FallDetector : F_TRIG;
SensorActive : BOOL;
PartEjected : BOOL;
END_VAR
FallDetector(CLK := SensorActive);
PartEjected := FallDetector.Q;
The .Q output is true for exactly one program cycle after the transition. Because these are function block instances, each variable declaration creates an independent state — no shared-storage problem if you declare separate instances.
For platform-specific syntax see the structured text programming guide.
Ladder Logic Examples
Example 1 — Button Press Increments a Counter Once
Problem: A pushbutton (I:0/0) should increment counter C5:0 by one per press. The button may be held for several seconds.
Without a one-shot (broken):
|--[XIC I:0/0]--[CTU C5:0 Preset:100]--|
Every scan while the button is held, C5:0.ACC climbs. A 2-second hold at 10 ms scan time = 200 counts.
With ONS (correct):
|--[XIC I:0/0]--[ONS B3:0/0]--[CTU C5:0 Preset:100]--|
B3:0/0 is the dedicated storage bit. C5:0.ACC increments exactly once per button press regardless of hold duration.
Example 2 — Toggle a Output with One Button
Problem: Push button I:0/1 should toggle output O:0/0 on and off.
Rung 1 (edge detect):
|--[XIC I:0/1]--|OSR B3:1/0 B3:1/1|
Rung 2 (toggle):
|--[XIC B3:1/1]--[XIO O:0/0]--[OTE O:0/0]--|
|--[XIC B3:1/1]--[XIC O:0/0]--[OTL O:0/0]--|
|--[XIC B3:1/1]--[XIC O:0/0]--[OTU O:0/0]--|
Simplified toggle using XOR logic in Structured Text:
IF ButtonEdge.Q THEN
LightOn := NOT LightOn;
END_IF;
ButtonEdge is an R_TRIG instance. The toggle fires once per button press because ButtonEdge.Q is true for only one scan.
Example 3 — Detect Machine Stop to Log a Fault
Problem: When conveyor drive DriveRunning goes false (falling edge), latch a fault bit FaultDriveStop for operator acknowledgment.
|--[XIC DriveRunning]--|OSF B3:2/0 B3:2/1|
|--[XIC B3:2/1]--|OTL FaultDriveStop|
The OSF fires once on the falling edge. The OTL (output latch) holds the fault until an operator resets it — a clean, reliable fault-capture pattern.
For more ladder construction fundamentals see the ladder logic tutorial.
Common Mistakes with One-Shot Instructions
Reusing the Same Storage Bit
This is the most frequent error. If two ONS instructions share the same storage bit:
|--[XIC Sensor1]--[ONS B3:0/0]--[CTU Counter1]--| ← uses B3:0/0
|--[XIC Sensor2]--[ONS B3:0/0]--[CTU Counter2]--| ← WRONG — same bit
The second ONS checks the bit modified by the first, producing false triggers or missed transitions. Always assign one unique bit per one-shot instruction.
Placing a One-Shot Inside a Conditional Block That Can Re-Enable
If a one-shot is gated by a condition that itself pulses on and off, the one-shot resets when the gate goes false and re-fires on the next gate rising edge. This is sometimes intentional but is often a subtle logic error. Draw the full truth table before assuming the behavior is correct.
Detecting Both Edges with a Single Instruction
ONS, OSR, R_TRIG, and P_TRIG detect rising edges only. To detect both edges you need an OSR/OSF pair or R_TRIG/F_TRIG pair, each with its own storage:
RisingEdge(CLK := Signal);
FallingEdge(CLK := Signal);
IF RisingEdge.Q OR FallingEdge.Q THEN
AnyTransition := TRUE;
END_IF;
Forgetting That the One-Shot Resets Across Power Cycles
When the PLC powers up, storage bits for ONS/OSR/OSF are cleared. If the physical input happens to be true at startup and the storage bit is false, the one-shot will fire once on the first scan — potentially triggering an unintended action. For startup-sensitive applications, add a first-scan mask using the PLC's built-in first-scan bit (S:1/15 in MicroLogix, FirstScan in ControlLogix).
How the Scan Cycle Makes One-Shots Necessary
A PLC does not react to signals in real time the way a microcontroller interrupt does. It processes everything in a continuous loop:
- Input scan — snapshot all physical input states into the input image table
- Program scan — execute every rung, top to bottom, using the input image
- Output scan — write the output image table to physical outputs
- Repeat
A 10 ms scan cycle means your program runs 100 times per second. A button held for 1 second produces 100 consecutive true conditions on every rung it controls. Without a one-shot, any action attached to that button fires 100 times.
The one-shot solves this by comparing the current rung state to a stored copy of the previous state. If current = true and previous = false, the transition is detected and the output fires for that single scan. The storage bit is then set to true so subsequent scans see current = true and previous = true — no transition, no output.
This is why the storage bit must be unique and persistent across scans. It is the one-shot's memory of what the signal looked like last time the rung ran.
Understanding the scan cycle deeply also helps you troubleshoot timer and counter behavior. See the full explanation in scan cycle explained.
Frequently Asked Questions
What is a one-shot in PLC programming?
A one-shot is a PLC instruction that produces a true output for exactly one program scan when its input transitions from false to true (rising edge) or true to false (falling edge). It prevents an action from repeating every scan while an input signal remains on.
What is the difference between ONS and OSR?
Both are Allen-Bradley rising-edge one-shot instructions. ONS is placed inline on a rung and gates rung continuity — it has no separate output bit. OSR is a coil instruction that drives a dedicated output bit you can reference as a contact in other rungs. Use ONS when you want a compact single-rung solution; use OSR when other rungs need to reference the one-shot output.
What is rising edge detection?
Rising edge detection identifies the exact moment a signal transitions from 0 (false) to 1 (true). In PLC terms, it is the scan where the current rung or signal state is true and the stored previous state is false. Only that single scan is flagged; all subsequent true scans are ignored until the signal first goes false and returns true.
When do you use a one-shot?
Use a one-shot any time an action should occur once per event rather than once per scan. The three most common cases are: incrementing a counter for each physical event (part detected, door opened), toggling an output with a single pushbutton, and advancing a step in a sequence without the transition condition causing re-entry on the next scan.
Can I use the same storage bit for two one-shot instructions?
No. Each ONS, OSR, or OSF instruction requires a unique storage bit. Sharing a storage bit between two instructions causes them to read each other's previous-state memory, producing false triggers and missed transitions that are very difficult to debug.


