Array Instructions Overview

Reference for the Ladder Logic array instructions in rungs.dev — BSL, BSR, FFL, FFU, LFL, LFU, COP, CPS, FLL, AVE, SRT, STD, SIZE, FAL and FSC — and the CONTROL tag structure.

Most instructions work on one value at a time. The array instructions work on a run of elements: a stretch of a DINT array, a whole buffer, a window inside a longer array.

They all need to remember two things between scans — how many elements they are working through, and which one they are on. That is what a CONTROL tag holds, the way a TIMER tag holds a timer's preset and accumulator.

Available Array Instructions

InstructionSymbolPurpose
BSL

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

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.
FFL

FFL

Source

source

(DN)

Array

array

(EM)

Control

control

Length

length

Position

position

Puts a value into the next free slot of a queue on each rising edge, and stops once the queue holds .LEN of them.
FFU

FFU

Array

array

(DN)

Destination

destination

(EM)

Control

control

Length

length

Position

position

Takes the oldest value out of a queue on each rising edge, shifting the rest down one place.
LFL

LFL

Source

source

(DN)

Array

array

(EM)

Control

control

Length

length

Position

position

Puts a value on top of a stack on each rising edge, and stops once the stack holds .LEN of them.
LFU

LFU

Array

array

(DN)

Destination

destination

(EM)

Control

control

Length

length

Position

position

Takes the newest value off the top of a stack on each rising edge, leaving the others where they are.
COP

COP

Source

source

Dest

dest

Length

length

Copies a run of elements from one array into another, stopping at whichever array runs out first.
CPS

CPS

Source

source

Dest

dest

Length

length

Copies a run of elements the way COP does, holding the copy so nothing else can change the data part-way through.
FLL

FLL

Source

source

Dest

dest

Length

length

Writes one value into every element of a run of an array.
AVE

AVE

Array

array

(DN)

Dimension

dimension

(ER)

Dest

dest

Control

control

Length

length

Position

position

Adds up a run of array elements and stores their average in a tag.
SRT

SRT

Array

array

(DN)

Dimension

dimension

(ER)

Control

control

Length

length

Position

position

Sorts a run of array elements into ascending order, in place.
STD

STD

Array

array

(DN)

Dimension

dimension

(ER)

Dest

dest

Control

control

Length

length

Position

position

Works out how spread out a run of array elements is and stores the result in a REAL tag.
SIZE

SIZE

Array

array

Dimension

dimension

Destination

destination

Counts the elements of an array and stores the count in the destination tag.
FAL

FAL

Control

control

(DN)

Length

length

(ER)

Position

position

Mode

mode

Dest

dest

Expression

expression

Works out an expression once for every element of an array and stores each answer, with the control tag counting the elements off.
FSC

FSC

Control

control

(DN)

Length

length

(ER)

Position

position

Mode

mode

Expression

expression

Tests an expression against each element of an array in turn and stops at the first one that passes.

CONTROL Tag Members

Every CONTROL tag exposes the same fields. Access them with a dot (MyControl.POS).

MemberTypeMeaning
.LENDINTLength — how many elements to work through
.POSDINTPosition — which element the instruction is on
.ENBOOLEnable — 1 while a loading or shifting rung is true
.EUBOOLEnable unload — 1 while an FFU or LFU rung is true
.DNBOOLDone — 1 when the instruction has worked through .LEN elements
.EMBOOLEmpty — 1 when the buffer holds nothing
.ERBOOLError — 1 when .LEN or .POS is out of range
.ULBOOLUnload — the bit BSL or BSR shifted out
.INBOOLInhibit — 1 while an FSC search is paused
.FDBOOLFound — 1 when an FSC search matched

Not every instruction uses every bit — and four of them use no control at all.

InstructionControlBits it uses
BSL, BSRyes.EN .DN .ER .UL
FFL, LFLyes.EN .DN .EM
FFU, LFUyes.EU .DN .EM
AVE, STD, SRTyes.EN .DN .ER
FAL, FSCyes.EN .DN .ER .UL .IN .FD
COP, CPS, FLL, SIZEnonone — they keep no state

.IN and .FD belong to FSC: .FD says it found a match and .IN parks the search there until you clear it.

.DN and .EM are results, not switches: the load and unload instructions work them out again from .POS every time they run, so writing one yourself changes nothing.

Reference these members as contacts, the same way you would a timer's:

0

Track.DN

Light

Once per edge, or every scan

The two halves of the family differ on when they run, and mixing them up is the commonest surprise:

  • Once per rising edgeBSL, BSR, FFL, FFU, LFL, LFU, AVE, STD, SRT, and FAL/FSC in ALL or INC mode. Holding the rung true does the job once. To do it again, let the rung go false first.
  • Spread over several scansFAL and FSC with a numerical mode. They keep going on every scan until the run finishes, even after the rung goes false.
  • Every scan the rung is trueCOP, CPS, FLL, SIZE. Leave one of these on a permanently true rung and it runs on every scan, overwriting whatever else touched the destination.

Where the Length comes from

The length you type into the box is a starting value, not something the instruction reads each scan. It is written into .LEN once, when the program starts, and after that the instruction reads .LEN from the control tag.

So writing Track.LEN := 4 from your logic changes how many elements the instruction works through on its next run, even though the box still shows the number you typed. That is deliberate — it is how you make a buffer that grows and shrinks while the program runs.

The array has to be long enough for .LEN

Studio checks the number you type against the array's declared size and tells you in the editor if it does not fit. It cannot check a .LEN your logic writes, because the value only exists while the program runs — so an over-long .LEN stops the program with a major fault instead.

Starting Part-Way Along

The array operand names where the region starts, so both of these are valid:

  • BSL(Samples, …) — start at element 0
  • BSL(Samples[4], …) — start at element 4

Elements before the start are never touched.

Sharing a control

One buffer's load and its unload are meant to share a control tag — that is how they agree on how full it is. Every other array instruction needs a control of its own. A BSL and a BSR do not cooperate through theirs: each one writes its own .UL there, so sharing one means the second shift overwrites what the first reported. Studio warns when it sees that.

  • BSL and BSR — the bit shift instructions
  • FFL and FFU — a first-in first-out queue
  • LFL and LFU — a last-in first-out stack
  • COP and CPS — copy a run of elements
  • FLL — write one value into every element
  • AVE and STD — average and spread
  • SRT — sort a run in place
  • SIZE — how many elements an array has
  • FAL and FSC — run your own expression over every element
  • CONTROL tags — declaring one
  • RES — clears .POS and the status bits, keeps .LEN
  • Arrays — declaring an array tag

On this page