Problem Overview
A common deployment pattern pairs a control-room S7-1200 acting as a Modbus TCP client with three (or more) remote S7-1200 stations acting as Modbus TCP servers. When the segment between client and servers crosses a wireless bridge (e.g. a GE/ProSoft wireless radio pair acting as a transparent Layer-2 bridge) plus an unmanaged Ethernet switch, integrators frequently report a stable symptom: the control-room PLC polls three remote servers using three independent MB_CLIENT instances, but only one or two servers ever appear to respond within the same scan window. The radios pass ping traffic cleanly, but the Modbus payload returns are dropped or delayed.
This article consolidates the field observations, Siemens official guidance on MB_CLIENT, and the underlying TCP/Modbus mechanics to give the integrator a deterministic path to a green status on every connection.
Reference Architecture
The failing topology in the source report is summarized below:
| Station | Role | PLC IP | GE Radio IP | Modbus TCP Port | Slave / Unit ID |
|---|---|---|---|---|---|
| Control Room PLC | Client (Master) | 192.168.0.100 | 192.168.0.10 | 502 | 1 |
| Remote PLC 1 | Server (Slave) | 192.168.0.110 | 192.168.0.30 | 502 | 1 |
| Remote PLC 2 | Server (Slave) | 192.168.0.120 | 192.168.0.20 | 502 | 2 |
| Remote PLC 3 | Server (Slave) | 192.168.0.130 | 192.168.0.40 | 502 | 3 |
Each remote S7-1200 runs the MB_SERVER instruction on its PROFINET port. The control-room S7-1200 calls three MB_CLIENT instances, one per remote server, in OB1. The unmanaged switch is shared between the local GE radio and the client CPU. Identical patterns fail when radios are daisy-chained or when a managed switch is replaced with an unmanaged one with insufficient buffer.
Root Cause Analysis
Four independent causes can produce the "only one or two servers respond at a time" symptom. Each must be ruled out before the system is considered healthy.
1. Insufficient Open TCP Connections on the S7-1200
Each MB_CLIENT instance opened with CONNECT = TRUE establishes a dedicated TCP connection to one server. The S7-1200 CPU (firmware V4.x and earlier) supports a finite number of open Modbus TCP connections. Each MB_CLIENT instance that requests a connect consumes one slot on both the client and the remote server CPU. When the slot pool is exhausted, further CONNECT requests are rejected with status 0x0001 or stay idle with DONE = FALSE, ERROR = TRUE, STATUS = 0x0007 (resource exhaustion). Refer to the Modbus/TCP with MB_CLIENT and MB_SERVER application document for the connection-count rules per CPU firmware.
2. MB_CLIENT Polling Collision on a Half-Duplex Wireless Bridge
When OB1 calls three MB_CLIENT instances back-to-back without any rate limiting, every PLC scan issues three Modbus request frames essentially simultaneously. The wireless bridge (GE radio in this case) is a half-duplex RF medium: only one station can transmit at a time, and the CSMA/CA back-off window in the radio firmware is typically tens of milliseconds. If two or three Modbus request/response pairs collide inside that window, only the first to win the medium completes; the others time out and are reported with STATUS = 0x80C8 (response timeout) on the next scan.
This matches the reported symptom precisely: the radio link is healthy (ping works), but the Modbus payload cannot survive a simultaneous multi-client burst.
3. MB_CLIENT Reusing a Single Instance DB Across Multiple Servers
Siemens' own example MB_CLIENT 1: Multiple requests with common TCP connection shows that a single instance DB can multiplex multiple Modbus function-code requests over one TCP connection to a single server. It is not designed to talk to multiple remote IP addresses from one instance. If all three MB_CLIENT calls reference the same instance DB while CONNECT toggles between three different REMOTE_IP values, the connection tears down and re-establishes on every scan. The visible result is identical to the symptom: only one server "works" because only one connection exists at a time.
4. Unmanaged Switch Buffer / Broadcast Storm Behavior
Replacing a managed switch with an unmanaged one is fine for low-volume Modbus TCP traffic, but some consumer-grade unmanaged switches implement very small MAC address tables and small output queues. When the radios forward ARP and Modbus frames for three remote subnets through the same 100 Mbit/s uplink, broadcast handling can dominate, and the CPU's PROFINET port may momentarily drop incoming responses. Always use an industrial-rated unmanaged switch (e.g. Siemens SCALANCE XB-005) for noisy RF-bridged segments.
Diagnostic Procedure
- Open TIA Portal and inspect every
MB_CLIENTcall site. Record the instance DB name for each call. If two or more share the same instance DB, that is a definitive root cause. Create a unique instance DB per server. - Add a watchdog tag to each
MB_CLIENTcall: latchDONErising edges into a counter and increment a "no-response" counter whenERRORrises withSTATUS = 0x80C8orSTATUS = 0x0007. Trend these counters in the watch table for 10 minutes. - Disconnect the Ethernet cable from the client PLC's PROFINET port. From a laptop on the same switch, run
ping -t 192.168.0.110,ping -t 192.168.0.120, andping -t 192.168.0.130simultaneously. If any ping shows > 5% loss while the PLC is disconnected, the wireless link itself is unstable. Re-pair the radios or replace their antennas. - Capture a Wireshark trace on the client PROFINET port using a SPAN-capable managed switch inserted between the client CPU and the radio. Filter for
tcp.port == 502and inspect Modbus function codes. Look for duplicate transaction IDs and orphaned request/response pairs (response without a matching request). - Verify the firmware version of each S7-1200 CPU against the connection-count table in the Siemens Modbus/TCP application document. S7-1200 CPUs with firmware V4.0 and below support fewer concurrent Modbus TCP connections than V4.1 and above.
Solution: Rate-Limited Polling with Independent Instance DBs
Apply the following engineering changes in order. Each step resolves one of the root causes identified above.
Step 1 — Generate a Unique Instance DB Per Server
In the MB_CLIENT call, uncheck Multi-instance and create three background DBs: MB_CLIENT_DB_1, MB_CLIENT_DB_2, MB_CLIENT_DB_3. Each DB stores its own TCP connection state and must never be reused for a different remote IP. See the MB_CLIENT instruction reference for the full parameter list.
Step 2 — Stagger REQ Pulses with Clock Bits
The MB_CLIENT instruction is edge-triggered on REQ. Issuing REQ = TRUE on every OB1 cycle is the fastest possible poll rate, which is exactly what causes the wireless collision. Replace the raw REQ with clock bits derived from the CPU's on-board clock memory (System Clock Bits in TIA Portal under PLC properties):
| Clock Bit | Period | Duty Cycle | Use |
|---|---|---|---|
| M10.0 | 1.0 s | 50% | MB_CLIENT instance 1 REQ |
| M10.1 | 1.0 s | 50% | MB_CLIENT instance 2 REQ |
| M10.2 | 1.0 s | 50% |
The clock bits above are in phase, which is still problematic. Force a phase offset using a TON timer block on each clock bit:
// FC_Poller_Remote1
"TON_DB_1"(IN := M10.0, PT := T#300ms); // delay instance 1
// FC_Poller_Remote2
"TON_DB_2"(IN := M10.1, PT := T#600ms); // delay instance 2
// FC_Poller_Remote3
"TON_DB_3"(IN := M10.2, PT := T#900ms); // delay instance 3
"MB_CLIENT_DB_1"(REQ := "TON_DB_1".Q, ...);
"MB_CLIENT_DB_2"(REQ := "TON_DB_2".Q, ...);
"MB_CLIENT_DB_3"(REQ := "TON_DB_3".Q, ...);
This separates the Modbus requests in time and gives the wireless bridge a clean RF window for each response. The PT values should be tuned to the round-trip time observed in the Wireshark trace from Step 4 of the diagnostic procedure.
Step 3 — Split Polling Across a Cyclic OB
If staggered clock bits are insufficient, move the MB_CLIENT calls out of OB1 (1 ms cyclic) into a slower cyclic interrupt OB, for example OB30 with a 100 ms cycle time. In that OB, use a small state machine that calls one MB_CLIENT instance per cycle. The total round-robin period for three servers is then 300 ms, well within the 1 s clock-bit window above. This is the same pattern Siemens recommends in its multi-server examples.
Step 4 — Confirm Connection Parameter Set Correctly
For each instance, verify:
-
CONNECTis set as a latch on the first OB1 scan (use a startup flag or a first-cycle bit) so the connection stays open permanently. -
REMOTE_IPADDR[1..4]holds the correct IP octets for each remote server. SetREMOTE_IPADDR[1] = 192,[2] = 168,[3] = 0,[4] = 110for instance 1, and so on. -
UNIT_IDmatches the slave ID of the remoteMB_SERVERinstance. The client sendsUNIT_ID = 1for remote 1,2for remote 2,3for remote 3. The control-room PLC's ownUNIT_IDis irrelevant because the control-room CPU is not runningMB_SERVER; if it is runningMB_SERVERfor a local HMI panel, give it a unique unit ID to avoid echo. -
MB_MODEandMB_DATA_ADDRmatch the server's holding register map exactly.
Refer to the MB_CLIENT instruction reference for the full parameter table.
Step 5 — Manage Connection Lifecycle
If any server is brought down for maintenance, set CONNECT = FALSE on that instance only. The other instances must continue operating. Do not toggle CONNECT on every scan; that creates a TCP teardown storm that confuses the radio link and the server CPU.
Time-of-Day Scheduling (Optional Improvement)
For sites where the round-robin pattern still produces occasional collisions (e.g. three radios chained through repeaters), schedule the remote servers to push data into the control-room PLC only in assigned time windows. The technique described in the field discussion uses time-of-day to gate transmission:
| Server | Sends When System Time Tenths = | Reserved RF Window |
|---|---|---|
| Remote PLC 1 | 0.1 s | 300 ms |
| Remote PLC 2 | 0.4 s | 300 ms |
| Remote PLC 3 | 0.7 s | 300 ms |
Each remote CPU syncs its time-of-day from the control-room CPU periodically (e.g. once per hour), then schedules its MB_SERVER-side data write to the Modbus buffer only inside its window. This eliminates the contention entirely at the cost of latency. It is a robust technique when the radio medium is shared with other equipment (SCADA, video) that cannot be controlled by the integrator.
Verification Procedure
- Build and download the project to the control-room PLC. Force the system clock to a known value and observe
MB_CLIENT_DB_1.DONE,MB_CLIENT_DB_2.DONE, andMB_CLIENT_DB_3.DONEin the watch table. - Confirm that each
DONErising edge occurs within its expected time window and thatSTATUS = 0for each. Capture 1000 cycles of data; verify < 0.1% error rate. - Run a continuous Wireshark trace for 5 minutes and count Modbus transactions. The number of requests should equal the number of responses for each remote IP.
- Disconnect a remote PLC's Ethernet cable. The corresponding
MB_CLIENTinstance should reportERROR = TRUEwithSTATUS = 0x80C8within the next poll cycle, while the other two instances continue to update normally. This proves that the failure is contained per server and not a global resource exhaustion. - Reconnect the cable. The error should clear on the next request and
DONEshould resume toggling.
Status Code Reference
| STATUS (hex) | Meaning | Likely Cause | Remediation |
|---|---|---|---|
| 0x0000 | No error | Normal operation | — |
| 0x0001 | Connection refused or invalid parameters | Wrong IP, port, or CONNECT toggling |
Verify IP/port; latch CONNECT
|
| 0x0007 | Resource exhaustion | Too many open Modbus connections for CPU firmware | Upgrade firmware or reduce concurrent instances |
| 0x80C8 | Response timeout | Server did not respond within timeout window | Stagger requests; check radio link; check MB_DATA_ADDR
|
| 0x80D1 | TCP connection error | Server CPU refused or reset the connection | Check MB_SERVER instance on remote CPU |
| 0x80D2 | TCP connection closed | Remote PLC went to STOP or lost link | Verify remote CPU is in RUN |
| 0x8380 | Invalid unit ID | Unit ID mismatch between client call and MB_SERVER
|
Match UNIT_ID on both sides |
Connection Count by Firmware
| S7-1200 CPU | Firmware | Max Concurrent Modbus TCP Connections (Client + Server) |
|---|---|---|
| CPU 1211C / 1212C / 1214C / 1215C | V4.0 | 8 (combined) |
| CPU 1211C / 1212C / 1214C / 1215C | V4.1 / V4.2 | 16 (combined) |
| CPU 1217C | V4.2 | 32 (combined) |
| CPU 1212FC / 1214FC / 1215FC | V4.2 | 16 (combined) |
The figures above are taken from the Modbus/TCP with MB_CLIENT and MB_SERVER application document on the Siemens Industry Online Support portal. Always verify against the firmware release notes for the exact CPU ordering number in use, because the connection budget is shared between all PROFINET communication, including S7 communication and open user communication.
Common Field Mistakes
- Calling three
MB_CLIENTinstances with the same instance DB. Each remote server requires its own instance DB. - Driving
REQfrom the same bit on every OB1 scan. The CPU cycles OB1 in single-digit milliseconds, far faster than the radio's CSMA/CA back-off can resolve. Always rate-limitREQ. - Setting the unit ID on the client to the slave ID of the remote server, then leaving the control-room CPU's own
MB_SERVERunit ID at 1. TwoMB_SERVERinstances on the same client CPU with the same unit ID will collide. - Forgetting to enable
System Clock Bitsin PLC properties. Without clock memory, the TON-based staggering trick does not work because there is no periodic edge to feed it. - Using a wireless bridge whose bridge mode forces 10 Mbit/s half-duplex. The PROFINET port negotiates with the bridge and may drop incoming responses if the bridge's flow control is misconfigured. Lock the radio port to 10 Mbit/s full-duplex if supported.
Frequently Asked Questions
How many concurrent Modbus TCP connections can one S7-1200 client open?
Up to 8 on firmware V4.0 and up to 16 on V4.1/V4.2 for most S7-1200 CPU variants, combined across client and server roles. The CPU 1217C supports up to 32. The exact number depends on the CPU ordering number and must be verified in the Siemens Modbus/TCP application document.
Why does ping work but MB_CLIENT time out?
ICMP echo requests are 84 bytes; Modbus request/response pairs are typically 100 to 260 bytes. A wireless bridge that passes ping traffic fine can still drop larger frames because of timing, retry, or buffer settings. Stagger MB_CLIENT requests with TON-delayed clock bits to give each request its own RF window.
Can a single MB_CLIENT instance talk to three remote servers?
No. A single instance DB holds the TCP connection state for one remote IP only. Use one instance DB per remote server, and call each from a separate FC block as Siemens describes in its multi-server examples.
What does STATUS 0x80C8 mean on MB_CLIENT?
It means the client sent a Modbus request but did not receive a valid Modbus response within the timeout window. Common causes are wireless collisions, an overloaded server CPU, or a wrong MB_DATA_ADDR that the server's MB_SERVER rejects silently.
Should I run MB_CLIENT in OB1 or in a cyclic interrupt OB?
OB1 is acceptable if you rate-limit REQ with clock bits and TON delays. A cyclic interrupt OB (e.g. OB30 at 100 ms) with a round-robin state machine is cleaner because it removes the accidental race condition between three simultaneously-triggered instances.