Compare commits
1 Commits
phase-3-pr
...
phase-3-pr
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c506ea298a |
451
docs/v2/mitsubishi.md
Normal file
451
docs/v2/mitsubishi.md
Normal file
@@ -0,0 +1,451 @@
|
|||||||
|
# Mitsubishi Electric MELSEC — Modbus TCP quirks
|
||||||
|
|
||||||
|
Mitsubishi's MELSEC family speaks Modbus TCP through a patchwork of add-on modules
|
||||||
|
and built-in Ethernet ports, not a single unified stack. The module names are
|
||||||
|
confusingly similar (`QJ71MB91` is *serial* RTU, `QJ71MT91` is the TCP/IP module
|
||||||
|
[9]; `LJ71MT91` is the L-series equivalent; `RJ71EN71` is the iQ-R Ethernet module
|
||||||
|
with a MODBUS/TCP *slave* mode bolted on [8]; `FX3U-ENET`, `FX3U-ENET-P502`,
|
||||||
|
`FX3U-ENET-ADP`, `FX3GE` built-in, and `FX5U` built-in are all different code
|
||||||
|
paths) — and every one of the categories below has at least one trap a textbook
|
||||||
|
Modbus client gets wrong: hex-numbered X/Y devices colliding with decimal Modbus
|
||||||
|
addresses, a user-defined "device assignment" parameter block that means *no two
|
||||||
|
sites are identical*, CDAB-vs-ABCD word order driven by how the ladder built the
|
||||||
|
32-bit value, sub-spec FC16 caps on the older QJ71MT91, and an FX3U port-502
|
||||||
|
licensing split that makes `FX3U-ENET` and `FX3U-ENET-P502` different SKUs.
|
||||||
|
This document catalogues each quirk, cites primary sources, and names the
|
||||||
|
ModbusPal integration test we'd write for it (convention from
|
||||||
|
`docs/v2/modbus-test-plan.md`: `Mitsubishi_<model>_<behavior>`).
|
||||||
|
|
||||||
|
## Models and server/client capability
|
||||||
|
|
||||||
|
| Model | Family | Modbus TCP server | Modbus TCP client | Source |
|
||||||
|
|------------------------|----------|-------------------|-------------------|--------|
|
||||||
|
| `QJ71MT91` | MELSEC-Q | Yes (slave) | Yes (master) | [9] |
|
||||||
|
| `QJ71MB91` | MELSEC-Q | **Serial only** — RS-232/422/485 RTU, *not TCP* | — | [1][3] |
|
||||||
|
| `LJ71MT91` | MELSEC-L | Yes (slave) | Yes (master) | [10] |
|
||||||
|
| `RJ71EN71` / `RnENCPU` | MELSEC iQ-R | Yes (slave) | Yes (master) | [8] |
|
||||||
|
| `RJ71C24` / `RJ71C24-R2` | MELSEC iQ-R | RTU (serial) | RTU (serial) | [13] |
|
||||||
|
| iQ-R built-in Ethernet | CPU | Yes (slave) | Yes (master) | [7] |
|
||||||
|
| iQ-F `FX5U` built-in Ethernet | CPU | Yes, firmware ≥ 1.060 [11] | Yes | [7][11][12] |
|
||||||
|
| `FX3U-ENET` | FX3U bolt-on | Yes (slave), but **not on port 502** [5] | Yes | [4][5] |
|
||||||
|
| `FX3U-ENET-P502` | FX3U bolt-on | Yes (slave), port 502 enabled | Yes | [5] |
|
||||||
|
| `FX3U-ENET-ADP` | FX3U adapter | **No MODBUS** [5] | No MODBUS | [5] |
|
||||||
|
| `FX3GE` built-in | FX3GE CPU | No MODBUS (needs ENET module) [6] | No | [6] |
|
||||||
|
| `FX3G` + `FX3U-ENET` | FX3G | Yes via ENET module | Yes | [6] |
|
||||||
|
|
||||||
|
- A common integration mistake is to buy `FX3U-ENET-ADP` expecting MODBUS —
|
||||||
|
that adapter speaks only MC protocol / SLMP. Our driver should surface a clear
|
||||||
|
capability error, not "connection refused", when the operator's device tag
|
||||||
|
says `FX3U-ENET-ADP` [5].
|
||||||
|
- Older forum threads assert the FX5U is "client only" [12] — that was true on
|
||||||
|
firmware ≤ 1.040. Firmware 1.060 and later ship the parameter-driven MODBUS
|
||||||
|
TCP server built-in and need no function blocks [11].
|
||||||
|
|
||||||
|
## Modbus device assignment (the parameter block)
|
||||||
|
|
||||||
|
Unlike a DL260 where the CPU exposes a *fixed* V-memory-to-Modbus mapping, every
|
||||||
|
MELSEC MODBUS-TCP module exposes a **Modbus Device Assignment Parameter** block
|
||||||
|
that the engineer configures in GX Works2 / GX Configurator-MB / GX Works3.
|
||||||
|
Each of the four Modbus tables (Coil, Input, Input Register, Holding Register)
|
||||||
|
can be split into up to 16 independent "assignment" entries, each binding a
|
||||||
|
contiguous Modbus address range to a MELSEC device head (`M0`, `D0`, `X0`,
|
||||||
|
`Y0`, `B0`, `W0`, `SM0`, `SD0`, `R0`, etc.) and a point count [3][7][8][9].
|
||||||
|
|
||||||
|
- **There is no canonical "MELSEC Modbus mapping"**. Two sites running the same
|
||||||
|
QJ71MT91 module can expose completely different Modbus layouts. Our driver
|
||||||
|
must treat the mapping as site-data (config-file-driven), not as a device
|
||||||
|
profile constant.
|
||||||
|
- **Default values do exist** — both GX Configurator-MB (for Q/L series) and
|
||||||
|
GX Works3 (for iQ-R / iQ-F / FX5) ship a "dedicated pattern" default that is
|
||||||
|
applied when the engineer does not override the assignment. Per the FX5
|
||||||
|
MODBUS Communication manual (JY997D56101) and the QJ71MT91 manual, the FX5
|
||||||
|
dedicated default is [3][7][11]:
|
||||||
|
|
||||||
|
| Modbus table | Modbus range (0-based) | MELSEC device | Head |
|
||||||
|
|--------------------|------------------------|---------------|------|
|
||||||
|
| Coil (FC01/05/15) | 0 – 7679 | M | M0 |
|
||||||
|
| Coil | 8192 – 8959 | Y | Y0 |
|
||||||
|
| Input (FC02) | 0 – 7679 | M | M0 |
|
||||||
|
| Input | 8192 – 8959 | X | X0 |
|
||||||
|
| Input Register (FC04) | 0 – 6143 | D | D0 |
|
||||||
|
| Holding Register (FC03/06/16) | 0 – 6143 | D | D0 |
|
||||||
|
|
||||||
|
This matches the widely circulated "FC03 @ 0 = D0" convention that shows up
|
||||||
|
in Ubidots / Ignition / AdvancedHMI integration guides [6][12].
|
||||||
|
|
||||||
|
- **X/Y in the default mapping occupy a second, non-zero Modbus range** (8192+
|
||||||
|
on FX5; similar on Q/L/iQ-R). Driver users who expect "X0 = coil 0" will be
|
||||||
|
reading M0 instead. Document this clearly.
|
||||||
|
- **Assignment-range collisions silently disable the slave.** The QJ71MT91
|
||||||
|
manual states explicitly that if any two of assignments 1-16 duplicate the
|
||||||
|
head Modbus device number, the slave function is inactive with no clear
|
||||||
|
error — the module just won't respond [9]. The driver probe will look like a
|
||||||
|
simple timeout; the site engineer has to open GX Configurator-MB to diagnose.
|
||||||
|
|
||||||
|
Test names:
|
||||||
|
`Mitsubishi_FX5U_default_mapping_coil_0_is_M0`,
|
||||||
|
`Mitsubishi_FX5U_default_mapping_holding_0_is_D0`,
|
||||||
|
`Mitsubishi_QJ71MT91_duplicate_assignment_head_disables_slave`.
|
||||||
|
|
||||||
|
## X/Y addressing — hex on MELSEC, decimal on Modbus
|
||||||
|
|
||||||
|
**MELSEC X (input) and Y (output) device numbers are hexadecimal on Q / L /
|
||||||
|
iQ-R** and **octal** on FX / iQ-F (with a GX Works3 toggle) [14][15].
|
||||||
|
|
||||||
|
- On a Q CPU, `X20` means decimal **32**, not 20. On an FX5U in default (octal)
|
||||||
|
mode, `X20` means decimal **16**. GX Works3 exposes a project-level option to
|
||||||
|
display FX5U X/Y in hex to match Q/L/iQ-R convention — the same physical
|
||||||
|
input is then called `X10` [14].
|
||||||
|
- The Modbus Device Assignment Parameter block takes the *head device* as a
|
||||||
|
MELSEC-native number, which is interpreted in the CPU's native base
|
||||||
|
(hex for Q/L/iQ-R, octal for FX/iQ-F). After that, **Modbus offsets from
|
||||||
|
the head are plain decimal** — the module does not apply a second hex
|
||||||
|
conversion [3][9].
|
||||||
|
- Example (QJ71MT91 on a Q CPU): assignment "Coil 0 = X0, 512 points" exposes
|
||||||
|
physical `X0` through `X1FF` (hex) as coils 0-511. A client reading coil 32
|
||||||
|
gets the bit `X20` (hex) — i.e. the 33rd input, not the value at "input 20"
|
||||||
|
that the operator wrote on the wiring diagram in decimal.
|
||||||
|
- **Driver bug source**: if the operator's tag configuration says "read X20" and
|
||||||
|
the driver helpfully converts "20" to decimal 20 → coil offset 20, the
|
||||||
|
returned bit is actually `X14` (hex) — off by twelve. Our config layer must
|
||||||
|
preserve the MELSEC-native base that the site engineer sees in GX Works.
|
||||||
|
- Timers/counters (`T`, `C`, `ST`) are always decimal in MELSEC notation.
|
||||||
|
Internal relays (`M`, `B`, `L`), data registers (`D`, `W`, `R`, `ZR`),
|
||||||
|
and special relays/registers (`SM`, `SD`) also decimal. **Only `X` and `Y`
|
||||||
|
(and on Q/L/iQ-R, `B` link relays and `W` link registers) use hex**, and
|
||||||
|
the X/Y decision is itself family-dependent [14][15].
|
||||||
|
|
||||||
|
Test names:
|
||||||
|
`Mitsubishi_Q_X_address_is_hex_X20_equals_coil_offset_32`,
|
||||||
|
`Mitsubishi_FX5U_X_address_is_octal_X20_equals_coil_offset_16`,
|
||||||
|
`Mitsubishi_W_link_register_is_hex_W10_equals_holding_offset_16`.
|
||||||
|
|
||||||
|
## Word order for 32-bit values
|
||||||
|
|
||||||
|
MELSEC stores 32-bit ladder values (`DINT`, `DWORD`, `REAL` / single-precision
|
||||||
|
float) across **two consecutive D-registers, low word first** — i.e., `CDAB`
|
||||||
|
when viewed as a Modbus register pair [2][6].
|
||||||
|
|
||||||
|
```
|
||||||
|
D100 (low word) : 0xCC 0xDD (big-endian bytes within the word)
|
||||||
|
D101 (high word) : 0xAA 0xBB
|
||||||
|
```
|
||||||
|
|
||||||
|
A Modbus master reading D100/D101 as a `float` with default (ABCD) word order
|
||||||
|
gets garbage. Ignition's built-in Modbus driver notes Mitsubishi as a "CDAB
|
||||||
|
device" specifically for this reason [2].
|
||||||
|
|
||||||
|
- **Q / L / iQ-R / iQ-F all agree** — this is a CPU-level convention, not a
|
||||||
|
module choice. Both the QJ71MT91 manual and the FX5 MODBUS Communication
|
||||||
|
manual describe 32-bit access by "reading the lower 16 bits from the start
|
||||||
|
address and the upper 16 bits from start+1" [6][11].
|
||||||
|
- **Byte order within each register is big-endian** (Modbus standard). The
|
||||||
|
module does not byte-swap.
|
||||||
|
- **Configurable?** The MODBUS modules themselves do **not** expose a word-
|
||||||
|
order toggle; the behavior is fixed to how the CPU laid out the value in the
|
||||||
|
two D-registers. If the ladder programmer used an `SWAP` instruction or a
|
||||||
|
union-style assignment, the word order can be whatever they made it — but
|
||||||
|
for values produced by the standard `D→DBL` and `FLT`/`FLT2` instructions
|
||||||
|
it is always CDAB [2].
|
||||||
|
- **FX5U quirk**: the FX5 MODBUS Communication manual tells the programmer to
|
||||||
|
use the `SWAP` instruction *if* the remote Modbus peer requires
|
||||||
|
little-endian *byte* ordering (BADC) [11]. This is only relevant when the
|
||||||
|
FX5U is the Modbus *client*, but it confirms the FX5U's native wire layout
|
||||||
|
is big-endian-byte / little-endian-word (CDAB) on the server side too.
|
||||||
|
- **Rumoured exception**: a handful of MrPLC forum threads report iQ-R
|
||||||
|
RJ71EN71 firmware < 1.05 returning DWORDs in `ABCD` order when accessed via
|
||||||
|
the built-in Ethernet port's MODBUS slave [8]. _Unconfirmed_; treat as a
|
||||||
|
per-site test.
|
||||||
|
|
||||||
|
Test names:
|
||||||
|
`Mitsubishi_Float32_word_order_is_CDAB`,
|
||||||
|
`Mitsubishi_Int32_word_order_is_CDAB`,
|
||||||
|
`Mitsubishi_FX5U_SWAP_instruction_changes_byte_order_not_word_order`.
|
||||||
|
|
||||||
|
## BCD vs binary encoding
|
||||||
|
|
||||||
|
**MELSEC stores integer values in D-registers as plain binary two's-complement**,
|
||||||
|
not BCD [16]. This is the opposite of AutomationDirect DirectLOGIC, where
|
||||||
|
V-memory defaults to BCD and the ladder must explicitly request binary.
|
||||||
|
|
||||||
|
- A ladder `MOV K1234 D100` stores `0x04D2` (1234 decimal) in D100, not
|
||||||
|
`0x1234`. The Modbus master reads `0x04D2` and decodes it as an integer
|
||||||
|
directly — no BCD conversion needed [16].
|
||||||
|
- **Timer / counter current values** (`T0` current value, `C0` count) are
|
||||||
|
stored in binary as word devices on Q/L/iQ-R/iQ-F. The ladder preset
|
||||||
|
(`K...`) is also binary [16][17].
|
||||||
|
- **Timer / counter preset `K` operand in FX3U / earlier FX**: also binary when
|
||||||
|
loaded from a D-register or a `K` constant. The older A-series CPUs had BCD
|
||||||
|
presets on some timer types, but MELSEC-Q, L, iQ-R, iQ-F, and FX3U all use
|
||||||
|
binary presets by default [17].
|
||||||
|
- The FX3U programming manual dedicates `FNC 18 BCD` and `FNC 19 BIN` to
|
||||||
|
explicit conversion — their existence confirms that anything in D-registers
|
||||||
|
that came from a `BCD` instruction output is BCD, but nothing is BCD by
|
||||||
|
default [17].
|
||||||
|
- **7-segment display registers** are a common site-specific exception — many
|
||||||
|
ladders pack `BCD D100` into a D-register so the operator panel can drive
|
||||||
|
a display directly. Our driver should not assume; expose a per-tag
|
||||||
|
"encoding = binary | BCD" knob.
|
||||||
|
|
||||||
|
Test names:
|
||||||
|
`Mitsubishi_D_register_stores_binary_not_BCD`,
|
||||||
|
`Mitsubishi_FX3U_timer_current_value_is_binary`.
|
||||||
|
|
||||||
|
## Max registers per request
|
||||||
|
|
||||||
|
From the FX5 MODBUS Communication manual Chapter 11 [11]:
|
||||||
|
|
||||||
|
| FC | Name | FX5U (built-in) | QJ71MT91 | iQ-R (RJ71EN71 / built-in) | FX3U-ENET |
|
||||||
|
|----|----------------------------|-----------------|--------------|-----------------------------|-----------|
|
||||||
|
| 01 | Read Coils | 1-2000 | 1-2000 [9] | 1-2000 [8] | 1-2000 |
|
||||||
|
| 02 | Read Discrete Inputs | 1-2000 | 1-2000 | 1-2000 | 1-2000 |
|
||||||
|
| 03 | Read Holding Registers | **1-125** | 1-125 [9] | 1-125 [8] | 1-125 |
|
||||||
|
| 04 | Read Input Registers | 1-125 | 1-125 | 1-125 | 1-125 |
|
||||||
|
| 05 | Write Single Coil | 1 | 1 | 1 | 1 |
|
||||||
|
| 06 | Write Single Register | 1 | 1 | 1 | 1 |
|
||||||
|
| 0F | Write Multiple Coils | 1-1968 | 1-1968 | 1-1968 | 1-1968 |
|
||||||
|
| 10 | Write Multiple Registers | **1-123** | 1-123 | 1-123 | 1-123 |
|
||||||
|
| 16 | Mask Write Register | 1 | not supported | 1 | not supported |
|
||||||
|
| 17 | Read/Write Multiple Regs | R:1-125, W:1-121 | not supported | R:1-125, W:1-121 | not supported |
|
||||||
|
|
||||||
|
- **The FX5U / iQ-R native-port limits match the Modbus spec**: 125 for FC03/04,
|
||||||
|
123 for FC16 [11]. No sub-spec caps like DL260's 100-register ceiling.
|
||||||
|
- **QJ71MT91 does not support FC16 (0x16, Mask Write Register) or FC17
|
||||||
|
(0x17, Read/Write Multiple)** — requesting them returns exception `01`
|
||||||
|
Illegal Function [9]. FX5U and iQ-R *do* support both.
|
||||||
|
- **QJ71MT91 device size**: 64k points (65,536) for each of Coil / Input /
|
||||||
|
Input Register / Holding Register, plus up to 4086k points for Extended
|
||||||
|
File Register via a secondary assignment range [9].
|
||||||
|
- **FX3U-ENET / -P502 function code list is a strict subset** of the common
|
||||||
|
eight (FC01/02/03/04/05/06/0F/10). FC16 and FC17 not supported [4].
|
||||||
|
|
||||||
|
Test names:
|
||||||
|
`Mitsubishi_FX5U_FC03_126_registers_returns_IllegalDataValue`,
|
||||||
|
`Mitsubishi_FX5U_FC16_124_registers_returns_IllegalDataValue`,
|
||||||
|
`Mitsubishi_QJ71MT91_FC16_MaskWrite_returns_IllegalFunction`,
|
||||||
|
`Mitsubishi_QJ71MT91_FC23_ReadWrite_returns_IllegalFunction`.
|
||||||
|
|
||||||
|
## Exception codes
|
||||||
|
|
||||||
|
MELSEC MODBUS modules return **only the standard Modbus exception codes 01-04**;
|
||||||
|
no proprietary exception codes are exposed on the wire [8][9][11]. Module-
|
||||||
|
internal diagnostics (buffer-memory error codes like `7380H`) are logged but
|
||||||
|
not returned as Modbus exceptions.
|
||||||
|
|
||||||
|
| Code | Name | MELSEC trigger |
|
||||||
|
|------|----------------------|---------------------------------------------------------|
|
||||||
|
| 01 | Illegal Function | FC17 or FC16 on QJ71MT91/FX3U; FC08 (Diagnostics); FC43 |
|
||||||
|
| 02 | Illegal Data Address | Modbus address outside any assignment range |
|
||||||
|
| 03 | Illegal Data Value | Quantity out of per-FC range (see table above); odd coil-byte count |
|
||||||
|
| 04 | Server Device Failure | See below |
|
||||||
|
|
||||||
|
- **04 (Server Failure) triggers on MELSEC**:
|
||||||
|
- CPU in STOP or PAUSE during a write to an assignment whose "Access from
|
||||||
|
External Device" permission is set to "Disabled in STOP" [9][11].
|
||||||
|
*With the default "always enabled" setting the write succeeds in STOP
|
||||||
|
mode* — another common trap.
|
||||||
|
- CPU errors (parameter error, watchdog) during any access.
|
||||||
|
- Assignment points to a device range that is not configured (e.g. write
|
||||||
|
to `D16384` when CPU D-device size is 12288).
|
||||||
|
- **Write to a "System Area" device** (e.g., `SD` special registers that are
|
||||||
|
CPU-reserved read-only) returns `04`, not `02`, on QJ71MT91 and iQ-R — the
|
||||||
|
assignment is valid, the device exists, but the CPU rejects the write [8][9].
|
||||||
|
- **FX3U-ENET / -P502** returns `04` on any write attempt while the CPU is in
|
||||||
|
STOP, regardless of permission settings — the older firmware does not
|
||||||
|
implement the "Access from External Device" granularity that Q/L/iQ-R/iQ-F
|
||||||
|
expose [4].
|
||||||
|
- **No rumour of proprietary codes 05-0B** from MELSEC; operators sometimes
|
||||||
|
report "exception 0A" but those traces all came from a third-party gateway
|
||||||
|
sitting between the master and the MELSEC module.
|
||||||
|
|
||||||
|
Test names:
|
||||||
|
`Mitsubishi_QJ71MT91_STOP_mode_write_with_Disabled_permission_returns_ServerFailure`,
|
||||||
|
`Mitsubishi_QJ71MT91_STOP_mode_write_with_default_permission_succeeds`,
|
||||||
|
`Mitsubishi_SD_system_register_write_returns_ServerFailure`,
|
||||||
|
`Mitsubishi_FX3U_STOP_mode_write_always_returns_ServerFailure`.
|
||||||
|
|
||||||
|
## Connection behavior
|
||||||
|
|
||||||
|
Max simultaneous Modbus TCP clients, per module [7][8][9][11]:
|
||||||
|
|
||||||
|
| Model | Max TCP connections | Port 502 | Keepalive | Source |
|
||||||
|
|----------------------|---------------------|----------|-----------|--------|
|
||||||
|
| `QJ71MT91` | 16 (shared with master role) | Yes | No | [9] |
|
||||||
|
| `LJ71MT91` | 16 | Yes | No | [10] |
|
||||||
|
| iQ-R built-in / `RJ71EN71` | 16 | Yes | Configurable (KeepAlive = ON in parameter) | [8] |
|
||||||
|
| iQ-F `FX5U` built-in | 8 | Yes | Configurable | [7][11] |
|
||||||
|
| `FX3U-ENET` | 8 TCP, but **not port 502** | No (port < 1024 blocked) | No | [4][5] |
|
||||||
|
| `FX3U-ENET-P502` | 8, port 502 enabled | Yes | No | [5] |
|
||||||
|
|
||||||
|
- **QJ71MT91's 16 is total connections shared between slave-listen and
|
||||||
|
master-initiated sockets** [9]. A site that uses the same module as both
|
||||||
|
master to downstream VFDs and slave to upstream SCADA splits the 16 pool.
|
||||||
|
- **FX3U-ENET port-502 gotcha**: if the engineer loads a configuration with
|
||||||
|
port 502 into a non-P502 ENET module, GX Works shows the download as
|
||||||
|
successful; on next power cycle the module enters error state and the
|
||||||
|
MODBUS listener never starts. This is documented on third-party FX3G
|
||||||
|
integration guides [6].
|
||||||
|
- **CPU STOP → RUN transition**: does **not** drop Modbus connections on any
|
||||||
|
MELSEC family. Existing sockets stay open; outstanding requests during the
|
||||||
|
transition may see exception 04 for a few scans but then resume [8][9].
|
||||||
|
- **CPU reset (power cycle or `SM1255` forced reset)** drops all Modbus
|
||||||
|
connections and the module re-listens after typically 5-10 seconds.
|
||||||
|
- **Idle timeout**: QJ71MT91 and iQ-R have a per-connection "Alive-Check"
|
||||||
|
(idle timer) parameter, default 0 (disabled). If enabled, default 10 s
|
||||||
|
probe interval, 3 retries before close [8][9]. FX5U similar defaults.
|
||||||
|
- **Keep-alive (TCP-level)**: only iQ-R / iQ-F expose a TCP keep-alive option
|
||||||
|
(parameter "KeepAlive" in the Ethernet settings); QJ71MT91 and FX3U-ENET
|
||||||
|
do not — so NAT/firewall idle drops require driver-side pinging.
|
||||||
|
|
||||||
|
Test names:
|
||||||
|
`Mitsubishi_QJ71MT91_17th_connection_refused`,
|
||||||
|
`Mitsubishi_FX5U_9th_connection_refused`,
|
||||||
|
`Mitsubishi_STOP_to_RUN_transition_preserves_socket`,
|
||||||
|
`Mitsubishi_CPU_reset_closes_all_sockets`.
|
||||||
|
|
||||||
|
## Behavioral oddities
|
||||||
|
|
||||||
|
- **Transaction ID echo**: QJ71MT91 and iQ-R reliably echo the MBAP TxId on
|
||||||
|
every response across firmware revisions; no reports of TxId drops under
|
||||||
|
load [8][9]. FX3U-ENET has an older, less-tested TCP stack; at least one
|
||||||
|
MrPLC thread reports out-of-order TxId echoes under heavy polling on
|
||||||
|
firmware < 1.14 [4]. _Unconfirmed_ on current firmware.
|
||||||
|
- **Per-connection request serialization**: all MELSEC slaves serialize
|
||||||
|
requests within a single TCP connection — a new request is not processed
|
||||||
|
until the prior response has been sent. Pipelining multiple requests on one
|
||||||
|
socket causes the module to queue them in buffer memory and respond in
|
||||||
|
order, but **the queue depth is 1** on QJ71MT91 (a second in-flight request
|
||||||
|
is held on the TCP receive buffer, not queued) [9]. Driver should treat
|
||||||
|
Mitsubishi slaves as strictly single-flight per socket.
|
||||||
|
- **Partial-frame handling**: QJ71MT91 and iQ-R close the socket on malformed
|
||||||
|
MBAP length fields. FX5U resynchronises at the next valid MBAP header
|
||||||
|
within 100 ms but will emit an error to `SD` diagnostics [11]. Driver must
|
||||||
|
reconnect on half-close and replay.
|
||||||
|
- **FX3U UDP vs TCP**: `FX3U-ENET` supports both UDP and TCP MODBUS transports;
|
||||||
|
UDP is lossy and reorders under load. Default is TCP. Some legacy SCADA
|
||||||
|
configurations pinned the module to UDP for multicast discovery — do not
|
||||||
|
select UDP unless the site requires it [4].
|
||||||
|
- **Known firmware-revision variants**:
|
||||||
|
- QJ71MT91 ≤ firmware 10052000000 (year-month format): FC15 with coil
|
||||||
|
count that forces byte-count to an odd value silently truncates the
|
||||||
|
last coil. Fixed in later revisions [9]. _Operator-reported_.
|
||||||
|
- FX5U firmware < 1.060: no native MODBUS TCP server — only accessible via
|
||||||
|
a predefined-protocol function block hack. Firmware ≥ 1.060 ships
|
||||||
|
parameter-based server. Our capability probe should read `SD203`
|
||||||
|
(firmware version) and flag < 1.060 as unsupported for server mode [11][12].
|
||||||
|
- iQ-R RJ71EN71 early firmware: possible ABCD word order (rumoured,
|
||||||
|
unconfirmed) [8].
|
||||||
|
- **SD (special-register) reads during assignment-parameter load**: while
|
||||||
|
the CPU is loading a new MODBUS device assignment parameter (~1-2 s), the
|
||||||
|
slave returns exception 04 Server Failure on every request. Happens after
|
||||||
|
a parameter write from GX Configurator-MB [9].
|
||||||
|
- **iQ-R "Station-based block transfer" collision**: if the RJ71EN71 is also
|
||||||
|
running CC-Link IE Control on the same module, a MODBUS/TCP request that
|
||||||
|
arrives during a CCIE cyclic period is delayed to the next scan — visible
|
||||||
|
as jittery response time, not a failure [8].
|
||||||
|
|
||||||
|
Test names:
|
||||||
|
`Mitsubishi_QJ71MT91_single_flight_per_socket`,
|
||||||
|
`Mitsubishi_FX5U_malformed_MBAP_resync_within_100ms`,
|
||||||
|
`Mitsubishi_FX3U_TxId_preserved_across_burst`,
|
||||||
|
`Mitsubishi_FX5U_firmware_below_1_060_reports_no_server_mode`.
|
||||||
|
|
||||||
|
## Model-specific differences for test coverage
|
||||||
|
|
||||||
|
Summary of which quirks differ per model, so test-class naming can reflect them:
|
||||||
|
|
||||||
|
| Quirk | QJ71MT91 | LJ71MT91 | iQ-R (RJ71EN71 / built-in) | iQ-F (FX5U) | FX3U-ENET(-P502) |
|
||||||
|
|------------------------------------------|----------|----------|----------------------------|-------------|------------------|
|
||||||
|
| FC16 Mask-Write supported | No | No | Yes | Yes | No |
|
||||||
|
| FC17 Read/Write Multiple supported | No | No | Yes | Yes | No |
|
||||||
|
| Max connections | 16 | 16 | 16 | 8 | 8 |
|
||||||
|
| X/Y numbering base | hex | hex | hex | octal (default) | octal |
|
||||||
|
| 32-bit word order | CDAB | CDAB | CDAB (firmware-dependent rumour of ABCD) | CDAB | CDAB |
|
||||||
|
| Port 502 supported | Yes | Yes | Yes | Yes | P502 only |
|
||||||
|
| STOP-mode write permission configurable | Yes | Yes | Yes | Yes | No (always blocks) |
|
||||||
|
| TCP keep-alive parameter | No | No | Yes | Yes | No |
|
||||||
|
| Modbus device assignment — max entries | 16 | 16 | 16 | 16 | 8 |
|
||||||
|
| Server via parameter (no FB) | Yes | Yes | Yes | Yes (fw ≥ 1.060) | Yes |
|
||||||
|
|
||||||
|
- **Test file layout**: `Mitsubishi_QJ71MT91_*`, `Mitsubishi_LJ71MT91_*`,
|
||||||
|
`Mitsubishi_iQR_*`, `Mitsubishi_FX5U_*`, `Mitsubishi_FX3U_ENET_*`,
|
||||||
|
`Mitsubishi_FX3U_ENET_P502_*`. iQ-R built-in Ethernet and the RJ71EN71
|
||||||
|
behave identically for MODBUS/TCP slave purposes and can share a file
|
||||||
|
`Mitsubishi_iQR_*`.
|
||||||
|
- **Cross-model shared tests** (word order CDAB, binary not BCD, standard
|
||||||
|
exception codes, 125-register FC03 cap) can live in a single
|
||||||
|
`Mitsubishi_Common_*` fixture.
|
||||||
|
|
||||||
|
## References
|
||||||
|
|
||||||
|
1. Mitsubishi Electric, *MODBUS Interface Module User's Manual — QJ71MB91*
|
||||||
|
(SH-080578ENG), RS-232/422/485 MODBUS RTU serial module for MELSEC-Q —
|
||||||
|
https://dl.mitsubishielectric.com/dl/fa/document/manual/plc/sh080578eng/sh080578engk.pdf
|
||||||
|
2. Inductive Automation, *Ignition Modbus Driver — Mitsubishi Q / iQ-R word
|
||||||
|
order*, documents CDAB convention —
|
||||||
|
https://docs.inductiveautomation.com/docs/8.1/ignition-modules/opc-ua/drivers/modbus-v2
|
||||||
|
and forum discussion https://forum.inductiveautomation.com/t/modbus-tcp-device-word-byte-order/65984
|
||||||
|
3. Mitsubishi Electric, *Programmable Controller User's Manual QJ71MB91 MODBUS
|
||||||
|
Interface Module*, Chapter 7 "Parameter Setting" describing the Modbus
|
||||||
|
Device Assignment Parameter block (assignments 1-16, head-device
|
||||||
|
configuration) —
|
||||||
|
https://www.lcautomation.com/dbdocument/29156/QJ71MB91%20Users%20manual.pdf
|
||||||
|
4. Mitsubishi Electric, *FX3U-ENET User's Manual* (JY997D18101), Chapter on
|
||||||
|
MODBUS/TCP communication; function code support and connection limits —
|
||||||
|
https://dl.mitsubishielectric.com/dl/fa/document/manual/plc_fx/jy997d18101/jy997d18101h.pdf
|
||||||
|
5. Venus Automation, *Mitsubishi FX3U-ENET-P502 Module — Open Port 502 for
|
||||||
|
Modbus TCP/IP* —
|
||||||
|
https://venusautomation.com.au/mitsubishi-fx3u-enet-p502-module-open-port-502-for-modbus-tcp-ip/
|
||||||
|
and FX3U-ENET-ADP user manual (JY997D45801), which confirms the -ADP
|
||||||
|
variant does not support MODBUS —
|
||||||
|
https://dl.mitsubishielectric.com/dl/fa/document/manual/plc_fx/jy997d45801/jy997d45801h.pdf
|
||||||
|
6. XML Control / Ubidots integration notes, *FX3G Modbus* — port-502 trap,
|
||||||
|
D-register mapping default, word order reference —
|
||||||
|
https://sites.google.com/site/xmlcontrol/archive/fx3g-modbus
|
||||||
|
and https://ubidots.com/blog/mitsubishi-plc-as-modbus-tcp-server/
|
||||||
|
7. FA Support Me, *Modbus TCP on Built-in Ethernet port in iQ-F and iQ-R* —
|
||||||
|
confirms 16-connection limit on iQ-R, 8 on iQ-F, parameter-driven
|
||||||
|
configuration via GX Works3 —
|
||||||
|
https://www.fasupportme.com/portal/en/kb/articles/modbus-tcp-on-build-in-ethernet-port-in-iq-f-and-iq-r-en
|
||||||
|
8. Mitsubishi Electric, *MELSEC iQ-R Ethernet User's Manual (Application)*
|
||||||
|
(SH-081259ENG) and *MELSEC iQ-RJ71EN71 User's Manual* Chapter on
|
||||||
|
"Communications Using Modbus/TCP" —
|
||||||
|
https://www.allied-automation.com/wp-content/uploads/2015/02/MITSUBISHI_manual_plc_iq-r_ethernet_users.pdf
|
||||||
|
and https://www.manualslib.com/manual/1533351/Mitsubishi-Electric-Melsec-Iq-Rj71en71.html?page=109
|
||||||
|
9. Mitsubishi Electric, *MODBUS/TCP Interface Module User's Manual — QJ71MT91*
|
||||||
|
(SH-080446ENG), exception codes page 248, device assignment parameter
|
||||||
|
pages 116-124, duplicate-assignment-disables-slave note —
|
||||||
|
https://dl.mitsubishielectric.com/dl/fa/document/manual/plc/sh080446eng/sh080446engj.pdf
|
||||||
|
10. Mitsubishi Electric, *MELSEC-L Network Features* — LJ71MT91 documented as
|
||||||
|
L-series equivalent of QJ71MT91 with identical MODBUS/TCP behavior —
|
||||||
|
https://us.mitsubishielectric.com/fa/en/products/cnt/programmable-controllers/melsec-l-series/network/features/
|
||||||
|
11. Mitsubishi Electric, *MELSEC iQ-F FX5 User's Manual (MODBUS Communication)*
|
||||||
|
(JY997D56101), Chapter 11 "Modbus/TCP Communication Specifications" —
|
||||||
|
function code max-quantity table, frame specification, device assignment
|
||||||
|
defaults —
|
||||||
|
https://dl.mitsubishielectric.com/dl/fa/document/manual/plcf/jy997d56101/jy997d56101h.pdf
|
||||||
|
12. MrPLC forum, *FX5U Modbus-TCP Server (Slave)*, firmware ≥ 1.60 enables
|
||||||
|
native server via parameter; earlier firmware required function block —
|
||||||
|
https://mrplc.com/forums/topic/31883-fx5u-modbus-tcp-server-slave/
|
||||||
|
and Industrial Monitor Direct's "FX5U MODBUS TCP Server Workaround"
|
||||||
|
article (reflects older firmware behavior) —
|
||||||
|
https://industrialmonitordirect.com/blogs/knowledgebase/mitsubishi-fx5u-modbus-tcp-server-configuration-workaround
|
||||||
|
13. Mitsubishi Electric, *MELSEC iQ-R MODBUS and MODBUS/TCP Reference Manual —
|
||||||
|
RJ71C24 / RJ71C24-R2* (BCN-P5999-1060) — RJ71C24 is serial RTU only,
|
||||||
|
not TCP —
|
||||||
|
https://dl.mitsubishielectric.com/dl/fa/document/manual/plc/bcn-p5999-1060/bcnp59991060b.pdf
|
||||||
|
14. HMS Industrial Networks, *eWON and Mitsubishi FX5U PLC* (KB-0264-00) —
|
||||||
|
documents that FX5U X/Y are octal in GX Works3 but hex when viewed as a
|
||||||
|
Q-series PLC through eWON; the project-level hex/octal toggle —
|
||||||
|
https://hmsnetworks.blob.core.windows.net/www/docs/librariesprovider10/downloads-monitored/manuals/knowledge-base/kb-0264-00-en-ewon-and-mitsubishi-fx5u-plc.pdf
|
||||||
|
15. Fernhill Software, *Mitsubishi Melsec PLC Data Address* — documents
|
||||||
|
hex-vs-octal device numbering split across MELSEC families —
|
||||||
|
https://www.fernhillsoftware.com/help/drivers/mitsubishi-melsec/data-address-format.html
|
||||||
|
16. Inductive Automation support, *Understanding Mitsubishi PLCs* — D registers
|
||||||
|
store signed 16-bit binary, not BCD; DINT combines two consecutive D
|
||||||
|
registers —
|
||||||
|
https://support.inductiveautomation.com/hc/en-us/articles/16517576753165-Understanding-Mitsubishi-PLCs
|
||||||
|
17. Mitsubishi Electric, *FXCPU Structured Programming Manual [Device &
|
||||||
|
Common]* (JY997D26001) — FNC 18 BCD and FNC 19 BIN explicit-conversion
|
||||||
|
instructions confirm binary-by-default storage —
|
||||||
|
https://dl.mitsubishielectric.com/dl/fa/document/manual/plc_fx/jy997d26001/jy997d26001l.pdf
|
||||||
Reference in New Issue
Block a user