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

NameTypeNotes
sourceDINT, INT, SINT, REAL, STRING, TIMER, COUNTER, CONTROLOne element — Samples[0], or a whole scalar tag
destDINT, INT, SINT, REAL, STRING, TIMER, COUNTER, CONTROLWhere it goes. Also one element
lengthDINT, INT or SINTHow 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 wroteWhat happens
length fits both arraysThat many elements copy
length bigger than either arrayCopies as much as fits, then stops
length of 0Copies nothing
length from a tag holding a negativeCopies 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 → REAL copy to convert. It reinterprets the bits.
  • Using the result in an expression. COP returns nothing; it is a statement on its own.

On this page