PLC Shift Register: BSL, BSR, and Product Tracking Explained
PLC shift register instructions explained — how BSL/BSR shift bits, the classic conveyor product-tracking application, and a ladder example you can reuse.
A PLC shift register is the cleanest solution to a problem that trips up nearly every automation programmer at least once: tracking products as they travel down a conveyor through multiple stations. The moment you try to do it with a pile of timers and one-shot latches, you discover why the shift register instruction exists. One encoder pulse moves every tracked product one station forward — no math, no race conditions, no nested timer chains.
This tutorial explains what a shift register is, how the BSL (Bit Shift Left) and BSR (Bit Shift Right) instructions work in Allen-Bradley ladder logic, and how to build a production-ready conveyor tracking program from scratch. The ladder patterns shown here translate directly to any IEC 61131-3 platform with minor naming changes.
What Is a Shift Register in a PLC?
A shift register is a block of consecutive bit addresses that moves its contents one position per trigger event. Think of it as a queue of true/false flags that slides along in lock-step with your physical conveyor. Each slot in the register represents one station — or one conveyor zone between stations. When the trigger fires (typically an encoder-driven pulse or a photo-eye at a fixed interval), every bit shifts one slot in the chosen direction, and a new bit enters at one end while the bit at the other end exits.
The key difference between a shift register and a plain array of bits is synchronization: all bits move simultaneously on a single rising-edge event. That atomic movement is what keeps the virtual map of your conveyor in sync with the physical product positions.
Shift registers appear in ladder logic as the BSL and BSR instructions in the Allen-Bradley/Rockwell world, and as equivalent SHL/SHR function blocks in IEC 61131-3 platforms. The concept is the same regardless of the vendor.
When to Use a Shift Register vs. Other Instructions
| Situation | Best instruction |
|---|---|
| Products tracked through multiple zones on a conveyor | BSL / BSR shift register |
| Counting parts or batches | CTU / CTD counter |
| Timed sequences (machine cycles) | Sequencer instruction |
| Large data queues (FIFO buffer) | FFL / FFU FIFO |
If your application involves products that need a "status flag" carried with them as they move through discrete zones, reach for BSL or BSR first.
BSL — Bit Shift Left
BSL (Bit Shift Left) shifts every bit in a file one position toward the higher-numbered bit address on each rising edge of its enable rung. A new bit value enters at bit 0 (the lowest address) and exits from the highest bit.
BSL Parameters
| Parameter | Allen-Bradley tag | What it means |
|---|---|---|
| File | B3:0 or a BOOL array tag |
The integer word (or array) that holds the shift register bits |
| Source bit | B3:0/0 or a standalone BOOL |
The value loaded into bit 0 on each shift |
| Length | Integer constant | Number of bits that make up the register |
| Unload bit | Internal status bit | Holds the value shifted out of the highest bit position |
On each false-to-true transition of the BSL enable rung:
- Every bit in the file shifts one position left (toward higher bit numbers).
- The value of the source bit enters at bit 0.
- The bit that was at position
Length − 1moves into the unload bit and is removed from the register.
The BSL instruction has a DN (done) bit that pulses for one scan after a shift completes. Use the DN bit to detect when a product exits the last zone.
BSL Timing Diagram
Trigger rung: _____|‾|___|‾|___|‾|___
Source bit: 0 1 0 0 1
↓ ↓ ↓ ↓
Register B3:0 (8 bits, LSB→MSB):
Before shift 1: 0 0 0 0 0 0 0 0
After shift 1: 1 0 0 0 0 0 0 0 ← source=1 entered at bit 0
After shift 2: 0 1 0 0 0 0 0 0 ← source=0, previous 1 moved to bit 1
After shift 3: 0 0 1 0 0 0 0 0 ← product now at bit 2
After shift 4: 1 0 0 1 0 0 0 0 ← new product entered, first continues moving
This is exactly how a product travels down a conveyor while a new one can enter behind it — independently, simultaneously.
BSR — Bit Shift Right
BSR (Bit Shift Right) is the mirror image of BSL. Bits shift toward lower-numbered positions on each trigger. The source bit enters at the highest position in the register, and the bit at position 0 exits through the unload bit.
When to Choose BSR Over BSL
The choice between BSL and BSR is purely a matter of how you want to visualize the register. If you think of your conveyor flowing left to right on a screen and you want bit 0 to represent the entry of the conveyor, use BSL — products enter at bit 0 and exit at the high end. If you prefer bit 0 to represent the discharge end, use BSR.
Neither is more correct than the other. Pick the convention that makes your HMI tag names and documentation easiest to read, then stick with it throughout the program.
BSR Parameters
The BSR parameters are identical to BSL:
| Parameter | Purpose |
|---|---|
| File | The BOOL array holding the register |
| Source bit | Value loaded at the highest bit position each shift |
| Length | Number of bits in the register |
| Unload bit | Holds the value that falls off the lowest bit position |
How the Shift Register Works in Detail
Understanding the four parameters together is what separates a programmer who can copy a template from one who can design a register for any application.
File (the Register Array)
The file is just a block of consecutive BOOL addresses. In Allen-Bradley ControlLogix you declare a BOOL array tag — for example, ConveyorZone[0..15] for a 16-zone conveyor. In older SLC 500 / MicroLogix systems the file is a bit file address like B10:0 where the length parameter selects how many bits in that word or across adjacent words are used.
The length of the file must equal the number of zones between the photo-eye that detects product entry and the station where the last action must happen. Getting this count right is the single most common source of shift-register bugs.
Source Bit
The source bit determines what value enters the register on each shift. In a product-tracking application the source bit is typically set by the entry photo-eye: when a product breaks the beam at the entry point, the source bit goes true for one scan, then resets. On the next trigger pulse, a 1 enters the register — marking that product as "present." When no product is at the entry photo-eye, the source bit is false and a 0 enters, representing an empty conveyor zone.
In quality-tracking applications the source bit can represent whether the product passed inspection — a 1 for good, 0 for reject. Every zone then carries a "this is a good product" flag rather than just a "product present" flag.
Length
Length is the total number of bit positions in the register. It must match the number of physical zones your trigger divides the conveyor into. If your conveyor has 12 zones between the entry sensor and the reject diverter, set Length to 12.
A common mistake is setting length to the number of stations rather than the number of zone intervals. Draw the conveyor on paper, mark every trigger-pulse interval, and count the spaces between them — that is your length.
Unload Bit
The unload bit receives the value that exits the register on each shift. It is a single-scan indicator. In a basic product-tracking application you may not need it at all — you act on the bits inside the register at specific positions. In a FIFO-style data transfer application the unload bit is how you retrieve each value in order.
The Classic Application: Tracking Products Down a Conveyor
Product tracking with a shift register is the textbook application, and for good reason — it is robust, scantime-efficient, and scales from a 3-zone fill line to a 64-zone automated assembly cell without changing the architecture.
The Problem It Solves
Imagine a bottling line with 10 stations between the fill sensor and a reject diverter at station 10. Products travel at variable speeds (the conveyor indexes, not runs continuously). Some products are rejected by a vision system at station 3. You need to open the diverter gate at station 10 only when a rejected product arrives there — not when a good product arrives, and not when an empty carrier arrives.
Without a shift register, you would need to track each product individually through every station — either with a complex array of timer structures or a state machine that grows quadratically with the number of products in flight. With a shift register, the entire tracking system is one BSL rung and one output rung.
Designing the Conveyor Tracking Register
Before writing a single rung:
-
Map the zones. Draw the conveyor from entry to exit. Mark the entry photo-eye position and every station that needs to act on product status. Count the number of trigger intervals (encoder pulses or zone-crossing events) between entry and each action station.
-
Choose your trigger. The trigger must fire exactly once per zone-length of conveyor travel. The most reliable method is an encoder-generated pulse: one pulse per zone length. A belt-mounted resolver or an incremental encoder on the drive shaft with a pulse scaler is typical. In slower conveyors a photo-eye at each zone boundary works.
-
Define the source bit. Decide what the source bit represents: product present, product passed inspection, product is type A vs. type B, etc.
-
Map register bits to stations. Document which bit number corresponds to which physical station. Bit 0 = entry zone, bit N = action station. Put this in a comment on every relevant rung — future technicians will thank you.
Example: Reject Diverter at Station 8
A conveyor has 8 zones between the entry photo-eye and a reject diverter gate. Products that fail a vision check at the entry point must be diverted. The conveyor is encoder-driven; the PLC generates one shift pulse per zone of belt travel.
Tags used:
| Tag | Type | Purpose |
|---|---|---|
EntryPhotoEye |
BOOL | True when product breaks beam at entry |
VisionReject |
BOOL | True when vision system flags product as bad |
ShiftPulse |
BOOL | One-scan pulse per zone of belt travel (from encoder) |
ConvZone[0..7] |
BOOL[8] | Shift register — 8 bits for 8 zones |
ConvSource |
BOOL | Source bit: true = rejected product present |
DiverterSolenoid |
BOOL | Output — opens reject gate |
Rung 1 — Set the source bit
[EntryPhotoEye]----[VisionReject]----( ConvSource )
Description: Source bit is true when a product is present at
entry AND the vision system has flagged it as reject.
This bit is latched for one scan before the BSL fires.
Rung 2 — Shift the register
[ShiftPulse]----[BSL File:ConvZone[0]
Source:ConvSource
Length:8 ]
Description: On each ShiftPulse rising edge, shift all bits
in ConvZone[] one position left. ConvSource enters
at ConvZone[0]. ConvZone[7] exits to unload bit.
Rung 3 — Activate the diverter
[ConvZone[7]]----( DiverterSolenoid )
Description: When the rejected product reaches zone 7 (the
diverter position), bit 7 is true. Energize the
diverter solenoid to route the product to the
reject lane. The bit clears on the next shift.
That is the complete tracking system. Three rungs. The diverter fires at exactly the right moment regardless of conveyor speed variations, because the shift is keyed to belt travel distance, not elapsed time.
Adding a "Product Present" Layer
In real lines you often want to track two things simultaneously: whether a product is present, and whether it is a reject. You can do this with two parallel shift registers of the same length — one for presence, one for quality:
ConvPresence[0..7] — 1 = product present in this zone
ConvReject[0..7] — 1 = product in this zone is a reject
Both registers share the same ShiftPulse trigger. The source bit for ConvPresence comes from EntryPhotoEye alone. The source bit for ConvReject comes from EntryPhotoEye AND VisionReject.
Rung — Diverter with presence confirmation
[ConvReject[7]]----[ConvPresence[7]]----( DiverterSolenoid )
Description: Only fire the diverter if both the reject flag
AND the presence flag are set at zone 7. Prevents
spurious activation on empty carrier slots.
This two-register pattern is the professional standard for high-reliability diverter control.
A Complete Ladder Example with Encoder Pulse
The following example adds the encoder pulse generation rung to make the program self-contained. This pattern works on Allen-Bradley ControlLogix or CompactLogix with an HSC (high-speed counter) or standard counter driving the shift.
// ── RUNG 0: Generate shift pulse from encoder counter ──────────────────
//
// C5:0 is a CTU counter. Its PV = zones_per_encoder_count (e.g., 100 pulses
// per zone). When C5:0.ACC reaches PV, C5:0.DN fires one scan, then resets.
[EncoderInput]----[CTU Counter:C5:0
Preset:100
Accum:0 ]
[C5:0/DN]----( ShiftPulse )----[RES C5:0]
Description: Each time the encoder counts 100 pulses (= one zone of
belt travel), C5:0 done bit pulses for one scan. That
one-scan pulse is ShiftPulse. The RES resets the counter
immediately so it starts counting the next zone.
// ── RUNG 1: Latch entry photo-eye to source bit ─────────────────────────
[EntryPhotoEye]----[VisionReject]----( ConvSource )
// ── RUNG 2: BSL shift register ─────────────────────────────────────────
[ShiftPulse]----[BSL File:ConvZone[0]
Source:ConvSource
Length:8 ]
// ── RUNG 3: Diverter output ─────────────────────────────────────────────
[ConvZone[7]]----( DiverterSolenoid )
// ── RUNG 4: Clear source bit after shift fires ──────────────────────────
[ShiftPulse]----( OTU ConvSource )
Description: Unconditionally unlatch the source bit immediately after
the shift fires. This prevents a second-scan carry-over
that would enter a spurious 1 on the next pulse.
Why Rung 4 matters: Without it, if the photo-eye signal is still true on the next scan (which it will be for most of the product's time at entry), the source bit remains set and the next shift would enter another 1 — doubling your tracked products. Clearing the source bit in the same scan ensures each product generates exactly one 1 in the register.
For platforms that support one-shot rising (OSR) instructions, replace Rung 4 with an OSR on Rung 1 to produce a single-scan pulse from the photo-eye naturally.
FIFO and LIFO Instructions (Brief Overview)
BSL and BSR are bit-level shift registers — they move single true/false flags. When you need to track integer or real values (product weights, batch IDs, temperatures) through a queue, Allen-Bradley provides dedicated FIFO instructions:
- FFL (FIFO Load): Loads a word value into the bottom of a FIFO stack.
- FFU (FIFO Unload): Unloads the oldest value from the top of the FIFO stack.
- LFL / LFU: Equivalent instructions for LIFO (Last-In, First-Out) stacks.
FIFO is useful when each product carries a numeric property — for example, a checkweigher reading — that must be compared against a limit when the product reaches the reject station. The checkweigher value is FFL-loaded at entry and FFU-unloaded at the reject station, with the queue depth matching the number of zones.
For most presence/quality tracking tasks, BSL with parallel registers is simpler and more transparent during troubleshooting. Reserve FIFO for cases where you need to carry a numeric value rather than a boolean flag.
See PLC programming languages for a comparison of how shift register function blocks are implemented in IEC 61131-3 Structured Text and Function Block Diagram versus Allen-Bradley ladder.
Synchronizing the Shift to the Conveyor
The single most important rule of shift register programming is: the trigger must represent exactly one zone of belt travel, every time, without exception. If the trigger fires at unequal intervals, the virtual register drifts out of sync with the physical conveyor and products get accepted or rejected at the wrong stations.
Encoder-Based Triggering (Recommended)
Use an incremental encoder mounted on the conveyor drive shaft or a tracking roller. Configure the PLC's high-speed counter to generate a pulse every N encoder counts, where N corresponds to exactly one zone length of belt travel. Calibrate N by marking the belt and counting pulses while moving the belt exactly one zone distance.
Advantages: Immune to speed variations, ramp-ups, and ramp-downs. The register always tracks physical position, not time.
Photo-Eye-at-Each-Zone-Boundary Triggering
Mount a photo-eye (diffuse or retro-reflective) at the exit boundary of each zone. Use a one-shot rising instruction on each sensor to generate the shift pulse.
This works well for indexing conveyors (stop-and-go) where the belt always moves products to a fixed position before stopping. It is unreliable on continuous-motion conveyors because products at different positions on the belt trigger their local sensors at different times, and the single BSL register cannot represent that.
Common Synchronization Pitfalls
- Trigger fires while product is between two zones. The shift moves the bit before the product physically arrives. Add a position-offset constant to the register length to compensate, or use encoder-absolute position instead of pulses.
- Multiple products enter before first shift fires. Source bit stays true for two entry events but only one shift fires. Always use an OSR or single-scan latch on the entry photo-eye.
- Conveyor speed varies significantly. Time-based triggers (timer pulses) drift. Encoder-based triggers do not. Always prefer encoder triggering on variable-speed conveyors.
- Belt slip. If the encoder is on the motor and the belt slips, the encoder count does not reflect actual belt travel. Mount the encoder on a tracking roller in contact with the belt surface instead.
For a deeper treatment of conveyor automation including motor control rungs and safety considerations, see the conveyor belt PLC programming guide.
Frequently Asked Questions
What is a shift register in a PLC?
A shift register is a block of consecutive bit addresses that moves all its values one position in a chosen direction each time a trigger signal pulses. In Allen-Bradley ladder logic, BSL (Bit Shift Left) and BSR (Bit Shift Right) are the standard shift register instructions. The register acts as a moving queue that keeps a virtual map of what is physically present on each zone of a conveyor or similar transport system.
What is BSL and BSR?
BSL (Bit Shift Left) moves every bit in the register toward the higher-numbered address on each trigger rising edge, with a new source bit entering at position 0. BSR (Bit Shift Right) is the mirror image — bits move toward lower-numbered addresses, and the source bit enters at the highest position. Both instructions are part of the Allen-Bradley ladder logic instruction set and have direct equivalents in IEC 61131-3 platforms (SHL, SHR, or SFTL/SFTR depending on the vendor).
How is a shift register used for product tracking?
Each bit in the register represents one physical zone on the conveyor. When a product enters the conveyor, the entry photo-eye sets the source bit to 1. The next trigger pulse (encoder-driven) shifts that 1 into bit 0 of the register. Every subsequent trigger pulse moves it one position further — bit 0 → bit 1 → bit 2 — tracking the product through each zone. When the bit reaches the position that corresponds to an action station (a diverter, a labeler, a reject gate), the output rung fires. Multiple products in flight are all tracked simultaneously because each one occupies a different bit position.
What clocks the shift register?
The most reliable clock source is an incremental encoder mounted on the conveyor drive. The PLC counts encoder pulses and generates one shift trigger every N pulses, where N is calibrated to represent exactly one zone length of belt travel. This makes the shift register immune to speed changes, ramp-up/ramp-down periods, and belt elasticity. Time-based triggers (timer pulses at a fixed interval) are only appropriate on indexing (stop-and-go) conveyors where the belt always moves the same distance per cycle.
Can I use a shift register for non-conveyor applications?
Yes. Any application where a state flag must propagate through a sequence of discrete steps in lock-step with a trigger event can use a shift register. Examples include: rotating dial machine positions (each index of the dial shifts the register), multi-stage oven zones tracked by a transport mechanism, batch process pipelines where each reaction step is triggered by a completion signal, and sequential fill-and-seal packaging machines. The sequencer instruction is a related tool for step-based machine control where outputs change at each step rather than flags being carried through zones.
Shift registers are one of the most underused instructions in ladder logic despite being the optimal solution for any tracking problem. Once you understand the four parameters — file, source bit, length, and unload bit — and the rule that your trigger must represent exactly one zone of travel, you can implement robust product tracking in three rungs. Build the encoder-pulse generator from the counter programming guide, wire in your BSL rung, and add the output rung at the zone position you calculated from your conveyor map. That is all it takes.


