Problem Overview
Engineers integrating a Omron Trajexia TJ1-MC16 motion controller with an Omron NT3S series HMI over the Hostlink (SYSWAY/C-mode) serial protocol frequently encounter a 32-bit data corruption symptom. 16-bit INT values round-trip cleanly between the HMI's VR (Value Register) memory and the controller's VR table, but any 32-bit REAL or DINT value splits across two consecutive 16-bit registers in a way that the receiving device cannot reconstruct.
The classic failure signature is: a floating-point number written to VR(300) on the HMI appears on the controller as two consecutive 16-bit words with the high half in VR(300) and the low half in VR(301). Reading VR(300) as a single 16-bit value returns only the high 16 bits of the IEEE 754 representation, which is meaningless as a stand-alone integer and cannot be used directly in Trio BASIC arithmetic.
System Architecture and Components
| Component | Function | Relevant Parameters |
|---|---|---|
| Omron Trajexia TJ1-MC16 | 16-axis motion controller running Trio BASIC | Hostlink slave node, SETCOM parameters |
| Omron NT3S (NTXS) HMI | Operator interface, serial Hostlink master | VR memory, Hostlink port, NTXS configuration software |
| Hostlink (SYSWAY/C-mode) | Serial master/slave protocol, RS-232/422 | 19200 bps, 7 data, 2 stop, even parity typical |
| Trio MotionPerfect | Programming environment for Trajexia | Supports IEEE_IN, IEEE_OUT, VR() table access |
For the canonical wiring and protocol parameters, consult the Trajexia TJ1-MC16 Programming Manual (I52E-EN) and the Trajexia Machine Control System Programming Manual (I58E-EN-05). Both manuals document the Hostlink slave implementation, the SETCOM instruction, and the HLS_NODE parameter.
Root Cause: Non-Standard Trio Floating-Point Format
The root cause is not a bug in either device. It is a floating-point byte-order mismatch between two otherwise IEEE 754-conformant implementations. The Trajexia firmware stores a 32-bit real in a non-standard order:
| Standard | Field Order (32-bit) | Bit Layout |
|---|---|---|
| IEEE 754 (used by Omron NT3S and most PLCs) | Sign → Exponent → Mantissa | SEEE EEMM MMMM MMMM MMMM MMMM MMMM MMMM |
| Trio Trajexia internal format | Exponent → Sign → Mantissa | EEEE EESM MMMM MMMM MMMM MMMM MMMM MMMM |
Because Hostlink exposes only 16-bit integer registers (VR), the four bytes of a Trio float arrive as two raw 16-bit words. Any consumer that interprets them as IEEE 754 will see a corrupted value. Performing arithmetic on the corrupted value produces drift, and comparisons (IF value > threshold) misfire because the bit pattern of a positive number can decode as a negative or out-of-range value.
There is no Hostlink register type code that signals "this is a 32-bit real"; the protocol simply does not carry type information. The NT3S side always packs the 32-bit REAL into two 16-bit words in IEEE 754 order, while the Trajexia side expects them in Trio order.
Hostlink Protocol Limitations on 32-bit Data
Hostlink (also called SYSWAY or C-mode) is a 1970s-era command-response protocol that operates strictly on 16-bit RD / WR word reads and writes. The following are the only legal operations on the TJ1 as a Hostlink slave:
-
RR/WR— read/write a single CIO/IR/HR word -
RD/WD— read/write a single DM/VR word -
RH/WH— read/write the high/low byte of a word
There is no RL / WL 32-bit block primitive, and no "float read" command. The VR() table on the Trajexia is internally stored as 16-bit entries for the purposes of Hostlink access, even when the application uses them as halves of a 32-bit value. This is why the high half appears in TABLE(0) and the low half in TABLE(1) after a write of an IEEE 754 single.
Solution 1: IEEE_IN and IEEE_OUT Conversion in Trio BASIC
The supported workaround is to keep the HMI side in IEEE 754 (which the NT3S cannot change), but reconstruct the value on the controller side using Trio's byte-extraction instructions and IEEE_IN. The instruction takes four bytes in IEEE 754 order and returns the Trio-format floating-point number that the rest of the application can use.
The companion instruction IEEE_OUT performs the reverse: it accepts a Trio-format float and returns four bytes ready to be packed back into two 16-bit words for the HMI. Together, they form a software endianness and field-order shim sitting between the Hostlink register and the application variables.
Conversion Sequence for Reading an HMI-Written REAL
- The HMI places the 32-bit IEEE 754 single in
VR(300)(low word) andVR(301)(high word). - The controller reads both words using
VR(300)andVR(301)in aREPEATloop. - Each word is masked to extract the high and low bytes.
- The four bytes are passed in IEEE order (sign → exponent → mantissa) to
IEEE_IN. - The resulting Trio-format float is stored in a
VRslot that the rest of the program reads.
Reference Implementation
The following MotionPerfect program is a minimal, compilable example that pulls a 32-bit REAL from the HMI, converts it to a Trio float, and exposes it at VR(302) for the application:
\ Read a 32-bit REAL from the HMI (VR300 / VR301)
\ and publish the usable Trio-format value at VR(302)
TABLE(63999, 1) \ reserve a small table
GOSUB comms_set \ configure Hostlink port 1
REPEAT \ main loop
\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
\ Extract the four bytes of the IEEE 754 single
\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
hbhw = (VR(301) AND $ff00) / 256 \ high byte of high word
lbhw = VR(301) AND $00ff \ low byte of high word
hblw = (VR(300) AND $ff00) / 256 \ high byte of low word
lblw = VR(300) AND $00ff \ low byte of low word
\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
\ Reassemble as a Trio floating-point value
\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
VR(302) = IEEE_IN(hbhw, lbhw, hblw, lblw)
UNTIL FALSE
\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
\ Hostlink slave configuration
\ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
comms_set:
HLS_NODE = 0 \ port 1 = Hostlink node 0, slave
SETCOM(19200, 7, 2, 2, 1, 5)
RETURN
Reverse Direction: Writing a Trio REAL to the HMI
To push a value from the controller back to the screen, use IEEE_OUT to obtain four bytes, pack two bytes into each of two consecutive VR words, and let the HMI read them in IEEE order. A typical sequence:
\ Source: Trio-format float in user_var
IEEE_OUT(user_var, hb_out, lb_out, hb_low, lb_low)
\ Pack high word
VR(310) = (hb_out * 256) + lb_out
\ Pack low word
VR(311) = (hb_low * 256) + lb_low
VR table is also little-endian. The shim above preserves that layout, so do not insert a SWAP between extraction and packing unless you also swap on the HMI side.
Solution 2: Replace the NT3S with an NS-Series HMI over Ethernet
Omron's official position is that the only clean way to pass Trajexia REAL values across the HMI boundary is to migrate to an NS5 (or NS8/NS10/NS12/NS15) with Ethernet and the dedicated Trajexia driver. This driver runs the IEEE 754 ↔ Trio conversion inside the NS runtime, so the screen presents a standard REAL to the tag database and no MotionPerfect conversion code is required.
| Approach | Hardware | Protocol | 32-bit REAL | Controller Code Required | Throughput |
|---|---|---|---|---|---|
| Legacy (this article) | NT3S + TJ1 | RS-232 Hostlink | Manual IEEE_IN shim | Yes, every read/write | ~30 tags/s at 19200 bps |
| Recommended | NS5/NS8/NS10/NS12/NS15 + TJ1 | Ethernet (FINS/UDP) | Native in NS driver | None | 100+ tags/s |
NS-series HMI configuration uses CX-Designer or the corresponding Sysmac Studio tool; the Trajexia driver appears in the manufacturer list and exposes VR, TABLE, axis parameters, and the IEEE float registers directly. The full setup is documented in the TJ1-MC16 Programming Manual in the "Communication with NS-series HMI" chapter.
Handshaking: Distinguishing HMI Writes from Controller Writes
If the application must support bidirectional 32-bit transfer (operator changes a setpoint on the screen, controller also updates the displayed value, e.g. an actual-position echo), you must add a handshaking scheme. Without it, both sides will write to the same two VR words and the last writer wins, with no way to tell which side initiated the change.
A common pattern uses a third 16-bit word as a toggle:
\ HMI increments VR(399) every time the operator changes the setpoint
\ Controller compares the new toggle against the last-seen toggle;
\ on change, the controller reads VR(300)/VR(301), runs IEEE_IN,
\ and publishes the value into a Trio variable that the motion
\ program consumes. After consumption, the controller writes a
\ sequence counter to VR(398) so the HMI knows the value has
\ been latched.
| Word | Owner | Meaning |
|---|---|---|
| VR(300), VR(301) | HMI ↔ TJ1 | 32-bit IEEE 754 single payload |
| VR(302) | TJ1 | Reconstructed Trio float (internal) |
| VR(398) | TJ1 | Latch counter (echoes last consumed value) |
| VR(399) | HMI | Change counter (increments on operator write) |
Firmware and Software Versions
Bug-fix history on the NTXS configuration software has included several releases that changed how the NT3S encodes 32-bit values. Always confirm you are running the latest NTXS version available in the Omron download portal before attempting any of the workarounds above; older versions have been observed to encode the mantissa with an internal byte swap that the shim code in this article does not compensate for.
| Component | Recommended Minimum | Notes |
|---|---|---|
| NTXS configuration software | Latest from Omron download portal | Several 32-bit encoding fixes shipped in updates |
| Trajexia firmware | Per the TJ1-MC16 Programming Manual revision matrix |
IEEE_IN / IEEE_OUT available on all shipped revisions |
| MotionPerfect | Version matching controller firmware | Required for VR() debug watch |
Verification Procedure
- Connect the NT3S to the TJ1 with a known-good RS-232 cable (null modem or Omron's XW2Z-style depending on the NT3S port variant). Confirm the link LED is active on the HMI.
- On the HMI, configure Hostlink to match
SETCOM(19200, 7, 2, 2, 1, 5): 19200 bps, 7 data bits, 2 stop bits, even parity, node 0. - Compile and download the sample program to the TJ1. In MotionPerfect, open the Watch window and add
VR(300),VR(301), andVR(302). - On the HMI, place a numeric entry field bound to
VR300and a numeric display bound toVR302(use a 32-bit REAL tag). - Enter the value
1234.5on the screen. The IEEE 754 encoding is0x449A5000. In the watch window,VR(300)should read0x5000andVR(301)should read0x449A.VR(302)should display1234.5. - Enter
-3.14159. The IEEE 754 encoding is0xC0490FDA. VerifyVR(300) = 0x0FDA,VR(301) = 0xC049, andVR(302) = -3.14159. - Add a motion command (e.g.,
MOVEABS(VR(302))on a configured axis) and command the move from the screen. Confirm the axis moves to the commanded position by the indicated amount. - If any verification step fails, halt the controller, swap the two bytes within each word using an extra shift, recompile, and re-test. This isolates whether your NTXS build is byte-swapping within words.
Common Pitfalls and Diagnostic Matrix
| Observed Symptom | Likely Cause | Corrective Action |
|---|---|---|
VR(302) shows very small or zero value |
Byte order is reversed within words | Swap hbhw/lbhw in the IEEE_IN call; recompile |
VR(302) sign is opposite of expected |
Sign bit at wrong bit position | Confirms Trio field-order hypothesis; code is otherwise correct |
| Value drifts slowly when integrated (PID, position) | Floating-point mantissa packing subtlety with repeated IEEE_IN round-trips | Avoid re-encoding the same value; latch a local Trio variable once |
| Hostlink timeout on every read |
SETCOM parameters do not match the HMI project |
Verify 19200,7,2,E in both NTXS project and controller |
IEEE_IN returns 0 even with valid bytes |
Argument order wrong: IEEE_IN expects (high word high byte, high word low byte, low word high byte, low word low byte) |
Reorder the four arguments as shown in the reference implementation |
| Controller can write to HMI but not read | HMI Hostlink port is in "write only" mode or wrong unit number | Reconfigure NT3S as Hostlink master on unit 0 |
Performance and Timing Considerations
At 19200 bps with 7E2, a Hostlink RD of one word requires roughly 33 ms including turnaround. Reading two words and the handshaking counter therefore takes around 100 ms per polling cycle. For closed-loop control, this is far too slow; the Ethernet NS-series path reduces the same cycle to single-digit milliseconds.
If you must remain on Hostlink, place the IEEE conversion in a fast background task triggered by the change counter rather than the main loop, and minimize the number of VR() reads per scan. Also keep VR(300)/VR(301) adjacent in the NT3S project so the byte order is unambiguous; the NT3S does not perform any byte reordering on its own.
Migration Checklist to Ethernet NS-Series
- Replace the NT3S with an NS5, NS8, NS10, NS12, or NS15. Confirm the NS model supports the Trajexia driver; all current NS models do.
- Add an Ethernet port connection between the NS and the TJ1. The TJ1-MC16 has a 10/100 Ethernet port on the front panel.
- In CX-Designer (or Sysmac Studio NS edition), select the Trajexia driver and enter the controller's IP address.
- Map screen numeric entry/display tags directly to the controller's
VRorTABLEaddresses. Set the tag type to REAL (32-bit IEEE 754). - Remove all
IEEE_IN/IEEE_OUTconversion code from the MotionPerfect program. - Recycle power on both devices and download both projects.
- Re-run the verification procedure from the previous section. All six value checks should pass without any byte manipulation in the controller.
FAQ
Why does Hostlink split a 32-bit REAL across two 16-bit registers?
Hostlink (SYSWAY/C-mode) has no 32-bit read or write primitive. The NT3S packs the IEEE 754 single into two adjacent VR words in little-endian order, and the Trajexia receives them as raw 16-bit values VR(300) and VR(301). Reconstruct the value with IEEE_IN.
What is the difference between the Trajexia float format and IEEE 754?
Both are 32-bit single-precision, but the field order differs. IEEE 754 stores sign → exponent → mantissa; the Trajexia stores exponent → sign → mantissa. Reading a Trio-format float as IEEE 754 (or vice versa) produces a corrupted value that will not match the original number.
Can I just swap the two words on the HMI side and skip the controller conversion?
Swapping the two 16-bit words only addresses the word-order, not the field-order within each word. The Trajexia float and IEEE 754 differ at the field level (sign and exponent positions are swapped), so a word swap is not sufficient. The IEEE_IN / IEEE_OUT instructions are required unless you switch to an NS-series HMI over Ethernet with the dedicated Trajexia driver.
Does this issue affect DINT (32-bit integer) values as well?
Yes, any 32-bit value is split across two 16-bit words. DINTs do not have the field-order problem (they are plain two's-complement integers), but they still need their two halves read from consecutive VR words and combined with bit-shifts. For example, dint = VR(301) * 65536 + VR(300) if VR(301) is the high word.
Is there a firmware version of the NT3S that fixes this transparently?
No. The Hostlink protocol on the TJ1 side only exposes 16-bit registers, so no NT3S firmware update can make 32-bit transfers transparent over Hostlink. The clean fix is a hardware migration to an NS-series HMI with Ethernet and the Trajexia driver. For NT3S hardware, the IEEE_IN workaround described in this article is the supported solution.