FFL and FFU — FIFO Queue
FFL and FFU in rungs.dev build a first-in first-out queue in an array — load a value at one end, take the oldest out at the other. Use them to track parts waiting their turn.
FFL
Source
source
Array
array
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
Array
array
Destination
destination
Control
control
Length
length
Position
position
Takes the oldest value out of a queue on each rising edge, shifting the rest down one place.
What a FIFO is
FIFO means first in, first out — a queue, like people waiting at a counter. The first value you put in is the first one you get back out.
Use one whenever something has to wait its turn: part numbers queuing for an inspection station, recipe steps waiting to run, alarm codes waiting to be shown.
The queue lives in an array you declare, and its state lives in a
CONTROL tag. FFL loads; FFU unloads. They
normally share one control tag — that is how they agree on how full the queue is.
Operands
FFL
| Name | Type | Notes |
|---|---|---|
source | numeric | The value to put in. A tag or a number |
array | numeric[] | Where the queue starts — Buf or Buf[2] |
control | CONTROL | The queue's state |
length | number | How many slots the queue has |
position | number | How many are in use at start-up. Usually 0 |
FFU
| Name | Type | Notes |
|---|---|---|
array | numeric[] | Where the queue starts |
destination | numeric | Where the unloaded value goes |
control | CONTROL | The same control tag the FFL uses |
length | number | Same as the FFL's |
position | number | Same as the FFL's |
The array can be DINT, INT, SINT or REAL. A value of a different type converts on the
way in and out, exactly as MOVE does.
How It Works
Both act on the rising edge. Holding the rung true loads or unloads once and no more.
| Event | FFL | FFU |
|---|---|---|
| Rung goes true | Writes source at .POS, then .POS goes up 1 | Reads the element at the start, shifts the rest down, .POS goes down 1 |
| Queue already full | Loads nothing | — |
| Queue empty | — | Writes 0 to the destination and leaves the array alone |
| Rung false | .EN goes to 0. Nothing else changes | .EU goes to 0. Nothing else changes |
After either one runs, .DN and .EM are worked out again from .POS:
.DNis on when the queue is full —.POShas reached.LEN..EMis on when the queue is empty —.POSis0.
.DN and .EM are results, not switches
They are recomputed from .POS every time the instruction runs, so writing .DN := 1
yourself does not stop the next load. If you want to stop a load, condition the rung.
Example — A Parts Queue
Each part detected joins the queue; each press of Take pulls the oldest one out.
0
PartSeen
FFL
Source
PartId
Array
Queue
Control
QCtl
Length
8
Position
0
1
Take
FFU
Array
Queue
Destination
NextPart
Control
QCtl
Length
8
Position
0
2
QCtl.EM
QueueEmpty
Both instructions name QCtl, so the load and the unload see the same queue.
Where Length comes from
length and position are written into the control tag once, when the program starts — the
instruction reads .LEN and .POS from the tag after that. See
Array Instructions.
Common Mistakes
- Giving the
FFLand theFFUdifferent control tags. They then disagree about how full the queue is. One queue, one control. - Adding an
ONSin front — unnecessary. Both already act on the rising edge. - Expecting
FFUto leave the destination alone when the queue is empty. It writes0. - Declaring the array shorter than
length. It stops the program with a major fault.
Related
- Array instructions overview — the
CONTROLmembers - LFL and LFU — a stack instead of a queue
- RES — empties the queue by clearing
.POS
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.
LFL and LFU — LIFO Stack
LFL and LFU in rungs.dev build a last-in first-out stack in an array — push a value on top, take the newest one back off. Use them for undo histories and nesting.