Resolving Siemens MB_CLIENT Error 80C5 with a Modbus TCP Slave Simulator (ModRSsim2 / Modbus Poll)
Symptom. TIA Portal V15.1 project on S7-1200/S7-1500 calls MB_CLIENT against a Modbus TCP slave simulator (ModRSsim2, Modbus Poll in slave mode, or similar) and the instance DB status word reports 16#80C5 ("Modbus communication failure" / "no remote partner"). Status words 16#7001 and 16#7002 may also appear in the same scan cycle. No holding/input register values are written to the configured tags.
This reference walks through the exact commissioning sequence that eliminates 80C5, explains what each status word means, and documents the IP, port 502, and instance-DB parameters that are commonly mis-configured when a Siemens CPU is the Modbus TCP client and a third-party PC application is the Modbus TCP server.
1. Required Toolchain and Software Versions
| Component | Minimum Version | Notes |
|---|---|---|
| SIMATIC STEP 7 (TIA Portal) | V15.1 (or V15.0 / V16 / V17 with same MB_CLIENT block) | Project used in source case is V15.1 |
| S7-1200 / S7-1500 firmware | V4.2 (S7-1200) / V2.0 (S7-1500) | MB_CLIENT requires ≥ V4.2 on S7-1200 and ≥ V2.0 on S7-1500 |
| ModRSsim2 (Modbus TCP slave) | Build 1660 or later | Default port 502, listens on 0.0.0.0 |
| Modbus Poll (master test tool) | V7.x or later | Used to validate simulator is reachable |
| PLCSIM / S7-PLCSIM (optional) | V15.1 | PLCSIM behaves like a real CPU on the same subnet |
| Windows firewall | Allow ModRSsim2 / Modbus Poll inbound on TCP/502 | Default Windows profile blocks 502 |
ModRSsim2 is published on SourceForge (ModRSsim2 download page) and exposes both Modbus RTU and Modbus TCP/IP server functions on the standard port 502.
2. Understanding the MB_CLIENT STATUS Output
The MB_CLIENT instruction writes the following tags in the instance DB:
-
STATUS– 16-bit WORD, hex status of the TCP/Modbus transaction. -
MB_STATUS– 16-bit WORD, Modbus-protocol-level exception code. -
MB_DATA_PTR– ANY pointer to the data buffer for read/write transactions. -
DONE,BUSY,ERROR– Boolean handshake flags.
| STATUS (hex) | Meaning (per S7-1200 / S7-1500 system manual) | What to check |
|---|---|---|
| 16#0000 | No error | Transaction complete |
| 16#7001 | Job processing – connection establishment | First call; CPU is opening TCP socket |
| 16#7002 | Job processing – connection established, read/write in progress | TCP link is up, request is in flight |
| 16#7003 | Connection terminated by DISCONNECT input |
Normal close after each cycle |
| 16#7004 | Internal error – instance DB inconsistency | Re-compile the DB and download again |
| 16#80C1 | All other connection errors (Winsock) | Wrong port, firewall, simulator not running |
| 16#80C2 | Modbus data address error (exception 02) | Register address out of range in slave |
| 16#80C3 | Modbus data length / value error (exception 03 / 04) | Wrong quantity or unsupported function |
| 16#80C4 | Connection terminated / TCP error | Slave crashed mid-cycle, network drop |
| 16#80C5 | Remote partner not available / no remote partner | Wrong IP, wrong port, firewall, PLC and PC not in same subnet, simulator in wrong role (master vs slave) |
3. Root-Cause Matrix for 80C5
| # | Probable cause | Diagnostic | Fix |
|---|---|---|---|
| R1 | PC IP address entered in CONNECT parameter does not match the actual IPv4 of the Windows host running ModRSsim2 |
ipconfig /all on PC; cross-check the value entered in TIA Portal |
Use a static IP, write it into the instance DB |
| R2 | S7 CPU and PC are on different subnets (e.g. 192.168.0.x vs 192.168.1.x) with no router | From PC: ping <PLC_IP>
|
Reconfigure one side so both share the same /24 subnet, or add a static route |
| R3 | ModRSsim2 is set to "Protocol = Modbus RTU" or the wrong unit ID | ModRSsim2 Connection menu → TCP/IP server | Select TCP/IP Server, port 502, Unit ID 1 (or 255 for Siemens) |
| R4 | ModRSsim2 is bound to a specific IP and the PLC is talking to the loopback (127.0.0.1) | ModRSsim2 → File → Settings → Network Interface | Set "Listen on all interfaces" or the wired NIC IPv4 |
| R5 | Windows Defender Firewall blocks inbound TCP/502 to ModRSsim2.exe | From a second PC: Test-NetConnection <PC_IP> -Port 502
|
Add inbound rule for ModRSsim2 on TCP/502, or temporarily disable the firewall for the lab subnet |
| R6 | MB_CLIENT CONNECT parameter has ActiveEstablished = TRUE but the slave is on a port other than 502 |
ModRSsim2 → Connection → Display Port | Set port in the TIA Portal instance DB to match (default 502 = standard Modbus TCP port) |
| R7 | Active/Established direction is wrong: the CPU is trying to "listen" while the simulator is also a server | STATUS = 16#80C1 instead of 16#80C5 | Set ActiveEstablished = TRUE for client/master role |
| R8 | Anti-virus or VPN client on the PC is intercepting loopback / non-routable packets | Wireshark on the PC NIC shows SYN but no SYN-ACK | Disable VPN, exclude ModRSsim2 from AV inspection |
| R9 | Older S7-1200 firmware < V4.2 lacks MB_CLIENT
|
Online → Diagnostic → Module Information → Firmware | Update firmware to V4.2 or later |
| R10 | PLCSIM instance is in a different PLCSIM virtual subnet than the host NIC | From PLCSIM: Online → Accessible Nodes | Start PLCSIM with "accessible via TCP/IP from any subnet" or align the virtual NIC |
4. Prerequisites
- Windows 10/11 host with a fixed IPv4 address (e.g.
192.168.0.10/24). Disable Wi-Fi or assign a unique metric so Modbus TCP is bound to the wired NIC. - ModRSsim2 installed and verified. Test that the simulator accepts a connection by opening Modbus Poll on the same PC, configuring Connection → Modbus TCP/IP, IP = 127.0.0.1, port = 502. If Modbus Poll reads register 40001, the simulator is functional.
- S7-1200 (or PLCSIM V15.1 instance) with a fixed IPv4 in the same /24 (e.g.
192.168.0.20/24- TIA Portal V15.1 project with a
MB_CLIENTcall in OB1 (or a cyclic OB) and a single instance DB.- One unmanaged switch or a crossover cable between PC and PLC.
- TIA Portal V15.1 project with a
5. Step-by-Step Configuration
5.1 Configure ModRSsim2 as a Modbus TCP Server (Slave)
- Launch ModRSsim2. From the menu bar select Connection → Modbus/TCP IP → Modbus Server (this is the default on first launch).
- Confirm the listening port is
502. Open Settings → TCP/IP Server Port if a different value appears. - Pre-load a few registers so the MB_CLIENT transaction has a defined response. In the main grid set:
- Address 0 (40001) = 16#0001 (Function code 03 read returns 0x0001).
- Address 1 (40002) = 16#0002.
- From the Windows host, open a second
cmdwindow and runnetstat -an | findstr :502. The line0.0.0.0:502 LISTENINGconfirms the simulator is bound to all interfaces.
5.2 Configure the S7 CPU Network Interface
- In TIA Portal, open Device Configuration → PROFINET interface → Ethernet addresses.
- Set IP address = 192.168.0.20, Subnet mask = 255.255.255.0. Do not enable a router unless one is required.
- Download the hardware configuration to the CPU. Verify with Online → Accessible Nodes that the CPU is reachable from the PC.
- From the PC run
ping 192.168.0.20. A reply confirms Layer-3 reachability.
5.3 Configure the MB_CLIENT Instance DB
Drop MB_CLIENT from Instructions → Communication → Modbus TCP into OB1. TIA Portal auto-generates the instance DB (e.g. MB_CLIENT_DB). Open the DB and inspect the CONNECT parameter, which is itself a TCON_IP_V4 structure:
| CONNECT sub-field | Required value (Siemens as client / ModRSsim2 as server) |
|---|---|
| InterfaceId | 64#0AEB (PROFINET interface of the S7-1200) – or 64#0000B0A0 for older S7-1200 |
| ID | W#16#1 (any 16-bit local connection ID not used elsewhere) |
| ConnectionType | 16#0B (TCP/IP) |
| ActiveEstablished | TRUE (CPU opens the connection, i.e. client/master) |
| RemoteAddress.ADDR[1..4] | 192, 168, 0, 10 (the ModRSsim2 host) |
| RemotePort | 502 |
| LocalPort | 0 (let the OS choose) or 2000 (use 2000+ for S7-1500) |
Minimum call interface on the FC/FB block:
MB_CLIENT_DB(
REQ := %M0.0, // 1-Hz blink, triggers a transaction
DISCONNECT := FALSE, // keep the TCP connection open
CONNECT := 'MB_CLIENT_CONNECT',
MB_MODE := 0, // 0 = read, 1 = write
MB_DATA_ADDR := 40001, // Modbus address (function-code-aware)
MB_DATA_LEN := 10, // 10 holding registers
DONE => %M10.0,
BUSY => %M10.1,
ERROR => %M10.2,
STATUS => %MW12,
MB_STATUS => %MW14,
MB_DATA_PTR := P#DB20.DBX0.0 WORD 10
);
For the S7-1500 family the equivalent block is also MB_CLIENT (TIA V15.1+). For S7-300/400 the legacy FB100 / FB101 / FB102 Modbus TCP package from Siemens is used instead and the STATUS mapping differs – do not mix the two.
5.4 Watch Table for Live Diagnosis
- Create a watch table with the instance DB tags:
MB_CLIENT_DB.STATUS,MB_CLIENT_DB.MB_STATUS,MB_CLIENT_DB.BUSY,MB_CLIENT_DB.ERROR,MB_CLIENT_DB.DONE. - Trigger
REQwith a 1-Hz clock bit. Observe the state sequence:
- Pattern A (healthy): STATUS 16#7001 → 16#7002 → 16#0000, DONE=TRUE on each REQ edge.
- Pattern B (no partner): STATUS 16#7001 → 16#80C5, ERROR=TRUE, DONE=FALSE. This is the fault described in the source case.
- Pattern C (TCP socket drop): STATUS 16#7001 → 16#7002 → 16#80C4, ERROR=TRUE. Indicates slave is alive but disconnects – check simulator stability and function code.
6. Eliminating 80C5 in the Source Case (Checklist)
- Confirm the role. In the source case the S7 CPU is the Modbus TCP client/master and ModRSsim2 is the server/slave. Ensure the simulator is in Modbus Server mode, not Modbus Client – ModRSsim2 supports both.
- Match the IP address. Re-read the four octets of the PC's wired IPv4. Do not type the loopback 127.0.0.1.
- Match the subnet. PC and PLC must share the first three octets (default /24). If a 169.254.x.x APIPA address is showing, fix the link first.
-
Open Windows Firewall for TCP/502.
netsh advfirewall firewall add rule name="ModRSsim2 502" dir=in action=allow protocol=TCP localport=502(run elevated). - Force REQ to pulse. 80C5 is also reported on the first call if the connection is opened and never used. Generate a clean REQ edge at least every 1 s to keep the link active.
-
Verify with Modbus Poll. From the same PC, point Modbus Poll to
127.0.0.1:502. If Poll cannot read, the simulator is mis-configured. If Poll can read, the simulator is fine and 80C5 is on the PLC path. -
Capture a packet trace. Start Wireshark on the PC with the filter
tcp.port == 502. With the CPU connected you should see SYNs from the PLC's IP, SYN-ACKs from the PC, then Modbus ADUs. If SYNs appear with no reply, the firewall or wrong IP is the cause.
7. Verification Procedure
- Download the project to the CPU (or PLCSIM) and go online.
- Open the MB_CLIENT watch table. Toggle
REQonce with a 1-second pulse. - Confirm STATUS goes 16#7001 → 16#7002 → 16#0000, and DONE pulses TRUE.
- Confirm the target data buffer (e.g.
DB20.DBW0) contains the value that ModRSsim2 is publishing at address 40001. - Change a value in ModRSsim2 and re-trigger REQ. The buffer must update within one cycle.
- Stop ModRSsim2. The next transaction should report STATUS = 16#80C5, ERROR = TRUE. This confirms the fault path is wired correctly – if 80C5 never appears with the slave down, the diagnostic chain is broken.
- Restart ModRSsim2 and re-trigger. STATUS should return to 16#0000 on the next successful transaction.
REQ with a controlled event (operator command, scan-edge of a slow clock), not a free-running 1-Hz flag, and add a watch-dog that alarms on three consecutive 80C5 events.8. Common Pitfalls When Using ModRSsim2 with a Siemens CPU
| Pitfall | Symptom | Resolution |
|---|---|---|
| ModRSsim2 in "Modbus Master" mode (default after first use on some builds) | 80C5 immediately on first call | Connection → Modbus/TCP IP → Modbus Server |
| PLCSIM virtual NIC is on a different /24 than the host | PLCSIM can ping host, host cannot ping PLCSIM | Set PLCSIM to the host subnet or enable PLCSIM's "accessible from any subnet" option |
| Two instances of ModRSsim2 running, one holds the port | Second instance silent; first does not accept new connections | Close the older instance or change the listening port |
Using MB_DATA_ADDR = 0 on a simulator that uses 1-based addressing |
80C2 / exception 02 | Add 1 to the desired address or use the simulator's 0-based entry |
| PLC is in STOP when MB_CLIENT is called | No status change, no TCP traffic | Run the CPU; check that OB1 is the active cyclic OB |
| Port 502 already bound by another service (e.g. an OPC-UA server) | ModRSsim2 silently fails to bind |
netstat -ano | findstr :502 → identify PID → stop or reconfigure |
| Use of MB_CLIENT on S7-1200 firmware < V4.2 | Block does not appear in the library | Update firmware; Siemens Industry Online Support for HSP |
9. Alternate Roles and Cross-Simulator Setups
9.1 Siemens CPU as Modbus TCP Server (Slave)
If the role is reversed and the S7 is the Modbus TCP server/slave, use MB_SERVER in TIA Portal. The PC simulator in this case must be a Modbus TCP client/master such as Modbus Poll. The MB_SERVER block binds the CPU to port 502 and waits for an incoming connection. STATUS = 16#80C5 on the PC side is then reported as "No response from slave" and has the same root-cause set (IP, port, firewall).
9.2 Using Modbus Poll as the Slave for Re-Testing
Modbus Poll can be put in "Slave" mode through the Display → Slave Mode menu in older builds or via the "Modbus Slave" companion tool. A free Modbus slave simulator that pairs well with Modbus Poll is "Modbus Slave" by WinTech. Configuration is the same as ModRSsim2: IP = the host running the slave, port = 502, function codes 03/06/16 supported by default.
10. Field-Proven Diagnostics Flow
11. Quick-Reference Parameter Set for the Source Case
| Parameter | Value in working case | Value that produced 80C5 |
|---|---|---|
| PC IPv4 | 192.168.0.10 (wired) | 127.0.0.1 or DHCP-derived address |
| PLC IPv4 | 192.168.0.20 / 24 | 192.168.0.20 with router = 192.168.1.1 |
| ModRSsim2 mode | Modbus/TCP Server | Modbus/TCP Master |
| ModRSsim2 port | 502 | 503 (or 502 with a second instance bound) |
| MB_CLIENT ActiveEstablished | TRUE | FALSE |
| MB_CLIENT RemotePort | 502 | 0 (unset) |
| REQ | 1-Hz pulse | Constant TRUE (no edge) |
| Windows Firewall | Inbound rule for 502 | Default block |
12. Extending the Pattern to Other Siemens CPUs
The same MB_CLIENT block exists on S7-1500 in TIA Portal V15.1 and later. For S7-300 / S7-400 the legacy Modbus TCP library (FB100 "MB_CLIENT" / FB101 "MB_SERVER" / FB102 "MB_RED_CLIENT") is shipped as part of the "Modbus_TCP_CP" example project in the Siemens Industry Online Support. STATUS code mapping is similar but 80C5 is reported as 16#C085 in some legacy builds – consult the CPU-specific manual before reusing the same watch table.
13. Frequently Asked Questions
What does STATUS 16#80C5 mean on MB_CLIENT?
It means the CPU could not reach the remote Modbus partner. The TCP socket was never established, the SYN-ACK never came back, or the partner closed before the Modbus ADU was answered. The three immediate checks are: PC IPv4 matches the RemoteAddress field, port 502 is open in the Windows firewall, and ModRSsim2 is set to Modbus Server mode.
Why do I see 16#7001 and 16#7002 right before 16#80C5?
16#7001 is the "connection being established" state and 16#7002 is the "request in flight" state. Both are normal on a healthy transaction. When the remote partner never responds, the CPU times out and the status rolls into 16#80C5. Seeing the two in sequence confirms the call is being issued but the slave is unreachable.
Is port 502 mandatory for Modbus TCP?
Port 502 is the IANA-assigned standard for Modbus TCP and is the default in TIA Portal's MB_CLIENT and in ModRSsim2. It is not strictly mandatory – some labs run Modbus TCP on 5020 or 8502 to avoid conflicts – but both ends must agree. Siemens MB_CLIENT requires the local port to be ≥ 1024 if a non-standard port is used, and the remote port can be any value the slave is bound to.
Can I use PLCSIM V15.1 as the Modbus partner instead of a real CPU?
Yes. PLCSIM V15.1 can act as a Modbus TCP client/master through MB_CLIENT on the simulated PROFINET interface, with the simulator host running ModRSsim2. Ensure the PLCSIM virtual NIC is on the same subnet as the host NIC, or enable "accessible from any subnet" in PLCSIM options. 16#80C5 in PLCSIM is most often a PLCSIM-virtual-subnet mismatch.
Does the same fix apply when Modbus Poll is the slave and the S7 is the master?
Yes. Modbus Poll in slave mode (companion tool "Modbus Slave") listens on TCP/502 just like ModRSsim2. The MB_CLIENT configuration is identical: ActiveEstablished = TRUE, RemoteAddress = the Modbus Slave host, RemotePort = 502. The same root-cause matrix (R1-R10) applies.