12
Sequencer and Shift Register Instructions
Chapter 11 taught the PLC to compute; this chapter teaches it to orchestrate. Sequencers descend from the brass cam-and-drum machines that once ran washing machines, jukeboxes, and traffic lights — the same idea, now stored in memory and stepped by a timer. Shift registers track parts moving down a conveyor by shifting a bit each time the line advances. FIFO and LIFO queues handle work orders, print jobs, and recipe steps in the order they arrived. By the end you’ll have the orchestration tools behind every batch sequencer and the tracking tools behind every moving line in the plant.
What you’ll be able to do after this chapter
Your goals for this chapter:
- Trace the lineage from mechanical drum sequencers to modern software sequencer instructions.
- Configure an SQO (sequencer output) instruction with a position pointer, length, file, and mask.
- Use SQC (sequencer compare) to verify that the field state matches the expected pattern at each step, and raise an alarm if it doesn’t.
- Combine SQO and SQC into a real industrial pattern where one drives outputs and the other verifies sensors.
- Use BSL and BSR bit shift registers to track defects, parts, or events as they move through positions.
- Use FFL/FFU for first-in-first-out word queues — print jobs, work orders, recipe steps.
- Use LFL/LFU for last-in-first-out stacks — undo buffers, function call returns, recursive logic.
- Recognise when sequencers, shift registers, or queues are the right tool — and when each is the wrong tool.
Key Concepts & Terms
Mechanical Sequencers
Long before microprocessors, factories needed machines that would perform a series of actions in a fixed order — fill, agitate, drain, rinse, spin. The solution was a mechanical drum sequencer: a slowly rotating cylinder studded with raised bumps (cams), with a row of switches whose levers (rollers) rode against the drum’s surface. As the drum turned, each cam pushed against its switch, closing a circuit and energising whatever output that switch controlled — a valve, a motor, a heater. After one full revolution the cycle was complete.
Figure 12.1 — Mechanical drum sequencerA rotating drum carries cams (raised bumps) at specific angular positions. As the drum turns, each cam in turn pushes its switch closed, energising the output assigned to that switch. Each angular position corresponds to one “step” of the sequence — exactly the same model used by software SQO instructions today.
Why this history matters
The mechanical drum did three things, all of which an SQO instruction does today:
- Stored a sequence pattern. The arrangement of cams on the drum encoded the recipe — which outputs to energise at which step. In software, the same pattern is stored as rows in a sequencer file (one row per step, with bits for each output).
- Stepped through the pattern. The motor turned the drum at a fixed rate; each angular position became a step. In software, a timer or event-driven trigger advances the position pointer.
- Drove physical outputs. The cam-and-roller pairs closed contacts that energised solenoids and motors. In software, the SQO instruction copies the bit pattern of the current step’s row to the output addresses.
The drum’s biggest limitation was inflexibility — to change the recipe you had to physically rebuild the drum by repositioning cams. PLCs eliminated that constraint: a new recipe is just new data in the sequencer file. The principle stayed; the mechanism became code.
Where you’ve already seen sequencers
If you’ve ever owned a washing machine with a click-click-click rotary timer dial, you’ve used a mechanical drum sequencer. Old jukeboxes, traffic lights, and stage-curtain controllers all started as cam-and-drum machines. The earliest PLCs explicitly marketed themselves as “drum replacement” — proving how central this pattern was to industry. Even today, many PLC vendors still call their highest-level batch instructions “drum” instructions in honour of this lineage.
Sequencer Output Instruction (SQO)
The SQO (Sequencer Output) instruction is the software equivalent of the mechanical drum. It steps through a stored data table one row at a time, and on each step copies that row’s bit pattern into a destination — typically an output word that drives the field outputs.
The five SQO parameters
| Parameter | Example | What it does |
|---|---|---|
| File | #N7:0 | The sequencer data table — one row per step. Each row is a bit pattern that will be copied to the destination at that step. |
| Mask | FFFFh or 00FFh | Which bits of the destination the SQO is allowed to change. Bits set to 1 in the mask are written; bits set to 0 are left alone (so other logic can drive those bits). |
| Destination | O:2 | The output word (or any word) where the current step’s pattern is written. |
| Control | R6:0 | The control register that holds the position pointer, length, and status bits. Same family as the FAL control register from Chapter 11. |
| Length | 4 | How many steps are in the sequence (rows in the file, not counting row 0). |
The control register’s status bits
The control register tracks the SQO’s progress and exposes useful status:
R6:0/EN— Enable bit: true while the SQO’s rung is true.R6:0/DN— Done bit: pulses true for one scan when the SQO returns to step 1 (i.e. completes one full cycle).R6:0/ER— Error bit: set if there’s a configuration problem (bad length, bad position, etc.).R6:0.LEN— Length: the configured length value.R6:0.POS— Position: the current step number (1, 2, 3 … LEN, then back to 1).
How SQO advances
SQO advances on each false-to-true transition of its rung. A common pattern is to drive the SQO from a self-clearing timer — TON with a preset of N seconds, with T4:0/DN as the SQO’s rung condition. Each time the timer’s DN bit pulses, the SQO advances one step. After the configured length, it wraps back to step 1.
Step 0 is special
Most SLC-style PLCs reserve step 0 of the sequencer file as the “reset” step. It contains the pattern that should be applied when the sequencer is reset (typically all zeros — all outputs off). Steps 1 through LEN are the actual operating steps. After step LEN, the SQO wraps back to step 1 (not step 0) and continues cycling. Step 0 is only loaded by an explicit reset operation, not by normal advance.
Variable step times
If every step needs the same dwell time, a single TON drives the SQO directly. But real industrial recipes rarely have equal step times — wash for 30 seconds, rinse for 90 seconds, spin for 300 seconds. The standard pattern: store each step’s preset time in a parallel data file (e.g. N7:100 through N7:103 for a 4-step sequence) and have the timer read its preset from N7:[100 + R6:0.POS - 1]. The timer’s preset changes with the step, so each step has its own duration. We’ll see this pattern in Worked Example 2.
Sequencer Compare Instruction (SQC)
The SQC (Sequencer Compare) instruction is SQO’s mirror image. Where SQO writes a stored pattern to an output word at each step, SQC reads a field input word and compares it to a stored pattern. If they match, the SQC’s FD (Found) bit goes true; if they don’t match, FD stays false.
SQC has the same five parameters as SQO (file, mask, source, control, length) — but the “destination” of SQO is replaced by a “source” parameter that points to the input word being compared, and the comparison result is reported through the FD bit instead of being written somewhere.
The classic SQO + SQC pairing
SQO and SQC are designed to work together. The pattern is fundamental to verified industrial sequencing:
- SQO writes the expected output pattern for the current step (open valve A, start pump 1, energise heater, etc.).
- SQC reads the actual sensor pattern for the current step (valve A actually open? pump 1 actually running? heater actually on?).
- SQC’s FD bit is true if the sensors confirm what SQO commanded. If the sensors disagree (a valve failed to open, a pump didn’t start), FD goes false — and your alarm logic raises the alarm and halts the sequence.
This is how every safety-rated batch process verifies itself: SQO commands, SQC verifies. We’ll see exactly this pairing in Worked Example 2.
When SQC catches what your eyes miss
Imagine a valve has a stuck-open fault — its solenoid is energised, but the disc inside is mechanically jammed in the open position. The PLC tells the valve to close at step 5 of a sequence. The output bit goes off as commanded, but the valve’s position-feedback sensor still reads “open”. Without an SQC checking that step 5’s expected sensor pattern includes “valve closed”, the sequence carries on — and product flows where it shouldn’t. With the SQC pairing, FD goes false at step 5, the alarm fires, and the operator catches the failure before it spreads. SQC turns silent mechanical failures into loud, immediate alarms.
SQC’s mask: same idea as SQO’s
The SQC’s mask works just like SQO’s: bits set to 1 in the mask are compared; bits set to 0 are ignored. Use this when you only want to verify some inputs at each step (e.g. ignore the spare digital inputs that aren’t tied to anything yet).
Bit Shift Registers (BSL and BSR)
Where sequencers walk through a stored pattern row by row, shift registers walk a single bit position by position. Each time the rung is triggered (typically by an encoder pulse from a moving conveyor), every bit in the register shifts one position. A new bit enters from one end; the bit at the other end falls out.
This is exactly the model you need to track parts moving along a conveyor. Each register bit represents one physical position on the line. As the conveyor advances by one position, the register shifts by one bit — keeping the register’s internal layout perfectly synchronised with what’s actually moving on the line.
BSL — Bit Shift Left
The BSL instruction shifts every bit toward higher positions (low → high). A new bit, taken from the configured Bit Address, enters at position 0. The bit previously at the highest position (length − 1) is unloaded into the UL bit of the control register and then discarded.
BSL file: #B3:10 control: R6:0 bit address: I:1/0 length: 16
That instruction creates a 16-bit shift register starting at B3:10. Each time the rung becomes true, every bit shifts up one position and the value of I:1/0 is loaded into bit 0. The bit that was at bit 15 ends up in R6:0/UL and then drops off. Use this when parts enter at one end of the conveyor (position 0) and leave at the other end (position 15).
BSR — Bit Shift Right
The BSR instruction is the mirror — bits shift toward lower positions (high → low). The new bit enters at the highest position (length − 1), and the bit at position 0 is unloaded into UL.
BSR file: #B3:20 control: R6:1 bit address: I:1/4 length: 16
Choose BSL or BSR to match the physical direction of your conveyor. If parts move left-to-right and your register’s “input” side is at low addresses, use BSL. If parts move right-to-left, or if your “newest” data should sit at the top of the register, use BSR.
Figure 12.2 — Bit shift register tracking defects on a conveyorThe inspection station sets a “1” in B3:10/0 whenever it detects a defect. Each conveyor advance shifts the bits left. When the “1” reaches B3:10/6 (above the ejector), the ejector fires and the defective part is rejected. The register’s bit positions stay perfectly synchronised with the parts on the line.
The shift trigger — encoder pulses, photo-eyes, or timers
The shift register only updates when its rung sees a false-to-true transition. Common triggers:
- Encoder pulse from the conveyor drive — one pulse per conveyor advance position. The register stays mechanically synchronised with the conveyor regardless of speed.
- Photo-eye at a known position — each part passing the eye triggers one shift. Robust if part spacing is known and consistent.
- Periodic timer — a TON’s DN bit pulses every X seconds. Suitable when the conveyor moves at a known fixed speed.
One trigger pulse, one shift
Just like ADD-with-OSR from Chapter 11, the shift register needs a clean rising-edge pulse from its trigger. If the trigger holds true for multiple scans, the BSL/BSR only fires once on the rising edge — the instructions have built-in edge detection through the control register’s EN bit. You don’t need a separate OSR. But if you’re driving the trigger from a continuous signal (like a photo-eye that stays high while a part is in front of it), the BSL will fire once when the eye first goes high, then nothing until the next part arrives.
Word Shift Operations — FIFO and LIFO
Bit shift registers move single bits one position per pulse. Word shift registers move whole 16-bit values — each “slot” holds an entire word, not a bit. They come in two flavours:
- FIFO — First-In, First-Out. The first value loaded is the first value retrieved. Like a queue at a service counter: whoever arrived first is served first. Used for print job queues, customer order processing, recipe step scheduling, anywhere fairness matters.
- LIFO — Last-In, First-Out. The last value loaded is the first retrieved. Like a stack of plates: take from the top of the pile. Used for undo buffers, function-call return addresses in the PLC’s own scan logic, depth-first traversal, and any “go back where you came from” pattern.
FFL and FFU — the FIFO pair
FIFO needs two paired instructions:
- FFL — FIFO Load. Loads a source value into the next empty slot at the back of the queue. Configured with the source word, the FIFO file (an array), the control register, and the length.
- FFU — FIFO Unload. Removes the value from the front of the queue and writes it to a destination word. All remaining values shift forward by one slot.
The shared control register tracks how many values are currently in the queue. R6:n/EM (empty) is true when the queue is empty; R6:n/FU (full) is true when the queue has reached its configured length and can’t accept more values. Always check these flags before loading or unloading.
LFL and LFU — the LIFO pair
LIFO works almost identically, but the unload instruction (LFU) returns the most recently loaded value rather than the oldest:
- LFL — LIFO Load. Pushes a source value onto the top of the stack.
- LFU — LIFO Unload. Pops the most recent value off the top of the stack and writes it to a destination.
Same EM/FU empty/full flags as FFL/FFU. The only behavioural difference between FIFO and LIFO is which stored value the unload returns — first-loaded for FIFO, last-loaded for LIFO.
When to use each
| Scenario | Choose | Why |
|---|---|---|
| Customer orders, print jobs, work tickets | FIFO | Fairness — earliest arrival served first. |
| Recipe steps loaded ahead of time, executed in order | FIFO | Steps must execute in the order they were queued. |
| Undo buffer (operator pressed UNDO) | LIFO | Undo the most recent action first. |
| Function-call returns / nested subroutines | LIFO | Return to the most recent caller first — classic “call stack”. |
| Tool magazine — reach for the tool you put down last | LIFO | Mechanically simpler — pull from the top of the stack. |
| Sample buffer — keep last N readings | BSR/BSL (bit) or shift array | Neither FIFO nor LIFO unloads — the buffer just rolls over. |
A queue is fair, a stack is fast
If you’ve ever stood in a deli line and watched someone walk up, get served immediately, and leave while you’re still waiting — that’s a stack (LIFO) and it feels unjust. Customers want a queue (FIFO). Now picture stacking dirty dishes by the sink — you wash the top one first, the one you put down most recently. That’s a stack (LIFO) and it feels natural. The same intuition applies in PLC programming: when fairness or order matters, FIFO; when “go back where you came from” matters, LIFO. Pick the wrong one and your logic will almost work, but in the cases where it doesn’t it will be very confusing.
Worked PLC Programs
Five Programs — From Traffic Lights to Print Job Queues
The five programs build progressively through the orchestration toolkit: SQO for a basic traffic-light cycle, SQO+SQC for a verified industrial wash cycle, BSL for tracking defects on a moving conveyor, BSR for a rolling 16-second alarm history, and FFL+FFU for a fair print-job queue.
The problem: a four-way intersection has a north–south traffic signal and an east–west traffic signal. The cycle has four phases: NS-green/EW-red, NS-yellow/EW-red, NS-red/EW-green, NS-red/EW-yellow. Each phase lasts 8 seconds. We need a sequencer that walks through the four phases continuously, with a timer driving each step transition.
Inputs & Outputs
INPUTS
I:1/0 — System enable (latch)
OUTPUTS (driven by SQO into O:2)
O:2/0 — NS Green
O:2/1 — NS Yellow
O:2/2 — NS Red
O:2/3 — EW Green
O:2/4 — EW Yellow
O:2/5 — EW Red
Sequencer File (data table at #N7:0)
| Step | Bit pattern (binary, bits 5..0) | NS | EW | Hex |
|---|---|---|---|---|
| 0 (reset) | 000000 | off | off | 0000h |
| 1 | 100001 | Green | Red | 0021h |
| 2 | 100010 | Yellow | Red | 0022h |
| 3 | 001100 | Red | Green | 000Ch |
| 4 | 010100 | Red | Yellow | 0014h |
Ladder Diagram (Two Rungs)
Rung 0 is a self-resetting 8-second timer (the XIO of T4:0/DN resets it the scan after it times out). Rung 1’s SQO advances one step every time the timer’s DN pulses. The mask 003Fh (binary 111111) lets the SQO drive bits 0 through 5 of O:2 — exactly the six light outputs.
How it works, step by step
- System enable goes true. Rung 0’s timer starts running. R6:0 starts at position 1.
- SQO immediately writes step 1’s pattern (
0021h) to O:2 — bits 0 (NS Green) and 5 (EW Red) go on. The intersection has NS-green/EW-red, exactly as designed. - 8 seconds pass. T4:0/DN pulses true for one scan. The XIO of T4:0/DN on rung 0 opens, dropping the timer’s enable; the next scan T4:0/DN goes false again, the XIO closes, and the timer restarts. Meanwhile rung 1’s SQO sees a false-to-true transition on its rung condition, advances to position 2, and writes step 2’s pattern (
0022h) — NS-yellow/EW-red. - Another 8 seconds. Step 3: NS-red/EW-green.
- Another 8 seconds. Step 4: NS-red/EW-yellow.
- Another 8 seconds. R6:0/DN pulses true (one full cycle complete). The position pointer wraps back to 1, and the cycle starts over.
003Fh) limits the SQO to writing only the bits we care about, leaving the rest of O:2 free for other logic to control. R6:0/DN gives you a clean “cycle complete” pulse that you can use to count cycles, log to history, or trigger end-of-cycle actions.
The problem: a parts-washing cabinet has four steps: pre-rinse, wash, post-rinse, dry. Each step opens different valves and runs different motors, and each step has a different duration (10 s / 60 s / 15 s / 30 s). Crucially, every step has a set of sensors that should report particular states — drain valve closed, fill valve open, cabinet door interlock made, etc. If the actual sensor states don’t match the expected pattern at any step, the cycle must halt and an alarm must fire. This is a textbook SQO + SQC verified-sequencer application.
Inputs & Outputs
INPUTS (read into I:1)
I:1/0 — START button
I:1/1 — Door closed limit switch
I:1/2 — Drain valve closed feedback
I:1/3 — Fill valve open feedback
I:1/4 — Pump running feedback
I:1/5 — Heater on feedback
I:1/6 — Dryer fan running feedback
OUTPUTS (driven by SQO into O:2)
O:2/0 — Fill valve solenoid
O:2/1 — Drain valve solenoid
O:2/2 — Wash pump motor
O:2/3 — Heater contactor
O:2/4 — Dryer fan motor
O:2/7 — ALARM lamp (alarm via SQC)
Two parallel sequencer files — one for outputs, one for expected sensors
| Step | Phase | Duration (N7:100…) | SQO output (N7:50…) | SQC expected (N7:60…) |
|---|---|---|---|---|
| 1 | Pre-rinse | 10 s | 0003h fill+drain | 007Eh door+drain+fill |
| 2 | Wash | 60 s | 000Ch pump+heater | 0076h door+pump+heater |
| 3 | Post-rinse | 15 s | 0003h fill+drain | 007Eh door+drain+fill |
| 4 | Dry | 30 s | 0010h dryer fan | 0042h door+fan |
Ladder Diagram (Three Rungs)
Three rungs: variable-preset timer (rung 0), SQO drives the output pattern (rung 1), SQC verifies the input pattern and the XIO of FD energises the alarm if there’s a mismatch (rung 2). Both sequencers run in parallel from the same step pointer because they share R6:0.POS via the timer’s preset indirection.
Why two separate control registers (R6:0 and R6:1)?
SQO and SQC don’t share their position pointer automatically — each has its own control register. To keep them in sync, you can either (a) drive both from the same trigger so they advance together (T4:0/DN here advances both), or (b) explicitly copy R6:0.POS → R6:1.POS with a MOV every scan. The first method is cleaner; both are common in practice.
N7:[100 + R6:0.POS - 1]), so each step reads its own duration from a parallel data file. This pattern scales: a 12-step batch process uses the same three rungs, just with longer files and Length=12. The pattern’s biggest pedagogical lesson is that sequencing without verification is dangerous — output bits can go on without the field actually responding, and SQC catches exactly that class of failure.
The problem: a bottling line has eight conveyor positions between an inspection station (position 0) and a reject ejector (position 6). When the inspection station sees a defective bottle, that bottle’s position must be tracked through the conveyor so that, six positions later, the ejector kicks the right bottle off the line. The conveyor has an encoder pulse that fires once per advance position. BSL with length 8 makes the bookkeeping trivial: each encoder pulse shifts the register one position, and a “defect detected” sets a 1 into bit 0; six positions later, that 1 reaches bit 6 — and that bit drives the ejector.
Inputs & Outputs
INPUTS
I:1/0 — Inspection station defect-detected output (vision system)
I:1/1 — Conveyor encoder pulse (one rising edge per advance position)
OUTPUTS
B3:10/0..7 — 8-bit shift register (positions 0 to 7)
O:2/0 — Reject ejector solenoid
R6:0 — BSL control register
Ladder Diagram (Two Rungs)
Two rungs total. Rung 0’s BSL shifts the register one position on each encoder pulse, sampling I:1/0 (the defect signal) into bit 0. Rung 1 simply outputs whatever’s currently in B3:10/6 — when the defect bit reaches that position, the ejector fires.
A walk-through over 8 encoder pulses
| Pulse | I:1/0 (defect?) | Register B3:10 (bit 7..0) | O:2/0 (eject) |
|---|---|---|---|
| start | — | 0000 0000 | off |
| 1 | defect | 0000 0001 | off |
| 2 | ok | 0000 0010 | off |
| 3 | ok | 0000 0100 | off |
| 4 | ok | 0000 1000 | off |
| 5 | ok | 0001 0000 | off |
| 6 | ok | 0010 0000 | off |
| 7 | ok | 0100 0000 | ON ← |
| 8 | ok | 1000 0000 | off |
Notice the timing: at pulse 7 the defect bit reaches bit 6 — exactly the position above the ejector — and O:2/0 lights for one shift cycle. The defective bottle gets kicked off the line at the right moment, six conveyor positions after it was inspected. At pulse 8 the bit shifts again to bit 7 (off the inspection-to-reject path) and the ejector turns off.
The problem: a vibration alarm on a critical pump (I:1/0) needs to be logged with the last 16 seconds of history visible to operators on the HMI as a 16-bit “history bar”. Each second, the alarm’s current state is sampled and pushed into the top of a 16-bit register; one second later that bit is one position lower, and 16 seconds later it falls off the bottom and is forgotten. This is exactly what BSR is built for: new data enters at the high bit and ages downward toward the low bit.
Inputs & Outputs
INPUTS
I:1/0 — Vibration alarm (1 = alarm active)
OUTPUTS
B3:20/0..15 — 16-bit alarm history (bit 15 = newest, bit 0 = oldest)
T4:1 — 1-second sample timer
R6:1 — BSR control register
Ladder Diagram (Two Rungs)
Two rungs. Rung 0 generates a 1-second tick. Rung 1’s BSR samples the alarm state at each tick and pushes it into bit 15 (the high bit); existing bits all shift one position right, and the bit at position 0 (oldest, 16 seconds old) falls off into R6:1/UL and is discarded.
A walk-through over 18 sample ticks
Suppose the vibration alarm trips for a 3-second burst starting at tick 5, then again briefly at tick 12:
| Tick (s) | I:1/0 | B3:20 — bits 15..0 (newest left, oldest right) |
|---|---|---|
| 0–4 | 0 | 0000 0000 0000 0000 |
| 5 | 1 | 1000 0000 0000 0000 |
| 6 | 1 | 1100 0000 0000 0000 |
| 7 | 1 | 1110 0000 0000 0000 |
| 8 | 0 | 0111 0000 0000 0000 |
| 9–11 | 0 | 0000 1110 0000 0000 at tick 11 |
| 12 | 1 | 1000 0111 0000 0000 |
| 13 | 0 | 0100 00111 0000 000 (oldest 0 falls off) |
| 17 | 0 | 0000 0100 00111 0000 |
The HMI displays B3:20 as a 16-cell history bar where lit cells indicate “alarm was active at that second”. Operators can immediately see when the alarm fired and for how long — much more useful than just the current alarm state.
BSR vs. BSL — same physics, different geography
You could solve this exact problem with BSL too — just put “newest” at bit 0 instead of bit 15. The choice is purely about which end of the register feels like “the top” to your operators reading the HMI. BSR with newest-at-MSB reads naturally on most HMIs because the high bit is conventionally rendered on the left, so a left-to-right “newer to older” history bar matches how we read English. BSL with newest-at-LSB works fine if your HMI renders bits low-to-high on the left. There’s no “right” answer; pick the one that matches your visual conventions and stay consistent across the project.
The problem: a network printer in a packaging cell receives print job IDs over a serial link as numeric job tokens (e.g. 47, 52, 53, 60). Multiple operators can queue jobs faster than the printer can produce them, so the PLC needs a queue that holds up to 16 jobs and feeds them to the printer one at a time, in arrival order. Each new job arrives in N7:200 with the SUBMIT bit (I:1/0) pulsed; each completed print pulses the printer-ready bit (I:1/1) and the next queued job is delivered to N7:201. Classic FFL / FFU queue.
Inputs & Outputs
INPUTS
I:1/0 — SUBMIT job (one-shot rising edge)
I:1/1 — PRINTER READY (rising edge = ready for next)
N7:200 — Incoming job ID (loaded by ladder before SUBMIT)
OUTPUTS
N7:300..N7:315 — FIFO queue array (16 slots)
N7:201 — Active job ID (output to printer)
R6:2 — FFL/FFU shared control register
O:2/0 — “QUEUE FULL” lamp
O:2/1 — “QUEUE EMPTY” lamp
Ladder Diagram (Four Rungs)
Four rungs: FFL guarded by /FU on rung 0, FFU guarded by /EM on rung 1, plus /FU and /EM directly driving status lamps. The control register R6:2 is shared between FFL and FFU — that’s the key requirement of the FIFO pair.
A walk-through over a busy queue period
| Event | Queue contents (front → back) | EM | FU | N7:201 (active job) |
|---|---|---|---|---|
| start | — | 1 | 0 | (stale) |
| SUBMIT job 47 | [47] | 0 | 0 | (stale) |
| SUBMIT job 52 | [47, 52] | 0 | 0 | (stale) |
| SUBMIT job 53 | [47, 52, 53] | 0 | 0 | (stale) |
| PRINTER READY | [52, 53] | 0 | 0 | 47 |
| SUBMIT job 60 | [52, 53, 60] | 0 | 0 | 47 |
| PRINTER READY | [53, 60] | 0 | 0 | 52 |
| PRINTER READY | [60] | 0 | 0 | 53 |
| PRINTER READY | — | 1 | 0 | 60 |
Notice the order: jobs are printed 47 → 52 → 53 → 60, exactly the order they were submitted. That’s the FIFO guarantee. With LFL/LFU instead, jobs would print 60 → 53 → 52 → 47 — most recent first, original first job last (and grumpy). The FIFO contract is what makes the queue feel fair.
Always guard FFL with /FU and FFU with /EM
Edge cases that bite real production code:
- FFL on a full queue silently drops the new value. The XIO of /FU on the FFL rung prevents that — the SUBMIT goes nowhere if the queue is full, and the operator should see the FULL lamp light to know why.
- FFU on an empty queue produces undefined behaviour on most platforms — the destination might keep its previous value (worst case: a stale job ID gets re-printed) or get garbage. The XIO of /EM on the FFU rung prevents the unload entirely when the queue is empty.
- Always pair /FU and /EM checks with operator-visible lamps so the human in the loop knows when the queue is at a limit.
Common Student Mistakes
Things to watch out for in this chapter:
- Forgetting that SQO advances on rung false-to-true transitions, not on every scan. If your trigger holds true for many scans, the SQO still only advances once. Either gate it with a self-resetting timer (as in Programs 1 and 2) or accept the once-per-rising-edge behaviour.
- SQO writing bits outside the mask. Bits set to 0 in the mask are untouched by SQO — but the corresponding bits in your sequencer file are also ignored. Setting a bit in the file but masking it out is a silent way to wonder why an output never turns on.
- Confusing step 0 and step 1. Step 0 is the reset row, loaded only by an explicit reset. The cycle starts at step 1 and wraps from step LEN back to step 1, never touching step 0 in normal operation.
- Running SQO and SQC out of step. They each have their own control register and don’t auto-sync. Either drive both from the same trigger, or copy
R6:0.POS → R6:1.POSwith a MOV every scan. - FFL on a full queue silently drops the new value. Always guard FFL with an XIO of
R6:n/FU, and let the FULL lamp tell the operator why their submit didn’t take. - FFU on an empty queue produces undefined behaviour. The destination might hold a stale value (worst case: a previously-printed job re-prints). Always guard FFU with an XIO of
R6:n/EM. - Encoder bounce on the BSL/BSR shift trigger. A noisy encoder pulse can register as multiple rising edges per actual position, causing extra shifts and misaligning the register from the conveyor. Either filter the encoder signal at the input, or feed it through a debounce timer before the BSL/BSR rung.
- Wrong shift direction for the conveyor’s physical direction. If parts move left-to-right and you use BSR (which shifts toward the low bit), your “1” will move backwards through the register relative to the part it represents. Match the instruction to the geography.
- Choosing FIFO when LIFO is needed (or vice versa). Customer orders, work tickets, and recipe steps want FIFO (fairness). Undo buffers, function-call returns, and “most recent first” logic want LIFO. The wrong choice almost works — except in the cases where it really matters.
- Sequencer file dimensioning errors. The file’s row count must equal the SQO’s Length (plus row 0). Length=4 needs 5 rows (0 through 4). Length=10 needs 11 rows. An off-by-one error here gives you a “phantom step” with whatever uninitialised data lives at that address.
Quick Recap
The ten things to take away from Chapter 12:
- Software sequencers descend directly from mechanical drum-and-cam machines — same idea, recipe stored as data instead of as physical bumps on a drum.
- SQO walks through a sequencer file and writes each step’s bit pattern to a destination output, with a mask controlling which bits it’s allowed to touch.
- SQC is SQO’s mirror: reads an input word and compares it to an expected pattern, raising the FD bit when they match.
- The SQO + SQC pair is the verified-sequencer pattern: SQO commands, SQC verifies, alarm raised on mismatch.
- Variable step durations come from indirect addressing on the timer’s preset, reading from a parallel data file using
R6:0.POSas the index. - BSL shifts bits from low position toward high; the bit at position 0 comes from the configured Bit Address; the high bit is unloaded into UL.
- BSR is the mirror: shifts from high toward low; new bits enter at the high position; the low bit is unloaded.
- BSL/BSR shift triggers are typically encoder pulses, photo-eyes, or fixed-period timers — whichever keeps the register synchronised with the physical event you’re tracking.
- FFL / FFU are the FIFO pair (queues, fairness); LFL / LFU are the LIFO pair (stacks, “most recent first”).
- Always guard FFL with an XIO of /FU and FFU with an XIO of /EM. Pair both checks with operator-visible status lamps so the human in the loop knows when the queue is at a limit.
Review & Self-Assessment
Chapter 12 Review Questions
Try answering each question on your own first. Tap to reveal the answer when you’re done.
Q1What three things did a mechanical drum sequencer do, and how does each map to a software SQO instruction?+
Q2Name the five SQO parameters and what each one does.+
#N7:0), one row per step. Mask — which destination bits the SQO is allowed to change (1 = write, 0 = leave alone). Destination — the output word the current step’s pattern is written to (typically O:2). Control — the R6:n control register that holds the position pointer, length, and status bits. Length — how many active steps in the sequence (rows 1 through LEN; row 0 is the reset row).Q3What does the SQO mask 003Fh mean, and why use it instead of FFFFh?+
003Fh in binary is 0000 0000 0011 1111 — only bits 0 through 5 are set to 1. The SQO will write to those six bits of the destination and leave bits 6 through 15 untouched. With FFFFh (all bits set) the SQO would overwrite the entire 16-bit destination, including bits driven by other rungs of your program — corrupting their values every step. The mask isolates the SQO’s authority to just the bits it’s responsible for, so other logic can drive other bits of the same destination word safely.Q4In the SQO + SQC verified-sequencer pattern, what catches a stuck-open valve fault?+
Q5How do you implement variable step durations in an SQO-based sequencer where each step has a different time?+
N7:100, N7:101, … one word per step), and configure the step timer’s preset to read indirectly from N7:[100 + R6:0.POS - 1]. The timer’s preset changes automatically as the SQO advances — step 1 reads N7:100, step 2 reads N7:101, and so on. This is exactly the pattern used in the parts-washer worked example to give pre-rinse 10 s, wash 60 s, post-rinse 15 s, and dry 30 s within a single shared sequencer.Q6In a BSL register of length 16, where does a new bit enter, and where does the unloaded bit go?+
R6:n/UL of the control register and then discarded. BSR is the mirror: new bits enter at the highest position, others shift down, and the bit at position 0 is unloaded.Q7How does an encoder pulse keep a BSL register synchronised with parts moving on a conveyor?+
Q8When would you choose BSR over BSL, given that they’re functionally mirror images?+
Q9What’s the difference between FIFO and LIFO, and give one example of where each is the right choice.+
Q10Why must FFL be guarded by an XIO of /FU, and FFU by an XIO of /EM?+
Q11A 5-step batch process needs to verify that, at each step, two specific door interlocks are closed. The other 14 bits of the input word are unused. How do you configure the SQC’s mask, and what’s the alternative?+
I:1/0 and I:1/1, the mask is 0003h (binary 0000 0000 0000 0011). The SQC will compare only those two bits against the expected pattern and ignore the other 14. The alternative would be to leave the mask at FFFFh and pre-load the remaining 14 expected-pattern bits with whatever the field sends — but that requires you to know and store those values for every step (and they can’t change). The mask approach is cleaner and survives any future wiring changes to the unused bits.Q12A bidirectional sortation conveyor sends parts left in one mode and right in the other, controlled by a “direction” output. How would you structure the shift register to track parts in both directions?+
Need help architecting a verified batch sequencer or a real-time part-tracking system?
Get one-on-one tutoring or design-review help from Dr Ahsan Rahman — Head of Electrical Engineering, with two decades of experience designing sequencer, queue, and conveyor-tracking logic for industrial automation.