reference · South Africa
IEC MOVE and Copy: Arrays, Recipes and PLC History
IEC MOVE and copy for PLC learners: check array bounds, history shifts, recipe validation and Siemens MOVE_BLK versus Rockwell COP and CPS data transfers.

IEC MOVE and copy operations transfer data between program variables, but choosing the right operation requires more than matching two tag names. Decide whether you intend to preserve a numerical value, duplicate a typed record or transfer a defined sequence of bytes. Then establish the permitted range, execution trigger and ownership of the data.
This guide helps South African PLC learners review scalar assignments, array copies, recipe transfers and history updates. Its five-slot history and record-validation examples are fictional algorithms with independently checked expected results. They do not establish native controller timing, memory layout or cross-task synchronisation.
This site has a commercial connection to PLC Simulator. Its educational exercises can support practice, but they do not supply vendor engineering licences or guarantee execution of arbitrary native copy instructions. The generated illustrations are conceptual learning scenes, not vendor screenshots or evidence of a customer installation.
Distinguish a value assignment from a memory copy
A numerical assignment expresses that a destination should receive a value according to the language's type rules. A raw memory copy transfers a byte pattern. Those intentions can produce different numerical results when source and destination representations differ. Treat the distinction as part of the design, not an implementation detail to discover after testing.
A simple teaching assignment can be written as Destination := Source; in Structured Text. It is still necessary to declare both variables and check whether the types are compatible. That line does not establish a universal rule for converting strings, arrays, structures or references between unrelated types.
| Intended operation | What must be defined |
|---|---|
| Copy a numerical setpoint | Units, destination range and conversion policy |
| Duplicate an array section | Element type, starting indices and count |
| Transfer a typed recipe | Schema, validity, ownership and application conditions |
| Copy a byte payload | Byte length, field layout, encoding and receiving contract |
| Capture a reporting record | Coherence, timestamp or sequence, and freshness |
Do not use raw copying as a shortcut for an unspecified conversion. A successful transfer of bytes does not prove that the destination represents the intended temperature, count or duration. The PLC data conversion reference explains how numeric conversion differs from scaling and reinterpretation.
Also distinguish an independent copy from a reference to existing data. A pointer or reference may still identify an object owned elsewhere. Copying a containing record does not automatically create independent copies of everything it refers to. For a beginner exercise, use records containing explicitly declared values and avoid implying deeper copy semantics that have not been specified.
Define what executes and who may write
A copy should have a clear trigger. “When a validated recipe request is accepted” differs from “on every cyclic execution while a button remains true”. The second behaviour can repeatedly overwrite changes or repeatedly insert the same history entry. An instruction that executes correctly can still be called at the wrong time.
Identify the writer for each destination. If a routine loads an active recipe and another routine immediately overwrites one of its members, a watch window may suggest that the copy failed. The underlying problem may be ownership and execution order. Cross-reference the destination and inspect every permitted writer before changing the copy instruction.
Record whether consumers may read during an update. A record containing a recipe identifier and a setpoint should not be treated as coherent merely because both fields exist. The application needs a documented point at which the new record becomes available as a complete, accepted revision.
A useful design separates the incoming request, a candidate record and the active record. The request identifies what the user wants; the candidate is checked; the active record is what the application currently accepts. This separation makes rejected requests and pending changes visible without presenting partially checked values as active settings.
Do not assume that a completed local copy acknowledges an external writer or proves that every downstream consumer has received the new revision. Those are separate events. Give request acceptance and application completion distinct meanings where the interface needs both.

