diff --git a/docs/v2/mitsubishi.md b/docs/v2/mitsubishi.md new file mode 100644 index 0000000..d40c723 --- /dev/null +++ b/docs/v2/mitsubishi.md @@ -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__`). + +## 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