# OSR / OSF — One Shot Rising and Falling

Source: https://rungs.dev/docs/ladder-logic/instructions/osr-osf

> OSR sets an output bit for one scan when its rung turns on; OSF sets it for one scan when the rung turns off. Both use a dedicated storage BOOL in the rungs.dev ladder simulator.

**One Shot Rising (`OSR`).** Sets its output bit for exactly one scan each time the rung goes from false to true. Uses a dedicated storage bit to remember the previous rung state.

**One Shot Falling (`OSF`).** Sets its output bit for exactly one scan each time the rung goes from true to false. Uses a dedicated storage bit to remember the previous rung state.

Unlike [`ONS`](https://rungs.dev/docs/ladder-logic/instructions/one-shot-ons) — which conditions the rung it sits in — `OSR` and `OSF` write a separate bit you can read anywhere else in your program.

## Operands [#operands]

| Name         | Type   | Meaning                                         |
| ------------ | ------ | ----------------------------------------------- |
| `storageBit` | `BOOL` | Remembers the rung state from the previous scan |
| `outputBit`  | `BOOL` | Pulses true for one scan on the edge            |

Each instruction needs its **own** storage bit. The output bit is the one you use downstream.

## How They Work [#how-they-work]

Both compare the rung condition now against the `storageBit` (what the rung was last scan):

- **`OSR`** — rung goes false → true: set `outputBit` for one scan. While the rung stays true, hold it false.
- **`OSF`** — rung goes true → false: set `outputBit` for one scan. While the rung stays true or stays false, hold it false.

A falling edge is not the same as "the input is off." `OSF` pulses on the single scan the rung _turns off_, then clears even though the rung stays off — that is what makes it a one-shot and not an inverted contact.

Neither fires on the first scan for a condition that was already settled at startup. [Prescan](https://rungs.dev/docs/scan-cycle/the-scan-cycle#before-the-first-scan) seeds the storage bit — `OSR` treats a rung that is already true as old news, and `OSF` has no stored "true" for a falling edge to measure against.

```
Rung   _____|‾‾‾‾‾‾‾‾|________|‾‾‾‾‾‾|___
OSR    _____|‾|_______________|‾|________
OSF    _____________|‾|______________|‾|_
```

## Example — Pulse on a Rising Edge [#example--pulse-on-a-rising-edge]

`OSR` turns a held button into a single-scan pulse on `PressPulse`, which drives an [`ADD`](https://rungs.dev/docs/ladder-logic/instructions/math) once per press:

```ladder
XIC(Button)OSR(PressStorage,PressPulse);XIC(PressPulse)ADD(Count,1,Count)
```

## Example — Act When a Signal Drops [#example--act-when-a-signal-drops]

`OSF` pulses `DropPulse` the moment `Guard` opens, latching an alarm:

```ladder
XIC(Guard)OSF(GuardStorage,DropPulse);XIC(DropPulse)OTL(Alarm)
```

## One-Shots vs `ONS` [#one-shots-vs-ons]

- [`ONS`](https://rungs.dev/docs/ladder-logic/instructions/one-shot-ons) is an **input** instruction: it makes the rest of _its own_ rung true for one scan. Best when the thing you want to pulse is right there on the same rung.
- `OSR` / `OSF` are **output** instructions: they set a named bit you can examine on other rungs. Best when the same edge needs to be reused in several places — or when you need the _falling_ edge, which `ONS` cannot detect.

## Common Mistakes [#common-mistakes]

- Confusing a falling edge with an inverted input — `XIO(Signal)` is true the _whole time_ the signal is off; `OSF` pulses for a _single scan_ when it turns off.
- Sharing one `storageBit` between two one-shot instructions — each needs its own.
- Reading the `storageBit` instead of the `outputBit` — the pulse is on the output bit.

## Related [#related]

- [`ONS` — One Shot](https://rungs.dev/docs/ladder-logic/instructions/one-shot-ons) — rising-edge one-shot that conditions its own rung
- [Bit instructions overview](https://rungs.dev/docs/ladder-logic/instructions/bit-instructions)