Check array bounds before copying a section
Define a fictional source array with indices 10 through 14 and values 101, 102, 103, 104 and 105. Define a destination array with indices 0 through 5, initially containing six zeroes. The exercise requests three source elements starting at index 11 and writes them starting at destination index 2.
The expected result is [0, 0, 102, 103, 104, 0]. The source remains [101, 102, 103, 104, 105]. This example uses equal element types and a separate destination, so it isolates count and index reasoning from overlap and conversion questions.
For a positive count, the last accessed index is the start plus the count minus one. Here the source ends at 13 and the destination ends at 4. Both are inside their declared ranges. Starting the same three-element transfer at source index 13 would require index 15, outside the source contract.
| Requested transfer | Exercise decision | Reason |
|---|---|---|
| Source 11, destination 2, count 3 | Accept | Both complete sections fit |
| Source 13, destination 2, count 3 | Reject | Source section exceeds index 14 |
| Source 11, destination 4, count 3 | Reject | Destination section exceeds index 5 |
| Count below zero | Reject | Not a valid transfer size |
| Count zero | No change | Explicit no-operation rule for this model |
The model also requires integral indices and count. For a nonzero request, validate both starting indices before calculating or accessing the section. Its zero-count rule performs no memory access; a native instruction's accepted arguments and zero-count behaviour must be checked separately.
In a fixed-width implementation, the validation arithmetic itself must not overflow. A bounds check written with an overflowing addition can approve an invalid request. Use a supported wider calculation or a carefully bounded remaining-capacity comparison, and test the exact expression types.
Check unchanged data as well as copied data. Sentinel values before and after the destination section help reveal unintended writes. Use distinct source values rather than filling the source with one repeated number, because identical values can conceal an incorrect start index or copy direction. The array indexing and populated-length reference develops this distinction further.
Worked history update: preserve the old entries first
Consider a five-slot teaching history ordered newest to oldest. Before an accepted event, it contains [A, B, C, D, E]. After inserting a new event N, the required result is [N, A, B, C, D]. E is deliberately discarded because the capacity is five.
One clear reference method takes an independent snapshot of the old history, assigns snapshot positions 0 through 3 to destination positions 1 through 4, then writes N at position 0. The snapshot must be a value copy in the model, not an alias that changes as the destination changes.
A second method for this particular in-place shift copies from the end towards the beginning. It assigns position 4 from 3, then 3 from 2, then 2 from 1, then 1 from 0. Finally it writes the new event at position 0. Each old source value is read before the algorithm overwrites it.
| Step in the descending-index model | History after the step |
|---|---|
| Initial values | A, B, C, D, E |
| Position 4 receives position 3 | A, B, C, D, D |
| Position 3 receives position 2 | A, B, C, C, D |
| Position 2 receives position 1 | A, B, B, C, D |
| Position 1 receives position 0 | A, A, B, C, D |
| Position 0 receives N | N, A, B, C, D |
Now deliberately reverse the loop direction while retaining the same assignments. After position 1 receives A, position 2 reads that newly overwritten A; the repetition continues. Before inserting N, the array becomes [A, A, A, A, A]. This is a counterexample for the stated loop, not a universal prediction about a vendor's overlapping COP implementation.
Writing N into position 0 before preserving the old history is another error. Even a later correctly ordered shift cannot recover the original A from that overwritten slot. Use a saved old value or complete the preservation step first.
The intermediate rows also show why correct final contents do not prove that a concurrent reader saw a coherent history. A reader observing the middle of this algorithm could see repeated entries. The final-state algorithm and the publication strategy need separate review.

Specify event acceptance and history capacity
The exercise inserts exactly one record for each accepted event. A level signal that stays true for five executions should not automatically mean five distinct events. Define how event identity, edge detection or a request-and-acknowledgement interface establishes acceptance for the actual application.
Also define what happens when two events are pending together. Their order should follow an explicit rule rather than whichever routine happened to run first without documentation. For a teaching exercise, process one supplied event at a time and record the accepted sequence. A real event system may need a queue, sequence identifiers or a documented loss policy.
A five-slot display is not an unlimited alarm archive. When the sixth accepted event arrives, the oldest retained entry is removed by this model. Record that capacity in the interface. If retention is a requirement, choose storage and export behaviour that meets it instead of assuming an array shift provides a complete audit history.
An alternative implementation could use a circular buffer, but that changes how the logical newest-to-oldest view maps onto physical indices. Compare the two designs using the same required event sequence. Do not judge correctness by expecting the physical arrays to look identical when their representations differ.
Validate a record before making it active
Use a separate fictional recipe record with three fields: schema version, recipe identifier and a whole-number teaching setpoint. The exercise accepts schema version 1, identifiers 10 or 20, and setpoints from 0 through 100 inclusive. These are arbitrary teaching rules, not process recommendations.
The current active record is (1, 10, 25). A candidate (1, 20, 75) may replace it only when validation passes and the application is permitted to apply the request. A candidate (1, 20, 101) is rejected; the active record remains unchanged. A valid candidate while application permission is false remains pending without changing the active record.
| Candidate and permission | Result |
|---|---|
(1, 20, 75), apply permitted | Active becomes (1, 20, 75) |
(1, 20, 101), apply permitted | Reject; active remains (1, 10, 25) |
(2, 20, 75), apply permitted | Reject unsupported schema |
(1, 30, 75), apply permitted | Reject unknown identifier |
(1, 20, 75), apply not permitted | Pending; active remains unchanged |
Validate a stable candidate. If another writer changes the source between validation and application, the program could apply values different from those it checked. Establish ownership, a captured candidate or an appropriate update protocol. Rechecking a single validity Boolean does not necessarily establish that all fields belong to the same revision.
Keep diagnostic status outside the copied business record unless its schema explicitly includes that status. Copying a structure wholesale may also copy fields that should be generated locally, such as an acceptance timestamp or local approval state. Review each field's meaning instead of assuming all same-sized records are interchangeable.
Continue with the PLC recipe-management guide for request handling and application conditions. This small example tests data selection and rejection; it does not authorise changes to running equipment.

