PLC Simulator
Data & conversion

MOVMove

MOV copies the value of its source (a tag or a constant) into its destination tag — on every scan the rung is true — leaving the source unchanged.

Join 1900+ learners practicing PLC programming

How it works

What MOV does during the scan

MOV is ladder logic’s assignment statement. Source in, destination out: the source may be a literal constant (MOV 500 Target_Speed) or another tag (MOV Recipe_Speed Target_Speed); the destination must be a tag, because it gets written. "Move" is a historical misnomer — nothing leaves the source. Every dialect implements it as a copy.

The behaviour that defines how you use it: a true rung executes the MOV on every scan, and a false rung does nothing at all. Both halves matter. The every-scan half means an unconditional MOV is a hammerlock on its destination — an HMI setpoint written by an unconditional MOV snaps back the instant an operator changes it, overwritten within one scan. The does-nothing half means the destination keeps its last value when the rung goes false; a MOV is not an OTE for numbers, and nothing "un-moves" when the condition drops. Recipe logic exploits exactly this: pulse the MOV once (through an ONS) and the value persists.

When the source and destination types differ, Logix converts the value on the way through — DINT to REAL, REAL to DINT — and the sharp edge is REAL-to-integer: the value is rounded (to nearest, ties to even), and values outside the destination’s range fault or clamp depending on platform. Moving between types silently is convenient right up until it hides a precision bug; the conversion instructions (and their rules) get their own page.

MOV also anchors a family: MVM (masked move — only the bits set in the mask are written, for packing bit fields into words), COP/CPS (copy raw memory across arrays and structures, no conversion), and FLL (fill a range with one value). When someone says "just MOV the whole recipe structure", they usually mean COP — MOV proper handles a single value.

MOV move instruction highlighted on a ladder rung — a Recipe_Select contact conditioning a MOV block that copies source value 500 into the Target_Speed destination tagA ladder rung between power rails: an XIC contact tagged Recipe_Select drives the highlighted MOV block listing Source 500 and Dest Target_Speed. While the rung is true the source value is copied to the destination on every scan; when the rung is false the destination keeps its last value.L1L2Recipe_SelectXICMOVSource 500DestTarget_Speedcopies every scan while true
The MOV (highlighted) copies the constant 500 into Target_Speed while Recipe_Select is true — re-writing it every scan, which is exactly why conditioning the rung matters.
MOV data-flow diagram — the source value 500 is copied into the Target_Speed destination tag on every scan while the rung is true, leaving the source unchangedTwo tag boxes connected by an arrow. Left: the Source box holding the literal value 500. Right: the Dest box for tag Target_Speed showing its value becoming 500. The arrow between them is labelled 'copy every scan (rung true)'. A note underneath states the source is not modified and the destination keeps its last value when the rung is false.Source500Target_Speed500copy every scan (rung true)source unchanged — dest holds last value when rung false
Data flow: the source value is copied to the destination on every true scan; the source is untouched, and when the rung goes false the destination simply keeps the last value written.

Across vendors

MOV in Allen-Bradley, Siemens, IEC 61131-3 and Mitsubishi

PlatformName / syntaxNotes
Allen-Bradley (Studio 5000 / RSLogix)MOVMOV Source Dest, converts between numeric types on the way. Relatives: MVM (masked), COP/CPS (raw copy), FLL (fill).
Siemens (TIA Portal)MOVEMOVE box with EN/ENO and IN → OUT1 (fan-out to multiple OUTs allowed). SCL writes it as an assignment: Target := Source;
IEC 61131-3 (CODESYS, OpenPLC):= / MOVEStructured Text assignment Target := Source; LD/FBD offer a MOVE box. Strict typing — explicit conversion functions where types differ.
Mitsubishi (GX Works)MOV / DMOV / MOVPMOV K500 D0 (16-bit), DMOV for 32-bit, and the P suffix (MOVP) executes once on the rung’s rising edge — a built-in one-shot move.

Mitsubishi’s MOVP pulse variant bakes in what AB programmers build with ONS + MOV. IEC Structured Text drops the pretence entirely: it is an assignment, written like one.

In practice

Worked MOV examples

Example 1 — recipe selection

