Detecting Modbus Wire Break on S7-1500 ET-200SP via STATUS

David Krause13 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

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:

  1. 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.
  2. 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.
  3. 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:

  1. Add the ET-200SP station in Devices & Networks. Insert the IM 155-6 PN and a CM PtP submodule in slot 1.
  2. 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.
  3. 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.
  4. Create a global DB (e.g., MB_MASTER_DB) and call MB_COMM_LOAD once on cold restart (OB100) to initialize the port.
  5. 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.
  6. 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:

  1. 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.
  2. 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.
  3. 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

  1. Compile and download the program to the S7-1500. Confirm the ET-200SP station is online and the CM PtP submodule reports no diagnostics.
  2. Establish Modbus communication with the slave. Verify holding registers update in the slave data DB and that comm_ok = TRUE.
  3. Place the CPU in RUN with the HMI online. Note a known register value, e.g., "Slave_Data".HoldingReg[0] = 1234.
  4. 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.
  5. Verify "Slave_Data".HoldingReg[0] = 0 and comm_ok = FALSE within one watchdog cycle after STATUS = 16#80C8.
  6. Reconnect the conductors. Verify STATUS returns to 16#0000 and HoldingReg[0] updates to the live value on the next successful request.
  7. 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.
  8. 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_USMSG instruction 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.
Safety note: For SIL-rated applications, Modbus alone is not an acceptable safety communication channel. Use PROFIsafe on PROFINET for safety I/O, and treat Modbus values as advisory only. The fault-to-zero reset described in this article is a best-practice availability feature, not a safety function.

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.

Back to blog