Resolving CX-Programmer Set Value Range on Unnamed DM Symbols

James Nishida13 min read
CJ/CP SeriesOmronTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Problem Overview

When commissioning or troubleshooting an Omron CJ1, CS1, CS1H, CP1, or CP1E program in CX-Programmer, an engineer often needs to Set Value (Force / Online Edit → Set Value) to a DM area word such as D100, D200, or D3000 to verify scaling, deadbands, setpoints, or floating-point constants. The expected workflow is: select the word → Online → Set Value → enter a decimal or hex constant → confirm.

The defect symptom is that the Set Value dialog only accepts values inside one of two windows:

  • &0 to &65535 (unsigned decimal)
  • #0000 to #FFFF (unsigned hexadecimal)

Negative numbers, signed 16-bit values below -1, 32-bit double-word values, BCD, or IEEE-754 REAL values cannot be entered. The dialog appears to grey out the sign or simply rejects the value and reverts to the unsigned range. When the same address is right-clicked and changed to display as Integer or Real, the full -32,768 to +32,767 (INT) or -3.4E+38 to +3.4E+38 (REAL) range suddenly becomes accessible — but on the next re-open of the project the setting is lost and the original restriction returns.

This is not a CX-Programmer firmware bug. The PLC's DM area itself stores raw 16-bit words; the limitation is a symbol-table / data-type registration issue in the offline project file. The same hardware behaves correctly once the data type is properly declared.

Root Cause: Unnamed Symbols Default to CHANNEL

CX-Programmer's symbol table uses two distinct mechanisms for labelling an address:

  1. Symbol (named global / local): A registered entry in the global or local symbol table with a Name, Data Type, and Address. The data type can be BOOL, CHANNEL, INT, DINT, UINT, UDINT, WORD, DWORD, BCD, REAL, LREAL, STRING, etc.
  2. Comment only (unnamed global symbol): A legacy mechanism in which the user types a comment directly above an instruction operand without registering a symbol. CX-Programmer still tracks the address internally as an Unnamed Global Symbol — a holdover from earlier SYSWIN and CPT support when symbol names were limited to 6–8 characters.

Unnamed Global Symbols carry no explicit data type. To stay backward-compatible, CX-Programmer restricts them to two implicit types only:

Operand Implicit Data Type Allowed Display / Entry Range
Single bit (e.g., W0.00) BOOL 0 or 1
Word / channel (e.g., D0) CHANNEL &0-65535 or #0000-FFFF

Because no data type is registered, CX-Programmer cannot render the value as INT (signed), BCD, or REAL — even though the bit pattern in the PLC is identical. When the dialog's right-click context menu is used to switch the view to Integer or Real, CX-Programmer applies an ad-hoc display override for that session only. The override is not saved with the project and reverts the next time the symbol is opened.

Editing the symbol via Edit → Symbol or right-clicking the address and choosing Edit Symbol reveals the underlying limitation: the Data Type dropdown is greyed out to BOOL or CHANNEL only. CX-Programmer explicitly disallows promotion of an unnamed symbol to REAL or DINT.

Why Some Addresses Show Integer or Real Automatically

If the engineer has previously registered a named symbol pointing at the same DM address — for example, PID_Error as REAL, or Counter_PV as INT — CX-Programmer stores the data type in the symbol table of the .cxp project file. From that point onward, every reference to that address inside the project, including bare operand entries in ladder, inherits the named symbol's data type. The Set Value dialog then opens with the full numeric range, sign, and decimal-point support appropriate to the data type.

Common patterns that produce a working symbol without realising it:

  • The address is referenced inside a Function Block (FB) instance whose internal variables map onto the DM area.
  • CX-Programmer auto-creates a symbol when the engineer types a name into the Symbol column of a rung operand (instead of the Comment column).
  • The project is imported from CX-Integrator / Sysmac Studio round-trip conversion, which re-emits symbols with explicit data types.

Solution 1 — Register a Named Symbol with the Correct Data Type

This is the canonical, long-term fix and applies to CJ1, CS1, CS1H, CP1, CP1E, and CP1L PLCs supported by CX-Programmer V9.x and earlier.

