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:
-
&0to&65535(unsigned decimal) -
#0000to#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.
Root Cause: Unnamed Symbols Default to CHANNEL
CX-Programmer's symbol table uses two distinct mechanisms for labelling an address:
- 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.
- 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
- Open the project
.cxp/.cxmfile in CX-Programmer. - Press F8 or choose View → Symbol Table → Global Symbols (or Local Symbols inside an FB).
- In the first empty row, type the desired name in the Name column, e.g.
PID_SP. - Type the address in the Address/Value column, e.g.
D200. - 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 |
- 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). - Repeat for every DM address that will receive negative or floating-point data.
- Save the project (Ctrl+S). The
.cxpfile now contains the data-type metadata; reload the project to verify persistence. - 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.
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)
- Insert a rung with the
+F(Floating Add) instruction:
[ +F +5.0E+1 +0.0E+0 D3000 ]
S1 S2 D
- 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. - Source 2 (
S2) is+0.0E+0to neutralise any garbage previously in D3000/D3001. Alternatively, point S2 at a known-zero REAL register such asD0after first clearing it with aMOV #0000 D0rung. - The destination
DisD3000. 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). - To copy the value to a different location preserving REAL type, use
MOVL:
[ MOVL D3000 D17020 ]
S D
- D17020 is treated as the start of a 32-bit REAL block by all subsequent floating-point instructions (
+F,-F,*F,/F,CMPwith 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.
#0000.Verification
- 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
-32768through+32767(INT) or-3.4E+38through+3.4E+38(REAL). - Enter
-1(INT) or-1.0E+0(REAL) and click OK. The watch window should display the value with a leading minus sign. - 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.
- From a second engineering workstation, copy the
.cxpfile 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.