BSL and BSR — Bit Shift

BSL and BSR in rungs.dev move every bit of a DINT array one place along on each rising edge, feeding a new bit in at one end. Use them to track parts down a conveyor.

BSL

Array

array

(DN)

Control

control

(ER)

Source Bit

sourceBit

(UL)

Length

length

Shifts every bit of a DINT array one place toward the high end on each rising edge, feeding the source bit in at bit 0.

BSR

Array

array

(DN)

Control

control

(ER)

Source Bit

sourceBit

(UL)

Length

length

Shifts every bit of a DINT array one place toward the low end on each rising edge, feeding the source bit in at the far end.

What a shift register is

A shift register is a row of bits that all move along together, one place at a time. Think of a conveyor with a station every metre: each time the belt advances one station, whatever was at station 1 is now at station 2, station 2 moves to station 3, and a fresh reading enters at station 1.

BSL (Bit Shift Left) moves the bits toward the high end and feeds the new bit in at bit 0. BSR (Bit Shift Right) moves them toward bit 0 and feeds the new bit in at bit length − 1.

Both work on a DINT array and keep their state in a CONTROL tag, the way a timer keeps its state in a TIMER. Give each shift instruction its own control tag, even a BSL and a BSR on the same array: the bit that falls off the end is reported in the control's .UL, and a second instruction on the same control overwrites it.

Operands

NameTypeNotes
arrayDINT[]Where the region starts — Buf or Buf[2]
controlCONTROLHolds the length, position and status bits
sourceBitBOOLThe bit fed in at the near end
lengthnumberHow many bits long the register is. A plain number, 1 or more

length is typed as a number, not a tag, and it is stored on the control tag as its .LEN — the box shows the tag's value there, the way a timer shows its preset. The instruction reads .LEN from the tag on every run, so logic can change it.

How It Works

Both instructions act on the rising edge — the scan where the rung goes from false to true. Holding the rung true shifts once and no more.

EventWhat happens
Rung goes trueOne shift. .EN and .DN turn on, .POS becomes .LEN
Rung stays trueNothing more
Rung false.EN, .DN, .ER and .POS go to 0 — but .UL is kept
.LEN below zero.ER turns on and nothing shifts
RES on the tag.POS and every status bit go to 0; .LEN is kept

Which bit falls out

.UL is a copy of the bit that left the register — bit length − 1 for BSL, bit 0 for BSR. It is a copy, not a removal: the bit still moves along inside the register as well.

.UL survives a false rung

Every other status bit is cleared when the rung goes false. .UL is not. That is deliberate — it is how you read the bit that just fell off the end on a later scan, after the rung has already dropped.

Example — Conveyor Tracker

A part sensor at the head of a conveyor, and an ejector 8 stations later. Each pulse of Advance moves the whole picture along one station.

0

Advance

BSL

Array

Stations

(DN)

Control

Track

(ER)

Source Bit

PartPresent

(UL)

Length

8

1

Stations[0].7

Eject

Stations[0].7 is bit 7 — the eighth station. When a part reaches it, the ejector fires.

The shift covers whole words

A DINT is 32 bits, and all 32 move

A length of 8 does not mean only 8 bits move. The instruction shifts whole DINT words: a length of 1 to 32 shifts one word, 33 to 64 shifts two, and so on. Bits above length − 1 inside that word move as well, and a bit pushed off the top of the last word is thrown away.

So if you use bit 20 of a register declared with a length of 8, it will drift. Keep anything you want left alone out of the array the shift register lives in.

The same rule decides how much array the instruction needs. A length of 40 needs two DINT elements, so BSL(Buf[1], …, 40) on a DINT[2] has only one element left to work with, and the overrun stops the program with a major fault.

Common Mistakes

  • Adding an ONS in front — unnecessary. BSL and BSR already act on the rising edge.
  • Expecting only length bits to move. See the callout above — the shift is by whole words.
  • Reading .UL as "the bit was taken out". It was copied; it also moved along.
  • Writing .LEN from logic and forgetting the array has to be long enough for it.
  • Array instructions overview — the CONTROL members and where .LEN comes from
  • RES — clears .POS and the status bits, keeps .LEN
  • Arrays — declaring the DINT array a shift register lives in

On this page