Prerequisites

  • CX-Programmer V7.0 or later (recommend V9.76 or later for full CP1 support — see the Omron Industrial Automation portal for current version notes).
  • Project is offline or in Program mode; symbol changes are not accepted while in Run mode and the dialog will refuse the edit.
  • Right to modify symbols: Protection → Release Password if the project is write-protected (UM protection or task-level protection).

Step-by-Step

  1. Open the project .cxp / .cxm file in CX-Programmer.
  2. Press F8 or choose View → Symbol Table → Global Symbols (or Local Symbols inside an FB).
  3. In the first empty row, type the desired name in the Name column, e.g. PID_SP.
  4. Type the address in the Address/Value column, e.g. D200.
  5. Click the Data Type cell and select the appropriate type:
Intended Use Data Type Numeric Range Storage
Signed 16-bit counter, error term, offset INT -32,768 to +32,767 1 word (16 bits)
Unsigned 16-bit flag map, BCD count, raw register WORD / CHANNEL 0 to 65,535 / 0-9999 BCD 1 word
Signed 32-bit accumulator, double-word counter DINT -2,147,483,648 to +2,147,483,647 2 consecutive words
Single-precision float (scaling, PID CV) REAL ±3.4E+38 (IEEE-754) 2 consecutive words (32 bits)
Double-precision float LREAL ±1.7E+308 (CJ2 / CS1H only) 4 consecutive words (64 bits)
4-digit BCD thumbwheel / DIP BCD 0 to 9999 1 word
  1. Click outside the row to commit. CX-Programmer validates the type against the address family and rejects the entry if the address is incompatible (for example, attempting to assign REAL to a single bit W0.00).
  2. Repeat for every DM address that will receive negative or floating-point data.
  3. Save the project (Ctrl+S). The .cxp file now contains the data-type metadata; reload the project to verify persistence.
  4. Go online, place the PLC in Program mode, then return to Run. Right-click the symbol in the watch window or on a rung operand → Set Value. The dialog now opens with the full INT or REAL entry range and a sign field.
Online symbol-table edits are not supported on CJ1/CS1 platforms. The PLC must be in Program mode, or the project must be edited offline and downloaded. NJ/NX-series controllers in Sysmac Studio allow online symbol edits but are outside CX-Programmer's scope.

Solution 2 — Loading Floating-Point Constants Without a REAL Symbol

For legacy programs where renaming an address to a named REAL symbol would break documentation or HMI tag mapping, there is a well-known workaround that pre-dates the symbol-table fix. It uses only the +F (Floating-Point Add) instruction and exploits the fact that the destination operand of +F and MOVL may be any 32-bit-aligned word pair, even one without a registered symbol.

Step-by-Step (loading 50.0 into D3000/D3001 as REAL)

  1. Insert a rung with the +F (Floating Add) instruction:
[ +F    +5.0E+1    +0.0E+0    D3000 ]
   S1       S2         D
  1. Source 1 (S1) is the hard-coded floating constant +5.0E+1 — CX-Programmer accepts scientific-notation floats in the operand entry even when the destination is unnamed.
  2. Source 2 (S2) is +0.0E+0 to neutralise any garbage previously in D3000/D3001. Alternatively, point S2 at a known-zero REAL register such as D0 after first clearing it with a MOV #0000 D0 rung.
  3. The destination D is D3000. The +F instruction interprets the destination as a 32-bit REAL word pair, placing the IEEE-754 single-precision encoding of 50.0 across D3000 (low word) and D3001 (high word).
  4. To copy the value to a different location preserving REAL type, use MOVL:
[ MOVL    D3000    D17020 ]
       S       D
  1. D17020 is treated as the start of a 32-bit REAL block by all subsequent floating-point instructions ( +F, -F, *F, /F, CMP with F modifier, SQRT, etc.) even though no symbol is registered there. The PLC is unaware of CX-Programmer's symbol table — the type lives in the project file, not in the controller.

