COP and CPS — Copy
COP and CPS are the Structured Text instructions in rungs.dev that copy a run of elements from one array into another, clamped to whichever array runs out first.
Copies a run of elements from one array into another, stopping at whichever array runs out first. Modeled on the COP and CPS instructions in Logix 5000® controllers.
COP(Samples[0], Snapshot[0], 10);After this statement, the first ten elements of Samples have been copied into Snapshot.
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.
Operands
| Name | Type | Notes |
|---|---|---|
source | DINT, INT, SINT, REAL, STRING, TIMER, COUNTER, CONTROL | One element — Samples[0], or a whole scalar tag |
dest | DINT, INT, SINT, REAL, STRING, TIMER, COUNTER, CONTROL | Where it goes. Also one element |
length | DINT, INT or SINT | How many destination elements. A tag or a number |
Both operands must name a single element, never the bare array name. The element you name is
where the run starts, so COP(Samples[2], Snapshot[0], 3) copies elements 2, 3 and 4.
A STRING copies as its 88 bytes: .LEN as four bytes, lowest first, then the 82 bytes of
.DATA, then two spare bytes. So COP(Reply[0], Msg, 1); turns a SINT buffer into text,
taking .LEN from its first four bytes.
To move only the characters, name the first one: COP(Reply[0], Msg.DATA[0], Count); copies
Count bytes into .DATA and leaves .LEN as it was, so set it next, with
Msg.LEN := Count;. The copy runs on through the two spare bytes and stops only at the end of
the STRING, or of the whole array when Msg is an element of one.
How many elements actually move
length counts destination elements, and the copy stops at whichever tag runs out first. None
of these is an error:
| 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 |
The count is worked out in bytes without a sign, which is why a negative length copies everything rather than nothing.
Copying between different types
COP moves raw bytes — it does not convert. Copying a DINT array into a REAL array
gives the bit patterns read as floats. That is how you pack four SINTs into one DINT, or
unpack a device word into bytes.
For a converted copy of one value, use an assignment instead:
Snapshot[0] := Samples[0];Common Mistakes
- Writing
COP(Samples, Snapshot, 5). Name one element:Samples[0]. - Expecting a
DINT→REALcopy to convert. It reinterprets the bits. - Using the result in an expression.
COPreturns nothing; it is a statement on its own.
Related
- SIZE — how many elements an array has
- Arrays — declaring one
- COP and CPS in Ladder
SWPB — Swap Byte
SWPB in rungs.dev Structured Text writes an INT or DINT with its bytes in a new order, to read numbers and text from devices that store bytes the other way round.
SIZE — Size In Elements
SIZE is the Structured Text instruction in rungs.dev that counts the elements of an array tag and stores the count in a DINT tag, so loops never hardcode an array's length.