Problem Overview
On a SIMATIC S7-1500 CPU paired with an ET-200SP IM 155-6 PN station that hosts a CM PtP RS-485 module (catalog 6ES7137-6AA00-0BA0) running Modbus RTU master, the most common field complaint is that holding-register data read from a remote slave remains frozen at its last valid value after the RS-485 cable is unplugged. The same symptom appears with Modbus TCP when the S7-1500 acts as a client via MB_CLIENT and the Ethernet path to the slave is lost. Because S7-1500 data blocks are retentive by default and the Modbus function block (FB) does not overwrite the destination buffer with a safe value when a request times out, the application logic continues to operate on stale telemetry. Actuators driven by these values may behave as if nothing changed; alarms computed from them may latch incorrectly or fail to clear.
The fix is straightforward and entirely application-side: the ERROR boolean and STATUS word output of the Modbus FB must be evaluated every cycle, and any non-zero STATUS — particularly the wire-break and timeout codes — must trigger an explicit write of zero (or a configured safe-state value) into the destination tags. This article documents the root cause, the STATUS semantics, the wiring and module prerequisites, and complete TIA Portal V17+ sample code for both Modbus RTU and Modbus TCP paths.
Root Cause: No Implicit Fault-to-Zero Mapping
Modbus RTU and Modbus TCP master function blocks in the TIA Portal instruction palette — MB_COMM_LOAD and MB_MASTER for the RTU library, MB_CLIENT for TCP — surface communication failures through two outputs: a Boolean ERROR flag and a Word STATUS code. These outputs are advisory. The FB does not modify the destination buffer when the request fails. This is consistent with IEC 61131-3 data ownership semantics: the user program owns lifecycle decisions on its variables.
Three concrete situations produce the frozen-data symptom:
- The slave device is powered down. The master issues a request, receives no response within the configured response timeout (default 1000 ms), and MB_MASTER returns STATUS = 16#80C8. No data is written.
- The A/B conductors of the RS-485 bus are physically disconnected or shorted. The CM PtP module reports a wire-break diagnostic, but MB_MASTER simply returns a receive error such as 16#80D0 (framing) or 16#80D1 (CRC). The previously read value in the destination DB is untouched.
- The CM PtP submodule loses PROFINET connectivity with the ET-200SP backplane (e.g., the module is pulled or its PROFINET device name is unassigned). MB_MASTER returns STATUS = 16#80EE indicating MB_COMM_LOAD is inactive.
In each case, if the application does not interrogate the FB outputs and explicitly clear the destination tags, the previous value persists indefinitely. Modbus itself is a polling protocol — see the Modbus Protocol reference — and there is no implicit "good value" handshake at the wire layer that would permit a PLC to know whether a register is fresh.
Modbus Communication Architecture
Modbus is a master-slave (client-server) messaging protocol originally published by Modicon in 1979. It runs over RS-232, RS-485, or TCP/IP transports and supports function codes for reading and writing coils, discrete inputs, holding registers, and input registers. Refer to National Instruments' Modbus protocol overview and the Wikipedia Modbus article for general protocol details, and the Schneider Electric Modbus FAQ for installation guidelines.
For the S7-1500 with ET-200SP topology addressed in this article, the relevant configurations are:
| Configuration | Master FB | Transport | Library / Source |
|---|---|---|---|
| RTU master via CM PtP on ET-200SP | MB_MASTER + MB_COMM_LOAD | RS-485 two-wire | Siemens MODBUS_PN / legacy MODBUS_RTU library |
| TCP client on S7-1500 CPU | MB_CLIENT | Ethernet / PROFINET | TIA Portal instruction palette |
| TCP server on S7-1500 CPU | MB_SERVER | Ethernet / PROFINET | TIA Portal instruction palette |
The detection and reset logic is identical regardless of transport — only the source of the STATUS word changes.
STATUS and ERROR Output Semantics
Every Modbus master FB exposes two diagnostic outputs:
- ERROR (Bool): Latched TRUE while the most recent job is in an error state. Cleared on the next successful request or on rising edge of the next job trigger.
- STATUS (Word): Hexadecimal status code. 16#0000 indicates no error and valid data in the destination buffer. Any non-zero value indicates an error, an intermediate state, or a job in progress.
The intermediate states (16#7000 series) are not errors — they signal that no job is active or that a job is currently in flight. The application must distinguish these from genuine errors so that it does not zero valid data while a request is still pending.
ET-200SP Hardware Considerations
The ET-200SP IM 155-6 PN (catalog 6ES7155-6AU00-0BN0 or later BA variants) supports CM PtP modules under its PROFINET device tree. The CM PtP 6ES7137-6AA00-0BA0 provides an RS-485/RS-422 interface configurable for Modbus RTU master or slave operation. Important wiring rules:
- RS-485 requires a 120 Ω termination resistor at each end of the bus. Enable the built-in terminator on the CM PtP if it is the physical end node.
- Maximum cable length is 1200 m at 9600 baud. For higher baud rates (19200, 38400, 57600, 115200) the maximum drops accordingly.
- Use shielded twisted-pair cable with shield grounded at one end to minimize noise-induced CRC errors (STATUS = 16#80D1).
- Assign a unique PROFINET device name and IP address to the ET-200SP station. A misconfigured device name causes MB_MASTER to fail with STATUS = 16#80EE because MB_COMM_LOAD cannot bind the port.
The CM PtP module exposes channel diagnostics including wire break, short circuit, and parameterization errors. These are accessible via the module's diagnostic buffer (read with RDREC SFB52) and surface in the S7-1500 CPU's diagnostic buffer as PROFINET alarms. Use OB82 (diagnostic interrupt OB) to catch them at the application layer for faster reaction than polling MB_MASTER STATUS.
Implementation: Modbus RTU Master (MB_MASTER)
Step-by-step configuration in TIA Portal V17 or later:
- Add the ET-200SP station in Devices & Networks. Insert the IM 155-6 PN and a CM PtP submodule in slot 1.
- Open the CM PtP properties. Set the operating mode to "Modbus RTU master" and configure baud rate, parity, and response timeout to match the slave datasheet. A typical response timeout is 1000 ms; for slow slaves, raise it to 3000 ms.
- Install the MODBUS_PN library (or the legacy MODBUS_RTU library for S7-1200/1500) from the Siemens support portal. Refer to the Siemens MODBUS_PN library entry for the current version compatible with your TIA Portal release.
- Create a global DB (e.g.,
MB_MASTER_DB) and call MB_COMM_LOAD once on cold restart (OB100) to initialize the port. - Call MB_MASTER cyclically from OB1 with the MODE = 0 (read holding registers), slave address, starting register, and a pointer to the destination area in the slave data DB.
- Implement a watchdog FB or FC that reads MB_MASTER_DB.STATUS and MB_MASTER_DB.ERROR each scan and clears the destination area on fault.
Implementation: Modbus TCP Client (MB_CLIENT)
For TCP, drag MB_CLIENT from the Instructions pane (Communication → Modbus TCP). The interface differs from MB_MASTER: it uses a CONNECT variant data block that defines the IP address, port (502 default), and connection timeout. STATUS codes follow the same convention. Configure MB_CLIENT_DB with the slave IP and call MB_CLIENT from a cyclic OB (OB1, OB30, or OB35 depending on required scan rate). The MB_CLIENT documentation lists the supported function codes and timeout behavior.
STATUS Word Reference Table
| STATUS (Hex) | Meaning | Category | Recommended Action |
|---|---|---|---|
| 16#0000 | No error, communication healthy | OK | Use returned data |
| 16#7000 | No job currently active | Idle | None |
| 16#7001 | First job call — request dispatched | In progress | None |
| 16#7002 | Job active, awaiting slave response | In progress | Hold last valid value |
| 16#7003 | Job active, transfer in progress | In progress | Hold last valid value |
| 16#80C8 | Slave did not respond within response timeout | Wire break / slave offline | Clear destination data |
| 16#80D0 | Receive error: framing, parity, overrun | Physical layer fault | Clear destination data |
| 16#80D1 | CRC mismatch on received frame | Noise / termination | Clear destination data |
| 16#80D2 | Parity / framing error in address byte | Wrong baud or slave address | Clear destination data |
| 16#80D5 | Negative acknowledgement from slave | Invalid function or address | Inspect slave register map |
| 16#80EE | MB_COMM_LOAD inactive or port unbound | Configuration fault | Verify port initialization |
| 16#80F1 | Job aborted by user (REQ reset) | Operator | None — expected |
| 16#80F4 | Internal error in FB | Library / firmware bug | Update library version |
Sample SCL Watchdog and Reset Logic
The following structured text code (TIA Portal SCL) implements a complete fault-to-zero reset for an MB_MASTER instance reading 10 holding registers into a DB. Place this in a new FC (e.g., FC100 "Modbus_Watchdog") called from OB1 immediately after the MB_MASTER call.
// FC100 "Modbus_Watchdog" — evaluate MB_MASTER STATUS and reset on fault
// Inputs : MB_MASTER_DB instance, fault_latch tag
// Outputs: comm_ok flag, destination register zeroing
#i := 0;
IF "MB_MASTER_DB".ERROR
OR ("MB_MASTER_DB".STATUS <> 16#0000
AND "MB_MASTER_DB".STATUS <> 16#7000
AND "MB_MASTER_DB".STATUS <> 16#7001
AND "MB_MASTER_DB".STATUS <> 16#7002
AND "MB_MASTER_DB".STATUS <> 16#7003
AND "MB_MASTER_DB".STATUS <> 16#80F1) THEN
// Rising-edge reset: zero only on fault transition to avoid scan-by-scan write
IF NOT "fault_latch" THEN
"fault_latch" := TRUE;
"comm_ok" := FALSE;
// Zero all 10 holding register destinations
FOR #i := 0 TO 9 DO
"Slave_Data".HoldingReg[#i] := 0;
END_FOR;
// Log the fault to the diagnostic buffer for post-incident review
"diag_status" := "MB_MASTER_DB".STATUS;
END_IF;
ELSE
"fault_latch" := FALSE;
"comm_ok" := TRUE;
"diag_status" := 16#0000;
END_IF;
The whitelist of in-progress STATUS codes (16#7000–16#7003, 16#80F1) prevents the watchdog from clearing valid data while a request is still pending. The edge-detected fault_latch ensures the destination is zeroed exactly once per fault transition, not on every scan during the failure window.
Edge Detection and Latching Variants
Three alternative implementations are common in production code:
- Immediate clear on every error scan: Simpler, but writes the DB every cycle during the fault window. Acceptable if the DB is small and write load is irrelevant.
- Edge-detected clear (recommended): Latches a fault flag, clears data once, and holds the cleared state until communication recovers. This is the pattern shown above.
-
Hold last-known-good with quality stamp: Preserves the last successful value alongside a quality BOOL (
DataFresh) that the downstream logic checks. Useful when zero is not a safe default (e.g., a temperature setpoint where zero would force full cooling).
For safety-relevant signals, combine the Modbus read with a hardwired channel and a watchdog timer that trips if the Modbus quality flag is FALSE for more than N seconds.
HMI Indication of Communication Health
Expose comm_ok and diag_status to the HMI. A typical WinCC Unified or Comfort Panel layout includes a status bar showing:
- Green indicator: comm_ok = TRUE, STATUS = 16#0000.
- Yellow indicator: comm_ok = TRUE, STATUS in 16#7000–16#7003 (job in progress).
- Red indicator: comm_ok = FALSE, STATUS ≠ 16#0000 with diagnostic text populated from a message list indexed by STATUS high byte.
The HMI tag for diag_status should be a Word with an integer representation so operators can search the manual for the specific fault code.
OB82 Diagnostic Interrupt Integration
For faster fault response than the application-level STATUS polling, wire OB82 (Diagnostic Interrupt OB). The CM PtP submodule raises a PROFINET diagnostic interrupt on wire break and short circuit. In OB82, evaluate the IOSTATE and fault bits in the local temp variables, set comm_ok := FALSE, and zero the destination area immediately. Combined with the MB_MASTER STATUS watchdog, this gives both hardware-level and protocol-level fault paths.
Reference: Siemens MODBUS_PN library FAQ and the S7-1500 MB_CLIENT documentation.
Verification Procedure
- Compile and download the program to the S7-1500. Confirm the ET-200SP station is online and the CM PtP submodule reports no diagnostics.
- Establish Modbus communication with the slave. Verify holding registers update in the slave data DB and that
comm_ok= TRUE. - Place the CPU in RUN with the HMI online. Note a known register value, e.g., "Slave_Data".HoldingReg[0] = 1234.
- Disconnect the RS-485 A/B conductors at either the master or the slave end. Observe MB_MASTER_DB.STATUS transitions to 16#80C8 within the response timeout window.
- Verify "Slave_Data".HoldingReg[0] = 0 and
comm_ok= FALSE within one watchdog cycle after STATUS = 16#80C8. - Reconnect the conductors. Verify STATUS returns to 16#0000 and HoldingReg[0] updates to the live value on the next successful request.
- Open the S7-1500 diagnostic buffer and confirm an entry from MB_MASTER or the CM PtP channel diagnostics identifying the fault and recovery timestamps.
- Repeat the test with the slave powered down (separate cause, same expected behavior).
Troubleshooting Matrix
| Observed Symptom | STATUS Code | Likely Cause | Corrective Action |
|---|---|---|---|
| Data frozen, value persists after cable cut | 16#80C8 | Wire break or slave unpowered | Verify cable, termination, slave power; watchdog should zero the value |
| Data frozen, intermittent CRC errors before freeze | 16#80D1 | RS-485 termination missing or EMI | Enable 120 Ω terminator at both ends; use shielded cable |
| Data never updates, no STATUS transitions | 16#80EE | MB_COMM_LOAD not called or port unbound | Verify CM PtP PROFINET name and IP; check OB100 init |
| Watchdog never fires, value stays valid | N/A | Watchdog FC not called from OB1 | Verify call location and OB cycle |
| Zero written every cycle, even during normal comm | Any | STATUS whitelist too narrow | Include 16#7000–16#7003 in the OK branch |
| Slave returns exception code 02 | 16#80D5 | Invalid data address | Verify register map against slave documentation |
| Fault latch oscillates rapidly | 16#80C8 | Intermittent cable or noise | Replace cable; add debounce timer on fault_latch |
Best Practices and Field-Proven Caveats
- Always define a safe default value explicitly. Do not rely on undefined behavior or initial DB values to mask a fault.
- Use the S7-1500's
WR_USMSGinstruction to write the STATUS code to the diagnostic buffer at the moment of fault transition. This gives a paper trail for post-incident analysis without needing external logging. - Set the Modbus response timeout to at least 2x the slave's worst-case scan period. A timeout shorter than the slave's processing time guarantees false 16#80C8 faults.
- For multi-slave buses, assign a unique slave address to each device. Address collisions produce 16#80D5 from one slave and silence from the other.
- For Modbus TCP over Wi-Fi or cellular gateways, expect occasional 16#80C8 faults due to latency spikes. Use a debounce timer (e.g., 5 consecutive fault cycles) before zeroing the destination.
- Keep the slave register map in a separate DB with symbolic names. Document each register's engineering units, valid range, and safe-state value at commissioning.
- On firmware updates of the MODBUS_PN library, re-test the watchdog logic — Siemens occasionally renumbers STATUS codes between major library versions.
Frequently Asked Questions
Which Siemens FB should I use for Modbus RTU master on a CM PtP under ET-200SP?
Use the MODBUS_PN library's MB_COMM_LOAD (called once on cold restart to bind the port) and MB_MASTER (called cyclically to issue read/write requests). STATUS codes follow the table in this article. Confirm library version compatibility with your TIA Portal release in the Siemens MODBUS_PN library FAQ.
Why does the Modbus FB hold the last value instead of zero on timeout?
Modbus is a polling protocol with no implicit freshness handshake at the wire layer. The Siemens FBs surface faults via ERROR and STATUS but do not modify the destination buffer. The application must explicitly reset the destination on any non-zero STATUS. This is consistent with IEC 61131-3 data ownership semantics.
What STATUS code indicates a wire break on RS-485?
STATUS = 16#80C8 is returned when the slave does not respond within the configured response timeout, which is the typical signature of a broken cable or unpowered slave. STATUS = 16#80D0 (framing) or 16#80D1 (CRC) also indicates physical-layer faults and should trigger the same zero-reset behavior.
How do I distinguish a pending request from a real fault in the STATUS word?
Whitelist the in-progress codes 16#7000 (idle), 16#7001 (first call), 16#7002 (job active), 16#7003 (transfer), and 16#80F1 (user-aborted). Treat any other non-zero STATUS as a fault and zero the destination. The SCL example in this article implements this whitelist directly.
Can I detect the wire break faster than waiting for the Modbus response timeout?
Yes. Wire OB82 (Diagnostic Interrupt OB) to the CM PtP submodule. It raises a PROFINET diagnostic interrupt within milliseconds of detecting a wire break or short circuit. Combine OB82 handling with the MB_MASTER STATUS watchdog for both hardware-level and protocol-level fault paths.
Should I zero the register or hold the last known good value?
It depends on the safety and process implications. Zero is appropriate for sensors where 0 is a valid safe state (e.g., a flow rate of 0 means no flow). For setpoints or controllers where 0 would force a hard stop, use a quality BOOL (DataFresh) alongside the last known value and let downstream logic decide what to do when DataFresh is FALSE.