This technique works for CJ, CS1, CS1H, and CP1H/CP1L CPUs. The CP1E E10/E14 type does not support REAL instructions at all and will flag the +F rung as an instruction error at download time.

IEEE-754 Single Precision on Omron REAL

Once a value is stored as REAL on CJ/CS1 hardware, the bit layout is identical to any other IEEE-754 32-bit single-precision float. This is what allows the bit pattern to round-trip through HMI scripts, OPC tags, and Python helpers without manual re-encoding.

Bit Position (D high word → low word) Field Width Description
31 Sign 1 bit 0 = positive, 1 = negative
30-23 Exponent 8 bits Biased by +127. 0 and 255 are reserved for denormals / ±∞ / NaN.
22-0 Mantissa 23 bits Fractional part after the assumed leading 1. The numeric value is (1.mantissa) × 2(exp-127).

For example, +5.0E+1 (50.0) encodes as 0x42480000: sign=0, exponent=10000100₂ (132 − 127 = 5), mantissa=10010000000000000000000₂ (0.5625). The reconstructed value is (1 + 0.5625) × 2⁵ = 1.5625 × 32 = 50.0. CX-Programmer renders this in the watch window as +5.00000E+1.

The assumed leading 1 (the "hidden bit") is why a 23-bit mantissa field still gives 24 bits of precision — at the cost of no representation for 0.0 in the same form. Zero is encoded as all-bits-zero, which IEEE-754 treats as +0.0 and which Omron REAL also returns for an uninitialised word pair if the high word happens to be #0000.

Verification

  1. After registering the symbol and downloading in Program mode, return to Run. Right-click the address in the watch window → Set Value. Confirm the dialog now shows a sign toggle and accepts -32768 through +32767 (INT) or -3.4E+38 through +3.4E+38 (REAL).
  2. Enter -1 (INT) or -1.0E+0 (REAL) and click OK. The watch window should display the value with a leading minus sign.
  3. Power-cycle the PLC or perform a project save → close → reopen → connect cycle. Reload the project file and verify the symbol's Data Type column still reads INT / REAL and the address still maps to the same DM word.
  4. From a second engineering workstation, copy the .cxp file and open it. The Set Value dialog should behave identically — this proves the data type is stored in the project, not in a per-workstation setting.

Common Instruction Reference

Instruction Mnemonic Operands Effect on Data Type
Move MOV S, D (16-bit) Copies a word; destination inherits the symbol's type if named, else defaults to CHANNEL.
Move Long MOVL S, D (32-bit) Copies a double-word; destination is treated as DINT, REAL, or DWORD depending on adjacent context. Pair alignment is not enforced by the instruction — a mis-aligned MOVL D5 D6 still downloads but causes data overlap.
Floating Add +F S1, S2, D (32-bit) Source and destination are REAL. Constant operands accept scientific notation.
Floating Move (alt) MOVF / inline +F Use +F <const> +0.0 D as a portable float-move that works on every CJ/CS1 CPU.
Float → Int16 FIX S, D Truncates the REAL source to the nearest INT and writes the 16-bit signed result.
Float → Int32 FIXL S, D Truncates REAL to DINT.
Int → Float FLT S, D Converts INT to REAL.
Int32 → Float FLTL S, D Converts DINT to REAL.

Troubleshooting Matrix

Symptom Likely Cause Diagnostic Step Fix
Set Value accepts only 0-65535 Address is an Unnamed Global Symbol Right-click address → Edit Symbol; check if Name field is blank Register a named symbol with INT/REAL data type
Right-click → Integer / Real works once, lost on reload Ad-hoc display override, not a saved type Save project, close, reopen, re-check Register a named symbol
Edit Symbol Data Type dropdown greyed to BOOL / CHANNEL Symbol is unnamed (comment only) Verify Name column is populated Add a Name; CX-Programmer unlocks type selection
REAL value entered as 50.0 displays as +5.0E+1 with extra digits Normal IEEE-754 representation None — this is correct No action; matches PLC output
+F rung flags "instruction error" at download CPU type does not support REAL (CP1E E10/E14, CP1A) Check CPU part number against CX-Programmer supported list Upgrade CPU to CP1E E20/N20/N30 or CP1L
Two adjacent REAL registers overlap and corrupt each other MOVL used with odd-word source/destination Watch both word pairs; values shift by 1 word Always use even-word boundaries for 32-bit data, e.g. D0, D2, D4
Symbol edits rejected in Run mode Online symbol-table edit not supported on CJ1/CS1 Check PLC mode indicator (green PROG vs blue RUN) Switch to Program mode, edit, download, return to Run
Project write-protected UM protection password set Protection → Release Password Enter the UM password; otherwise re-create symbol in a new project