| Recipe_A_PB    ONS_A              MOV 1200  Fill_Time  |
|-----] [--------[ONS]-------------------[MOV]----------|

| Recipe_B_PB    ONS_B              MOV 2500  Fill_Time  |
|-----] [--------[ONS]-------------------[MOV]----------|

Each button pulses one MOV through a one-shot, loading the fill-time setpoint for that product. The values persist after the buttons release — MOV’s do-nothing-on-false behaviour is the feature. Without the ONS the logic still works here, but the one-shots make the intent explicit and keep the tag writable from the HMI between presses (a held button would pin it).

Example 2 — capturing a value at an event

| Bottle_At_Eye    ONS_Cap        MOV Flow_Rate  Rate_At_Fill |
|-----] [----------[ONS]------------------[MOV]--------------|

| Fault_Active     ONS_Flt        MOV Step_Num   Fault_Step   |
|-----] [----------[ONS]------------------[MOV]--------------|

MOV as a snapshot tool: the instant the bottle arrives, the current flow rate is captured into Rate_At_Fill; the instant a fault fires, the sequence step number is frozen into Fault_Step for diagnostics. The one-shots are essential here — a level-triggered MOV would keep overwriting the snapshot with newer values for as long as the condition held, which defeats the purpose of capturing "the value at the moment it happened".

This capture-on-event idiom is one of the highest-value five-minute additions to any machine program: faults become diagnosable after the fact instead of only while they are active.

Gotchas

Common MOV mistakes

  • An unconditional MOV fighting the HMI

    A MOV on an always-true rung rewrites its destination every scan. Operators change the setpoint on the HMI, and it snaps back before their finger leaves the screen. Setpoints written by both logic and HMI need an explicit arbitration (one-shot moves on events, or a "logic owns it" mode bit).

  • Expecting the destination to clear when the rung goes false

    MOV is not an OTE for numbers — false rungs do nothing, and the destination holds the last value written. If "condition gone" must mean "value zeroed", add a second MOV (or CLR) on the inverse condition.

  • Silent rounding on REAL-to-integer moves

    MOV converts between numeric types, and REAL → DINT rounds. 2.5 becomes 2 (round-to-even), 2.51 becomes 3. Totals computed from rounded moves drift. Do the math in REAL and convert once, deliberately, at the boundary.

  • MOV where COP was needed (or vice versa)

    MOV handles one value with conversion; COP block-copies raw bytes across arrays/UDTs with no conversion. COP-ing between mismatched structures reinterprets bytes rather than converting values — an INT array COP-ed onto a REAL array produces garbage that looks plausible.

  • Moving into a tag that something else also writes

    Same rule as duplicate OTEs, but for words: two MOVs (or a MOV and a PID output) writing one destination means the last write each scan wins and the loser is invisible. Cross-reference the destination before adding "just one more MOV".

Run MOV live — no install

Drop the instruction on a rung in the browser simulator, toggle the inputs, and watch the rung state, accumulator values and outputs update scan by scan.

Questions

MOV — frequently asked

What does the MOV instruction do in a PLC?

MOV copies the value of its source — a constant or a tag — into its destination tag, on every scan where its rung is true. The source is unchanged (despite the name, nothing moves), and on false rungs the instruction does nothing, so the destination retains the last value written.

Does MOV execute every scan or just once?

Every scan the rung is true. If you need a one-time load — recipe selection, capturing a value at an event — put a one-shot (ONS) in front of the MOV, or on Mitsubishi use the pulse variant MOVP. An unconditional always-true MOV effectively locks its destination to the source value.

Can MOV convert between data types like DINT and REAL?

In Allen-Bradley Logix, yes — MOV converts between numeric types on the way through, so MOV of a DINT into a REAL performs the integer-to-float conversion implicitly. Going the other way (REAL into an integer) rounds the value. IEC 61131-3 platforms are stricter and expect explicit conversion functions such as DINT_TO_REAL.

What is the difference between MOV and COP in Studio 5000?

MOV copies a single value and converts between numeric types. COP copies a block of raw memory — arrays, UDT structures — with no conversion at all, just bytes. Use MOV for one number, COP for whole structures of the same layout, and never COP between different layouts expecting conversion.