Vendor-specific MOVE and copy behaviour
Siemens MOVE and MOVE_BLK
Siemens' V21 FBD MOVE documentation includes transfer tables for arrays, structures and PLC data types as well as elementary types. The allowed combinations depend on the CPU and IEC-check setting, so describing MOVE as universally scalar-only is too narrow. Consult the Siemens MOVE transfer tables.
The V21 SCL MOVE_BLK reference requires matching source and destination data types and defines COUNT in elements. It identifies an invalid OUT result when the requested data exceeds what the source or destination provides. That does not establish a universal OB121 response. Check the precise language form and its result handling in the Siemens MOVE_BLK documentation.
Rockwell MOVE, formerly MOV
Rockwell documents the change from MOV to MOVE in Logix Designer version 36. Its current MOVE page directs Structured Text users to assignment rather than a named MOVE instruction call. Older project examples therefore need version context; a different mnemonic does not by itself indicate an unsupported project. See the Studio 5000 MOVE reference.
Rockwell COP and CPS
The version 38.01 reference defines COP and CPS as byte copies and Length as destination elements. Their boundaries are base-tag boundaries; a member array can be overrun within its containing tag. The documentation distinguishes controller generations for source-size limits. CPS delays tasks that try to interrupt it, while remote-client updates still require application interlocking. Select it from the documented sharing conditions, not simply because a UDT exists. See the COP and CPS reference.
For a hypothetical destination element occupying four bytes, a requested length of three describes twelve bytes. This arithmetic explains the unit; it does not establish how an arbitrary instruction handles insufficient storage, padding or mismatched layouts. Verify those details on the target.
Make the evidence useful in a training assessment
A good assessment gives the learner distinct source values, known destination contents and an explicit transfer contract. Ask for the expected whole destination before execution. Then check the copied section, unchanged neighbours, source preservation and rejected-input behaviour.
For the history exercise, test more than one insertion. After N and then P, the required logical history is [P, N, A, B, C]. A solution that works only for a freshly initialised array may fail after it starts reading its own previously updated state.
For the recipe exercise, include a valid-but-pending request and an invalid request. Ask the learner to show that the active record stays unchanged in both cases while the reported status differs. This reveals whether validation and application permission have been conflated.
Use PLC program-testing exercises to practise writing explicit outcomes. Confirm the available exercise scope. Mathematical and state-transition fixtures support reasoning; native memory-copy, scheduling and fault behaviour need evidence from the appropriate engineering environment.

Questions about PLC MOVE, array copying and data consistency
Does MOVE delete the source?
A normal value-transfer exercise leaves the source available and changes the destination. Do not interpret the everyday word “move” as a request to clear the source automatically. If clearing is part of the application, specify it as a separate action and consider what should happen if the transfer is rejected or incomplete.
Is COP length measured in bytes?
In the cited Studio 5000 COP/CPS reference, Length counts destination elements. Element size determines the requested byte quantity. Other library functions may use bytes or a different unit, so read the exact parameter definition. A parameter called Length is not enough information to infer the unit.
Can I copy an overlapping array to shift a history?
First check the instruction's overlap semantics. The descending-index algorithm above has an explicitly checked final-state result, while the opposite loop direction destroys required old values. Do not substitute an unverified overlapping native block copy and assume it behaves like a temporary snapshot.
Does a synchronous copy validate a recipe?
No. Data coherence and business validity are separate requirements. A complete record can still contain an unsupported schema, an unknown identifier or an out-of-range setting. Likewise, individually valid fields can belong to different revisions unless the update protocol preserves their relationship.
Why does the copied value change immediately afterwards?
Inspect subsequent writers and the source's update timing. Another routine, HMI write or repeated load request may overwrite the destination after the copy. Capture the execution context and accepted request sequence. Replacing one copy mnemonic with another does not resolve an unspecified writer relationship.
What should a South African PLC course teach here?
Ask for assessed work on types, bounds, event acceptance and unchanged-data checks, using the course's stated controller and software version. Learners comparing classroom options in Johannesburg, Durban or Cape Town can request the same evidence. Location alone does not establish that a provider teaches structured data handling in depth.

Turn the exercise into a clear portfolio record
Keep the input contract, declared types, expected results and observed results together. Explain which tests use a mathematical model and which were run in native engineering software. Include an intentionally wrong history loop and explain why it loses old entries; a visible counterexample is stronger than a claim that the final code is reliable.
For further expression practice, explore Structured Text learning resources and verify the current access terms. Present educational work honestly, with its environment and limits, rather than describing it as a customer commissioning project.
Before accepting any copy routine, account for the complete source and destination sections, the permitted writers, the trigger and the reader's view of the update. Those decisions make a short MOVE or copy statement understandable and testable within the larger program.