Best Practices

  • Always name symbols in the global or local symbol table. Comments are a documentation convenience; only names carry data type. A consistent naming convention (e.g. FB1_PID_CV_REAL) makes the Set Value behaviour predictable and portable across engineering workstations.
  • Document the data type next to the address in the rung comment even after the symbol is named. Engineers returning to the project after several years will see (REAL) in the comment and avoid the CHANNEL-only trap.
  • Group REAL data on even-word boundaries. CJ/CS1 do not enforce alignment for MOVL or floating-point instructions, so a stray MOVL with an odd-word destination silently overlaps the next variable. Reserve even D-words (D0, D2, D4, …) for 32-bit and 64-bit values.
  • Use the workbench View → Watch Window with the data type column visible (View → Show Data Type) to confirm at a glance what the controller is interpreting each address as.
  • When porting to NJ/NX (Sysmac Studio), the same logic applies but the data type system is stricter: variables must declare INT, LREAL, etc. up front, and there is no "Unnamed Global Symbol" fallback. The legacy CX-Programmer symbol table effectively becomes a de-facto contract for the new project.

Frequently Asked Questions

Why does CX-Programmer allow negative values in the Watch Window but not in the Set Value dialog?

The Watch Window and the Set Value dialog both honour the symbol's registered data type. If the address is named with an INT or REAL data type, both windows accept the full signed range. The 0-65535 restriction appears only when the address is an Unnamed Global Symbol, in which case CX-Programmer defaults the data type to CHANNEL. CX-Programmer's ad-hoc "display as Integer / Real" right-click override changes the watch view only for the current session; it is not a true data type and does not persist.

Can I change a symbol's data type while the PLC is in Run mode?

On CJ1, CS1, and CP1 controllers using CX-Programmer, symbol-table edits require Program mode — the dialog will refuse the change and report that the PLC is online. Switch the mode selector to PROG, edit the symbol, transfer the project to the PLC, then return to MONITOR or RUN. NJ/NX controllers in Sysmac Studio do support online data-type edits for non-retain variables, but this is outside CX-Programmer's scope.

How do I load a floating-point constant such as 50.0 into a DM word pair that has no REAL symbol?

Use the +F instruction with the constant as source 1 and zero as source 2: [ +F +5.0E+1 +0.0E+0 D3000 ]. The destination is interpreted as a 32-bit REAL word pair regardless of whether a symbol is registered, because the +F opcode is typed for REAL. To copy the value to a different location, follow with [ MOVL D3000 D17020 ]. The bit pattern is IEEE-754 single precision, identical to any other platform's float.

Does using a comment on an address instead of a name change the data type at runtime in the PLC?

No. The PLC executes only the bit pattern in memory; it has no concept of a symbol name, comment, or data type. The type is purely a project-file annotation that affects CX-Programmer's online displays, the Set Value dialog range, and how the ladder editor checks operand compatibility. Two identical projects with one using a comment and one using a named REAL symbol will run identical logic on the same hardware — the difference is only in the human-tool interaction.

Why does the Edit Symbol dialog limit data type to BOOL and CHANNEL for some addresses?

That restriction is the explicit signal that the address is an Unnamed Global Symbol. CX-Programmer cannot promote an unnamed address to INT, DINT, REAL, or BCD because there is no name in the symbol table to attach the new type to. Adding a Name in the symbol table immediately unlocks the full type dropdown. If the address is inside a Function Block's local variable scope, the same restriction applies until the variable is declared with a name and type in the FB definition.

Back to blog