Where does a request for %M00001 stop?
Follow the packet. Ignition's Modbus TCP driver builds a request from the OPC item path prefix. That prefix selects a Modbus function code. The request travels over Ethernet to the Modbus TCP server in the IC693CPU374. The CPU then resolves the function code against a fixed set of PLC reference tables. The request for %M dies at that last hop. No Modbus function code points at %M, so no item path prefix in Ignition can reach it.
The 90-30 Modbus server exposes these tables and no others:
| Modbus data type | Function codes (read / write) | 90-30 reference table | Ignition prefix (verified working) |
|---|---|---|---|
| Discrete inputs (input status) | 02 / none | %I |
[PLC]DI420 → %I00420
|
| Coils (coil status) | 01 / 05, 15 | %Q |
[PLC]C429 → %Q00429
|
| Holding registers | 03 / 06, 16 |
%R, %AQ
|
[PLC]HR288 → %R00288 (INT), [PLC]HRF82 → %R00082 (REAL) |
| Input registers | 04 / none | %AI |
IR prefix |
| None | n/a |
%M, %G, %S
|
Not reachable |
To get %M, %G, or %S data into Ignition, copy it into %R or %Q with ladder MOVE instructions. The CPU has no configuration setting that remaps these tables into Modbus space. It also has no alternate Modbus address for them. The existing Quick Panel reached %M because it talked to the CPU in GE's native Ethernet protocol, which addresses every reference table directly. Moving the HMI to Modbus TCP drops that access.
Check 1: Is the TCP path healthy?
Layer one first, even when the symptom looks like addressing. Take this reading: the quality of tags that already work on the same device connection.
| Reading | Meaning | Next check |
|---|---|---|
| DI, C, HR, and HRF tags on the same device show Good quality with live values | Link, IP, port 502 session, and unit addressing all work | Check 2 |
| All tags on the device are Bad or the device status shows disconnected | Physical, IP, or TCP problem | Fix cabling, IP/subnet, and the CPU's Ethernet configuration before touching addressing |
| Some tags are good, some are intermittent | Request timeouts or oversized block reads | Review the driver's request timeout and max-per-request settings, then return to Check 2 |
In this installation, the %I, %Q, and %R tags all read correctly. That rules out the network and points the fault at the reference table.
Check 2: Does the prefix-to-reference offset line up?
Compare the item path number with the PLC reference number on a known-good tag.
| Reading | Meaning | Next check |
|---|---|---|
HR288 returns the value in %R00288
|
Ignition's one-based numbering matches the 90-30 reference numbering | Check 3 |
HR288 returns the value in %R00289 or %R00287
|
Zero-based versus one-based mismatch in the device settings | Toggle the zero-based addressing option on the Ignition device, then re-verify |
HRF82 returns a garbage float while HR82 and HR83 look sane |
Word order for 32-bit values is wrong | Toggle the reverse word order option, then re-verify |
Here the item path numbers equal the reference numbers directly, and the REAL at %R00082 decodes correctly. Offsets and word order are already correct. Any %M data you move into %R or %Q will land at the address you expect.
Check 3: Is the target in a Modbus-visible table?
Take this reading: the reference type of each tag that fails.
- %I, %Q, %R, %AQ, %AI: The address is reachable. Check the reference against the CPU's configured table size, because an address past the end returns an exception.
- %M, %G, %S: The address is not reachable over Modbus at any offset. The server answers with an exception (typically Illegal Data Address) or the tag goes Bad. Go to the mapping procedure.
Before mapping, decide which way each bit flows. Status bits flow from the PLC to the HMI and only need a PLC-side copy into the Modbus table. Command bits, such as HMI pushbuttons, flow from the HMI to the PLC. For those, Ignition writes to %R or %Q and ladder copies the value back into %M. Keep status and command bits in separate register blocks. If one register is both written by Ignition and overwritten every scan by a MOVE, the HMI write is lost on the next scan.
How do you map %M into %R or %Q?
Pick the destination first. %R is usually the safer target. %Q references in the configured I/O range drive physical outputs, so a %M copy into those references would energize real field devices. If you use %Q, restrict the copies to %Q references with no module assigned.
- Inventory every %M, %G, and %S reference the Quick Panel application uses. Mark each as status (PLC to HMI) or command (HMI to PLC).
- Check alignment. When the %M bits sit in contiguous, byte-aligned blocks, move them as words. A single MOVE INT/WORD then carries 16 bits into one %R register.
- Reserve an unused %R block for status words and a separate unused %R block for command words. Cross-reference the program to confirm nothing else writes there.
- For status, add MOVE WORD instructions from each aligned %M block into the status %R block, executed unconditionally every scan.
- For scattered, non-aligned bits, use bit-level moves (MOVE BIT or a contact/coil pair) into individual %Q references or into bit positions of a %R word.
- For commands, add MOVE WORD or bit moves from the command %R block back into the target %M references. Pulse-type commands need a reset strategy. Either Ignition writes 0 after the press, or the PLC clears the command word after it acts.
- In Ignition, create one HR tag per packed %R word. Break out the individual bits with expression tags, or use bit-within-register addressing if your driver version supports it. Map each bit to the original Quick Panel tag name.
- Download the logic and put the CPU in RUN.
In a packed word, the lowest-numbered %M reference lands in bit 0 of the %R register. For example, a word move starting at %M00001 places %M00001 in bit 0 and %M00016 in bit 15. Build the Ignition bit breakout on that order, and confirm it with the verification steps below before commissioning screens.
How do you verify the mapped bits end to end?
Verify against the source reference in the PLC, not against the HMI alone. Values reach Ignition one PLC scan plus one poll interval after they change.
- Online with the PLC, force or toggle one known %M status bit, for example
%M00001. Confirm the destination %R word changes by exactly the value of the expected bit (1 for bit 0). - In Ignition, watch the HR tag for that word. The raw integer must match the %R value shown in the PLC reference table view.
- Toggle a high-order bit, such as the 16th bit of the block. Confirm the Ignition breakout tag for bit 15 follows it. This catches off-by-one and bit-order errors in the expression tags.
- For each command bit, write 1 from an Ignition tag. Confirm the command %R word changes, then confirm the target %M reference changes on the next scan.
- Watch the command bit for several seconds after the write. If it snaps back to 0 without a reset action, another MOVE or coil is writing the same register. Find it with a cross-reference and relocate the block.
- Finally, compare every migrated screen object side by side with the running Quick Panel, and confirm matching states on at least one status bit and one command bit per screen.
FAQ
Why does my GE 90-30 %M tag show Bad quality in Ignition when %R tags work?
The 90-30 Modbus TCP server only exposes %I (discrete inputs), %Q (coils), %R and %AQ (holding registers), and %AI (input registers). %M has no Modbus mapping, so the request fails at the CPU no matter which item path prefix you use.
Why does the 90-30 not have a configuration setting to expose %M over Modbus?
The Modbus reference map on the CPU is fixed. The only way to publish %M, %G, or %S is ladder logic that moves the bits into %R or %Q every scan.
How do I move many %M bits into a single %R register?
If the %M bits are contiguous and byte-aligned, one MOVE INT/WORD copies 16 bits into one %R word. Non-aligned bits need individual bit moves.
Why does my HMI command bit written to %R keep resetting to 0?
Something else in the program is writing the same register every scan, usually a status MOVE that overlaps the command block. Keep command and status %R blocks separate, and cross-reference the address to find the conflicting writer.
Why do Ignition HR tag numbers match %R numbers directly on the 90-30?
The Ignition device is using one-based addressing, which matches GE reference numbering, so HR288 reads %R00288. If values appear shifted by one register, toggle the zero-based addressing option on the device.