Resolving Siemens MB_CLIENT Error 80C5 with Modbus TCP Simulator

David Krause14 min read
ModbusSiemensTroubleshooting
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

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.

Engineer field-note. In Siemens nomenclature the Modbus TCP client = Modbus master, and the Modbus TCP server = Modbus slave. The two pairs of words are interchangeable in the field, but you must use the correct role in TIA Portal. If Siemens is the client/master, the PC simulator must run as the server/slave (ModRSsim2 default). If Siemens is the server/slave, the PC simulator must run as the client/master (Modbus Poll default). Cross-wiring these roles is the single most common cause of 80C5.

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)
Key reading. 16#7001 followed by 16#7002 followed by 16#80C5 in a single transaction is the classic fingerprint of a CPU that opened the TCP socket attempt, never received a TCP SYN-ACK, and timed out. 16#80C4 is the fingerprint of a socket that was opened and then dropped mid-transaction. The two faults have different root causes and different fixes.

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

  1. 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.
  2. 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.
  3. S7-1200 (or PLCSIM V15.1 instance) with a fixed IPv4 in the same /24 (e.g. 192.168.0.20/24
  4. TIA Portal V15.1 project with a MB_CLIENT call in OB1 (or a cyclic OB) and a single instance DB.
  5. One unmanaged switch or a crossover cable between PC and PLC.

5. Step-by-Step Configuration

5.1 Configure ModRSsim2 as a Modbus TCP Server (Slave)

  1. Launch ModRSsim2. From the menu bar select Connection → Modbus/TCP IP → Modbus Server (this is the default on first launch).
  2. Confirm the listening port is 502. Open Settings → TCP/IP Server Port if a different value appears.
  3. 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.
  4. From the Windows host, open a second cmd window and run netstat -an | findstr :502. The line 0.0.0.0:502 LISTENING confirms the simulator is bound to all interfaces.

5.2 Configure the S7 CPU Network Interface

  1. In TIA Portal, open Device Configuration → PROFINET interface → Ethernet addresses.
  2. Set IP address = 192.168.0.20, Subnet mask = 255.255.255.0. Do not enable a router unless one is required.
  3. Download the hardware configuration to the CPU. Verify with Online → Accessible Nodes that the CPU is reachable from the PC.
  4. 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

  1. 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.
  2. Trigger REQ with 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)

  1. 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.
  2. Match the IP address. Re-read the four octets of the PC's wired IPv4. Do not type the loopback 127.0.0.1.
  3. 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.
  4. Open Windows Firewall for TCP/502. netsh advfirewall firewall add rule name="ModRSsim2 502" dir=in action=allow protocol=TCP localport=502 (run elevated).
  5. 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.
  6. 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.
  7. 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

  1. Download the project to the CPU (or PLCSIM) and go online.
  2. Open the MB_CLIENT watch table. Toggle REQ once with a 1-second pulse.
  3. Confirm STATUS goes 16#7001 → 16#7002 → 16#0000, and DONE pulses TRUE.
  4. Confirm the target data buffer (e.g. DB20.DBW0) contains the value that ModRSsim2 is publishing at address 40001.
  5. Change a value in ModRSsim2 and re-trigger REQ. The buffer must update within one cycle.
  6. 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.
  7. Restart ModRSsim2 and re-trigger. STATUS should return to 16#0000 on the next successful transaction.
Safety note. For production code, drive 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

MB_CLIENT call with REQ STATUS == 16#7001 ? CPU opens TCP socket STATUS == 16#7002 ? TCP up, Modbus request sent no 80C5: no remote partner check IP/port/firewall STATUS == 16#0000 ? Done = TRUE, data valid 80C2/80C3/80C4: protocol check MB_STATUS, MB_DATA_ADDR no no

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.

Back to blog