Eight FBD programming examples explained block by block: seal-in, timers, flasher, counter, comparator, hysteresis alarm, edge detection and scaling.

The fastest way to learn Function Block Diagram programming is to read real circuits — not symbol tables. Below are eight FBD programming examples, ordered from the two-block seal-in to a scaled analog alarm with hysteresis, each explained block by block with its Structured Text equivalent so you can verify your reading. Together they cover the block set that appears in the overwhelming majority of working FBD programs: AND/OR/NOT, TON/TOF, CTU, R_TRIG, SR, the comparators, and MOVE/math with EN. If the notation itself is new, skim the Function Block Diagram Complete Tutorial first — this post assumes you know what pins and networks are.

(Each example below is a spot for a simulator screenshot of the network; every one can be built and animated in the PLC-Ladder simulator as you read.)

Example 1 — Start/Stop Seal-In (OR + AND)

Blocks: one OR, one AND. Start and Motor feed the OR; its output and StopOK feed the AND; the AND output is written to Motor. The feedback wire from Motor back into the OR is what makes it remember — broken by the variable, so the OR sees last scan's value.

Motor := (Start OR Motor) AND StopOK;

Press Start, Motor latches; drop StopOK, it releases. This is the FBD twin of ladder's most famous rung.

Example 2 — On-Delay Start (TON)

Blocks: the seal-in from Example 1, plus a TON instance SealAir. Motor wires to IN, PT is the constant T#5s, and Q drives Pump. The pump therefore starts five seconds after the motor and stops with it instantly.

Motor := (Start OR Motor) AND StopOK;
SealAir(IN := Motor, PT := T#5s);
Pump := SealAir.Q;

Example 3 — Run-On Fan (TOF)

Blocks: one TOF instance RunOn. DriveRunning → IN, T#30s → PT, Q → Fan. The fan follows the drive up immediately and hangs on 30 s after it stops. One block, one wire in, one wire out — TOF circuits are usually this small. (The full TON/TOF/TP story, with timing diagrams, is in PLC Timers Explained.)

RunOn(IN := DriveRunning, PT := T#30s);
Fan := RunOn.Q;

Example 4 — Flasher (Two TONs in a Ring)

Blocks: T1 : TON and T2 : TON, cross-coupled. T2.Q is negated (the small circle on the pin) into T1.IN; T1.Q feeds T2.IN; T1.Q also drives the Beacon. T1 times 500 ms, then T2 times 500 ms, then T2.Q resets T1 and the ring restarts — a 1 Hz flash with the on-time set by T2.PT and off-time by T1.PT.

T1(IN := NOT T2.Q, PT := T#500ms);
T2(IN := T1.Q,     PT := T#500ms);
Beacon := T1.Q;

This is the first example where FBD visibly beats ladder for readability: the ring topology is obvious as wires.

Example 5 — Parts Counter with Edge Detection (R_TRIG + CTU)

Blocks: Edge : R_TRIG and Batch : CTU. The photo-eye PartSensor feeds Edge.CLK; Edge.Q — TRUE for exactly one scan per rising edge — feeds Batch.CU. PV is 24; Batch.Q goes TRUE at a full box and ResetBtn wires to Batch.RESET.

Edge(CLK := PartSensor);
Batch(CU := Edge.Q, RESET := ResetBtn, PV := 24);
BoxFull := Batch.Q;

Why the R_TRIG is not optional: a part blocking the eye for half a second at a 10 ms scan is ~50 TRUE scans — without edge detection the counter jumps 50 per part. Many CTU implementations edge-detect CU internally, but never rely on it; the explicit block documents the intent. (The full story of this trap is in PLC Counters Explained.)

Example 6 — Set/Reset Latch with Priority (SR)

Blocks: one SR instance Fault. OverTemp → SET1, AckButton → RESET, Q1 → FaultLamp. SR is set-dominant: if the over-temperature is still present, holding Ack does nothing — the fault refuses to clear while its cause persists, which is exactly what you want from an alarm latch. (Its sibling RS is reset-dominant; pick deliberately.)

Fault(SET1 := OverTemp, RESET := AckButton);
FaultLamp := Fault.Q1;

Example 7 — Analog Alarm with Hysteresis (GT + LT + SR)

Blocks: GT comparing TankTemp > 90.0 into SET1 of an SR; LT comparing TankTemp < 85.0 into RESET. The alarm sets above 90° and clears only below 85° — the 5° gap (hysteresis) stops the alarm chattering when the temperature hovers at the threshold. A GT alone, wired straight to the lamp, is the naive version that flickers.

HiTemp(SET1 := TankTemp > 90.0, RESET := TankTemp < 85.0);
TempAlarm := HiTemp.Q1;

Example 8 — Scaling a Raw Analog Input (Math Chain with EN)

Blocks: a left-to-right chain: SUB (raw − 4000), MUL (× span), DIV (÷ 16000), ADD (+ offset) — converting a 4–20 mA input (4000–20000 counts) to 0–150 °C. In EN/ENO vendors, chain ENO → EN down the line so a fault (like a broken-wire raw value) stops the chain rather than propagating garbage; wire the final ENO to a SignalOK flag.

TempC := (INT_TO_REAL(Raw) - 4000.0) * 150.0 / 16000.0;

Compare the one-line ST to the four-block chain: this is the honest trade-off. FBD shows the flow and the fault path; ST is compact. Real programs use both.

Build Them, Break Them

Each circuit above took more words to explain than it takes minutes to build. Recreate them in order in the simulator — the seal-in and flasher especially reward watching live — and then break each one on purpose: remove the R_TRIG from Example 5 and watch the count explode, or delete the hysteresis from Example 7 and watch the chatter. Every pin of every block used here (and the ones we skipped, like F_TRIG, CTD and TP) is catalogued in Function Block Diagram Symbols: Every Standard Block and What Its Pins Mean — the natural next read.Visit PLC-Ladder Website