COP and CPS — Copy
COP and CPS in rungs.dev copy a run of elements from one array into another. Use them to snapshot a buffer, replicate a value, or move a batch of readings in one rung.
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
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.
What they do
COP moves a batch of values in one rung — a whole array of readings into a working copy,
a few elements of a recipe into the active recipe, one element replicated across a buffer.
CPS is the same copy with a guarantee: nothing else touches the data while it runs. On a real
controller that matters, because an input module can update a tag between one element and the
next. Studio runs one thing at a time, so the two behave identically here.
Unlike the timers and counters, these are not edge-triggered: they copy on every scan the rung is true.
Operands
| Name | Type | Notes |
|---|---|---|
source | DINT, INT, SINT, REAL, TIMER, COUNTER, CONTROL | One element — Buf[0], or a whole scalar tag |
dest | DINT, INT, SINT, REAL, TIMER, COUNTER, CONTROL | Where it goes. Also one element |
length | DINT, INT or SINT | How many destination elements to copy. A tag or a number |
One element, not the array
Both operands must name a single element: COP(Samples[0], Copy[0], 5), never
COP(Samples, Copy, 5). That is the opposite of BSL, which does accept the bare
array name. The element you name is where the run starts.
How many elements actually move
length counts destination elements, and the copy stops at whichever tag runs out first.
So all three of these are safe and none of them faults:
| What you wrote | What happens |
|---|---|
length fits both arrays | That many elements copy |
length bigger than either array | Copies as much as fits, then stops |
length of 0 | Copies nothing |
length from a tag holding a negative | Copies the whole remaining run |
A negative length copying everything looks odd, and it is: the controller counts bytes
without a sign, so -3 reads as a very large number and then clamps. Studio does the same.
Nothing at compile time can see what a tag holds, so this is decided while the program runs.
Copying between different types
COP moves raw bytes, it does not convert. Copy a DINT array into a REAL array and you
get the bit patterns read as floats, not the numbers converted. That is deliberate and it is
what a real controller does — it is how you unpack a device word into bytes, or pack four
SINTs into one DINT.
If you want the numbers converted, use MOVE or FLL instead.
Example — Replicate One Value
Fill element 0, then copy it along the array. This is the classic replicate idiom, and it works because an overlapping copy propagates forward: each element is written, then read for the next.
0
Reset
MOVE
Source
Baseline
Dest
Buffer[0]
1
Reset
COP
Source
Buffer[0]
Dest
Buffer[1]
Length
7
Structured Text
Both have a Structured Text form, with the same three arguments:
COP(Samples[0], Snapshot[0], 10);
CPS(Samples[0], Snapshot[0], 10);Common Mistakes
- Naming the bare array —
COP(Samples, Copy, 5). Name an element:Samples[0]. - Expecting a
DINT→REALcopy to convert. It reinterprets the bits. UseMOVE. - Expecting a fault when
lengthis too big. It clamps quietly, which is why a copy that "did nothing" is usually a source that had nothing left from its start element. - Leaving the rung permanently true and wondering why the destination never keeps an edit — it is overwritten every scan.
Related
- Array instructions overview
- FLL — write one value into every element instead
- MOVE — one value, converted rather than reinterpreted
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.
FLL — Fill
FLL in rungs.dev writes one value into every element of a run of an array. Use it to clear a buffer, preset a recipe, or zero a structure in one rung.