Resolving S7-1200 ET200SP CM PTP Modbus RTU RS485 Comm Loss

David Krause16 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 S7-1200 ET200SP CM PTP Modbus RTU RS485 Communication Loss

This technical reference addresses a recurring field fault on Siemens S7-1200 CPUs controlling a Variable Frequency Drive (VFD) over Modbus RTU RS485 through an ET200SP distributed I/O station. The communications channel drops the moment the PROFINET cable between the S7-1200 and the ET200SP head module is unplugged, or the instant the VFD is power-cycled, and the only recovery path the operator has is to power-cycle the S7-1200 CPU and the CM PTP module together. That symptom pattern points to a specific class of programming error in TIA Portal V15: the application code is not supervising the DONE, ERROR, and STATUS outputs of the Modbus_Comm_Load and Modbus_Master instructions, so the port state is never re-initialized when the slave disappears. The sections below diagnose the root cause, define the parameters that govern the recovery, and present working SCL and ladder code that restores Modbus RTU traffic automatically without a PLC restart.

1. Problem Description and Field Symptoms

The reported failure mode is reproducible on the engineering bench and on the customer site:

  1. The S7-1200 establishes Modbus RTU RS485 communication with a VFD (any vendor that exposes Modbus RTU registers, e.g., Siemens G120, ABB ACS, Schneider Altivar, Danfoss VLT) through an ET200SP station that contains a CM PTP serial module.
  2. Under normal conditions, Modbus_Comm_Load configures the port, Modbus_Master issues read/write requests, and the VFD responds within the configured response timeout. Drive speed, status word, and control word all update on each cycle.
  3. When the PROFINET cable between the S7-1200 and the ET200SP IM 155-6PN head is removed and reconnected (or when the VFD is power-cycled), the next Modbus_Master call hangs at BUSY=1, the ERROR output never asserts, and the STATUS output freezes at the value reported at the start of the failed transaction.
  4. Reading the VFD registers online shows stale data. The MB_MASTER instance DB reveals the LINE_PRE (line pre-processing time) and RETRIES parameters are still at the values from the original successful call, but no new telegram is dispatched.
  5. Only a power-cycle of the CPU plus the ET200SP station brings the channel back. A warm restart (MRES) of the CPU does not.

The fact that a CPU restart is required confirms the CM PTP module's internal port-handle in the user program has been left in a half-open TCP/serial state. The PLC has not crashed, the PROFINET ring recovers, but the Modbus RTU port FSM (finite state machine) inside the instance DB never returns to the IDLE state because nothing in the user logic is asking it to.

2. Affected Hardware, Firmware, and Software

Component Catalog Number Minimum Firmware Notes
S7-1200 CPU (1214C, 1215C, 1217C) 6ES721x-1xxxxx-0XB0 V4.2 (for TIA V15 stability) Modbus RTU library ships with the CPU
ET200SP IM 155-6PN HF 6ES7155-6AU00-0CN0 / 6ES7155-6AU30-0CN0 V4.2 PROFINET head, supports CM PTP
CM PTP (RS485/422 variant) 6ES7137-6AA00-0BA0 (basic) / 6ES7137-6AA01-0BA0 (HF) V1.1 or higher Source refers to "CM PTP ST"; serial interface module
BaseUnit for CM PTP 6ES7193-6BP00-0DA0 (BU15-P16+A0+2D) or BU20 variant n/a Carries the RS485 A/B terminals and shield
TIA Portal 6ES7822-1AA05-0YA5 (V15) / V15.1 / V16 n/a Modbus library "MODBUS_PN_CPU" or "MODBUS_RTU" blocks
VFD slave any Modbus RTU RS485 slave n/a Address 1 to 247, half-duplex, 8N1 or 8E1 common
Compatibility caveat: When the CM PTP is plugged into an ET200SP station (as opposed to the S7-1200 CPU's own CB/RS485 interface), the port hardware identifier used by Modbus_Comm_Load must come from the ET200SP device configuration, not the CPU's local interface. Mixing them produces the symptom pattern reported here.

3. Root Cause Analysis

Three independent root causes can produce this exact symptom. They frequently combine.

3.1 Timer-Triggered Master With No Error Handshake

The classic mistake is to drive the REQ input of Modbus_Master from a cyclic OB1 timer (e.g., every 100 ms) and ignore the DONE / ERROR outputs. As long as the slave is alive, the pattern works: the rising edge of REQ dispatches a telegram, the slave responds, DONE pulses for one cycle, and the next timer tick re-arms REQ. When the slave disappears, the block's internal state machine advances to WAIT_FOR_RESPONSE, the response timeout elapses, the block writes ERROR=1 and a non-zero STATUS (typically 0x80C8 for slave timeout), and then returns to IDLE. The next timer pulse should re-trigger a new request.

But the timer keeps pulsing at 100 ms. If the slave is still absent, the same failure repeats. If the slave comes back but the application code has not cleared the previous request latch, the REQ input may be stuck high or low in the wrong phase, and no new rising edge is generated. The block silently sits in IDLE forever. The user sees the field as "communication is gone, and I have to restart."

3.2 CM PTP Port Lost After PROFINET Reconnect

ET200SP stations buffer serial ports through the PROFINET backplane. When the PROFINET link between the S7-1200 and the IM 155-6PN drops, the CM PTP module is re-parameterized by the CPU on reconnect. The Modbus port must be re-configured by another call to Modbus_Comm_Load; if the application uses the REQ input of Modbus_Comm_Load tied only to the first scan (one-shot), the second parameterization is never issued. The port remains in a "configured but disconnected" state. Modbus_Master calls go nowhere because the underlying port is closed.

3.3 VFD Power-Cycle Stalls the FSM

Some VFDs (notably certain Schneider, ABB, and older Siemens Masterdrives firmware) leave the bus in an undefined state during a brown-out. The CM PTP driver in the S7-1200 sees a framing error or a character that is not a valid Modbus start-of-frame silence, and the block sets STATUS=0x80D2 (parity/framing) or 0x80E1 (unspecified). If the application code does not explicitly clear the request latch and re-issue Modbus_Comm_Load, the port FSM locks up until the CPU is restarted.

4. CM PTP Hardware Configuration in TIA Portal

Configure the ET200SP station so the CM PTP module is set up for RS485 half-duplex operation before any code is written.

  1. Insert the ET200SP IM 155-6PN in the device view and assign the PROFINET name and IP consistent with the S7-1200's PROFINET interface.
  2. Drag the CM PTP module into slot 1 of the ET200SP. Right-click, Properties → Module parameters → Port configuration.
  3. Select RS485 half-duplex (2-wire) as the operating mode. This is the only mode compatible with a standard 2-wire Modbus RTU trunk.
  4. Disable the receiver enable (if shown) so the driver controls DE/RE automatically based on transmit activity. The CM PTP handles this internally for RS485 mode 1.
  5. Enable the bus terminator on the physical module if the CM PTP is the last node on the trunk (slide switch on the BaseUnit). Use a 120 Ω resistor between A and B, plus 680 Ω pull-up on B and pull-down on A, per the Siemens CM PTP manual.
  6. Set the protocol selection in the module to "Freeport" or leave it to the default; the Modbus blocks program the UART registers at runtime, overriding the static configuration.
  7. Compile the hardware configuration and download it to the S7-1200. Confirm the CM PTP slot reports no diagnostic errors in the online view.
RS485 mode constant: In the Modbus library documentation, the MODE input of Modbus_Comm_Load uses 0 = RS232 full duplex, 1 = RS485 half duplex, 4 = RS422 full duplex (4-wire). The correct value for a 2-wire Modbus RTU trunk is MODE := 1.

5. Modbus_Comm_Load Parameter Reference

The Modbus_Comm_Load instruction (FB / FC depending on library version) configures the port. The block must be called once on first scan, and re-called whenever the port is to be re-initialized.

Input / Output Data Type Typical Value Description
REQ BOOL Rising edge Re-arm to re-parameterize the port
PORT PORT (HW identifier) CM PTP hardware ID Identifies the serial port (ET200SP CM PTP, not CPU)
BAUD DINT 9600 / 19200 Baud rate; must match VFD
PARITY UINT 0=None, 1=Odd, 2=Even 2 (Even) is the most common for VFDs
FLOW_CTRL UINT 0=None RS485 half-duplex has no flow control
RTS_ON_DLY UINT 0 No delay for RS485
RTS_OFF_DLY UINT 0 No delay for RS485
RESP_TO UINT 1000 (ms) Response timeout, must exceed slave response time
MODE USINT 1 1 = RS485 half-duplex
DONE BOOL output True for one cycle after successful config
ERROR BOOL output True on configuration failure
STATUS WORD output 0x0000 success, non-zero error

6. Modbus_Master Parameter Reference

The Modbus_Master instruction (FB) executes a single read or write transaction per call. It is normally called from a cyclic OB; a single rising edge on REQ starts one transaction.

Input / Output Data Type Typical Value Description
REQ BOOL Rising edge Triggers a new transaction
MB_ADDR USINT 1–247 Slave address (e.g., VFD at address 1)
MODE USINT 0=Read, 1=Write, 2=Read/Write Modbus function code selector
DATA_ADDR UINT 40001 for holding register 0 Modbus address (1-based for Siemens blocks)
DATA_LEN UINT 1–125 Word count for read/write
DATA_PTR VARIANT DB or tag Local buffer; length must match DATA_LEN
DONE BOOL output True for one cycle on success
BUSY BOOL output True while transaction in progress
ERROR BOOL output True on transaction failure
STATUS WORD output See error code table
LINE_PRE REAL instance DB Inter-frame pause (ms) before sending
LINE_PRE sizing: The Modbus RTU standard requires a 3.5 character silence between frames. At 9600 baud, one character is 1.04 ms, so LINE_PRE must be at least 3.65 ms. Use 5 ms as a safe default for 9600 baud, scaling proportionally for higher baud rates (use 1.5 ms at 38400 baud, 1 ms at 115200 baud).

7. STATUS and Error Code Reference

Map every non-zero STATUS value to a recovery action. The codes below are documented in the Siemens "Modbus RTU" library help (FB / FC reference) and in the S7-1200 system manual, volume 1/2.

STATUS (hex) Meaning Recovery Action
0x0000 No error None; continue polling
0x80C8 Slave response timeout Retry; if persistent, re-issue Modbus_Comm_Load
0x80D0 CRC / checksum error Retry; check baud and parity
0x80D1 Wrong slave address echo Check MB_ADDR and physical addressing
0x80D2 Parity or framing error Re-issue Modbus_Comm_Load; check wiring
0x80D5 Modbus function not supported Verify MODE / DATA_ADDR against VFD manual
0x80E1 Unspecified internal error Re-issue Modbus_Comm_Load; check instance DB
0x80E2 Buffer overflow (DATA_PTR too small) Increase buffer size in DB
0x80E3 Frame structure error Re-issue Modbus_Comm_Load
0x80E4 CRC mismatch from slave Check bus termination; check for noise
0x80E5 Function code rejected by slave VFD may be in local mode; verify VFD state

8. Recovery Logic Implementation

Two interlocking requirements must be satisfied:

  1. Watch the outputs of Modbus_Comm_Load and Modbus_Master. The application code must inspect DONE, ERROR, and STATUS on every cycle, not just on success.
  2. Re-arm Modbus_Comm_Load on any persistent failure. The REQ input of Modbus_Comm_Load must be re-issued with a fresh rising edge whenever the Master reports a recoverable error. This re-initializes the CM PTP port state machine.

A robust pattern is to wrap the master in a state machine with four states: IDLE, WAIT_FOR_CONFIG, WAIT_FOR_RESPONSE, and ERROR_RECOVERY. After N consecutive errors (e.g., 3 retries within 1 second), the state machine pulses the REQ of Modbus_Comm_Load to reconfigure the port, then resumes polling.

9. Sample SCL (Structured Control Language) Recovery Routine

The following SCL code, written in a function block named FB_ModbusVFD, demonstrates the recommended pattern. The block is called from OB1 (or a cyclic OB) and drives both Modbus_Comm_Load and Modbus_Master.

FUNCTION_BLOCK "FB_ModbusVFD"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      i_StartComm   : BOOL;          // First-scan or manual reset
      i_Enable      : BOOL;          // Master enable
      i_SlaveAddr   : USINT := 1;    // VFD Modbus address
      i_RegAddr     : UINT  := 1;    // Holding register start (1-based)
      i_RegCount    : UINT  := 2;    // Read 2 words (status, frequency)
   END_VAR

   VAR_OUTPUT
      o_Done        : BOOL;
      o_Busy        : BOOL;
      o_Error       : BOOL;
      o_Status      : WORD;
      o_Reg0        : WORD;          // VFD status word
      o_Reg1        : WORD;          // VFD actual frequency
   END_VAR

   VAR
      // Modbus instance DBs (drop the official Siemens blocks in here)
      instCommLoad  : MODBUS_LOAD;   // FB 1800 (or library equivalent)
      instMaster    : MODBUS_MASTER;  // FB 1801
      rtsComm       : BOOL;          // rising-edge latch for Comm_Load
      rtsMaster     : BOOL;          // rising-edge latch for Master
      errCount      : INT;           // consecutive error counter
      tonReconfig   : TON;           // dwell timer for reconfig pulse
      tPoll         : TON;           // poll cadence timer (250 ms)
   END_VAR

BEGIN
   // --- 1. Cadence: poll every 250 ms ---
   tPoll(IN := NOT tPoll.Q, PT := T#250ms);

   // --- 2. Re-arm Modbus_Comm_Load on first scan OR after 3 errors ---
   IF i_StartComm OR (errCount >= 3) THEN
      rtsComm := TRUE;
      errCount := 0;
   END_IF;

   instCommLoad(
      REQ      := rtsComm,
      PORT     := "CM_PTP_HW_ID",      // hardware identifier of the CM PTP
      BAUD     := 9600,
      PARITY   := 2,                    // 2 = Even
      FLOW_CTRL:= 0,
      RESP_TO  := 1000,
      MODE     := 1,                    // 1 = RS485 half-duplex
      DONE     => ,
      ERROR    => ,
      STATUS   =>
   );

   // Auto-reset the rising edge for Comm_Load
   IF rtsComm AND (instCommLoad.DONE OR instCommLoad.ERROR) THEN
      rtsComm := FALSE;
   END_IF;

   // --- 3. Drive the Master only after Comm_Load succeeded ---
   rtsMaster := tPoll.Q AND i_Enable AND instCommLoad.DONE AND NOT rtsMaster;

   instMaster(
      REQ       := rtsMaster,
      MB_ADDR   := i_SlaveAddr,
      MODE      := 0,                    // 0 = Read Holding Registers
      DATA_ADDR := i_RegAddr,
      DATA_LEN  := i_RegCount,
      DATA_PTR  := P#DB100.DBX0.0 WORD 2,  // local 2-word buffer
      DONE      => ,
      BUSY      => ,
      ERROR     => ,
      STATUS    =>
   );

   // --- 4. Latch outputs and update error counter ---
   o_Done   := instMaster.DONE;
   o_Busy   := instMaster.BUSY;
   o_Error  := instMaster.ERROR;
   o_Status := instMaster.STATUS;

   IF instMaster.DONE THEN
      o_Reg0 := "DB100".Word0;
      o_Reg1 := "DB100".Word1;
      errCount := 0;
   END_IF;

   IF instMaster.ERROR THEN
      errCount := errCount + 1;
   END_IF;
END_FUNCTION_BLOCK

Key behaviors of this block:

  • The i_StartComm input is wired to the first-scan bit (or to an HMI reset button). It issues one rising edge to Modbus_Comm_Load at startup.
  • After 3 consecutive master errors, the block automatically re-arms Modbus_Comm_Load, which re-initializes the CM PTP port. This is what the source refers to as the "disable and enable" recovery pattern.
  • The poll cadence is 250 ms. The rtsMaster signal is pulsed only on the rising edge of tPoll.Q, so the Master is never re-triggered while BUSY is true.
  • The hardware identifier CM_PTP_HW_ID must point to the ET200SP CM PTP slot, not the S7-1200 CPU's own RS485 port. In TIA Portal, open the device view, select the CM PTP module, and read the "Hardware identifier" from the Properties pane (a number, typically in the 260–270 range for ET200SP CM PTP slots).

10. Ladder (FBD) Equivalent for Engineers Using LAD/FBD

For installations standardized on ladder, the same pattern fits a small network of contacts and coils.

Network 1: First-scan / reset pulse to Comm_Load
   |--[ FirstScan ]--[/ Comm_Load.DONE /]--[/ Comm_Load.ERROR /]--( Comm_Load_REQ )

Network 2: Error-driven reconfiguration
   |--[ ErrorCount >= 3 ]--( Reset_Comm_REQ )

Network 3: Modbus_Comm_Load (FB)
   |--[ REQ = Comm_Load_REQ ]--[ PORT = HW ID ]--[ BAUD = 9600 ]--
   |--[ PARITY = 2 ]--[ MODE = 1 ]--[ RESP_TO = 1000 ]--
   ==> [ DONE, ERROR, STATUS ]

Network 4: Poll timer 250 ms
   |--[ TON T#250ms ]--( Poll_Tick )

Network 5: Modbus_Master trigger (one-shot)
   |--[ Poll_Tick ]--[ Enable ]--[ Comm_Load.DONE ]--
   |--[ NOT Master.BUSY ]--[ NOT Master_REQ ]--( Master_REQ )

Network 6: Modbus_Master (FB)
   |--[ REQ = Master_REQ ]--[ MB_ADDR = 1 ]--[ MODE = 0 ]--
   |--[ DATA_ADDR = 1 ]--[ DATA_LEN = 2 ]--[ DATA_PTR = DB100 ]--
   ==> [ DONE, BUSY, ERROR, STATUS ]

Network 7: Error counter
   |--[ Master.ERROR ]--[ ADD 1 ]--( ErrorCount )

Network 8: Reset error counter on success
   |--[ Master.DONE ]--[ MOVE 0 ]--( ErrorCount )

11. Verification and Commissioning Procedure

  1. Download the program to the S7-1200. Open the watch table on the instCommLoad and instMaster instance DBs.
  2. Confirm instCommLoad.DONE pulses true on the first cycle and instCommLoad.STATUS = 0x0000.
  3. Confirm o_Reg0 and o_Reg1 update every 250 ms and reflect the VFD's reported status and frequency.
  4. Unplug the PROFINET cable between the S7-1200 and the ET200SP IM 155-6PN. Wait 10 seconds. Reconnect.
  5. Within 3 seconds of reconnection, verify that o_Reg0 and o_Reg1 resume updating. The errCount should rise to 3 and then reset, after which the rtsComm pulse re-initializes the port.
  6. Power-cycle the VFD (turn main input off, wait 5 seconds, restore). Within 1 second, verify that the master reports STATUS=0x80C8 (timeout) for two or three poll cycles, then resumes updating with valid data.
  7. Force a wiring fault (disconnect A or B). Confirm that the error counter increments, the reconfig pulse fires after the third error, and the port does not lock up.
  8. Reconnect the wiring. Confirm the channel recovers automatically within the configured dwell time without operator intervention or CPU restart.

12. Preventive Design Patterns

  • Always monitor DONE, ERROR, and STATUS. Treat any non-zero STATUS as a transient event and apply the recovery rules above.
  • Never tie the Master REQ input to a free-running timer alone. Gate the rising edge with the previous DONE / ERROR outputs and the inverse of BUSY.
  • Use one-shot reconfiguration. Drive Modbus_Comm_Load.REQ from a one-shot pulse (first scan or a manual reset), and from an automatic error-driven reconfiguration counter. Never leave REQ continuously high.
  • Watch the ET200SP PROFINET diagnostics. Subscribe to the IM 155-6PN diagnostic interrupts in OB82 / OB83. Use slot-level diagnostics to detect a CM PTP module that has been re-parameterized and trigger the same reconfig pulse from the diagnostic OB.
  • Validate the bus physically. RS485 requires twisted pair (Belden 3106A or equivalent), 120 Ω termination at both ends, and a common ground reference between the VFD and the CM PTP BaseUnit. Floating grounds produce the same 0x80D2 framing error the user sees on VFD power-up.
  • Set RESP_TO generously. A VFD that takes 300 ms to respond should be configured with RESP_TO = 1000 ms to absorb startup transients.
  • Match LINE_PRE to baud rate. 5 ms at 9600 baud, scaling down as baud rate rises. Insufficient LINE_PRE produces intermittent 0x80E3 frame structure errors.

13. Frequently Asked Questions

Why does Modbus RTU RS485 communication stop after I unplug and replug the PROFINET cable to the ET200SP?

The CM PTP module inside the ET200SP is re-parameterized by the S7-1200 whenever the PROFINET connection is re-established. If the application code ties Modbus_Comm_Load.REQ to a first-scan bit only, the port is never re-configured, and Modbus_Master writes into a closed port. Re-arming Modbus_Comm_Load with a fresh rising edge after the PROFINET link returns restores the port.

Do I have to power-cycle the S7-1200 to recover the Modbus RTU link?

No. The recovery is done in software. Watch the ERROR and STATUS outputs of Modbus_Master; after a defined number of consecutive errors, re-issue Modbus_Comm_Load with a rising edge on REQ. This re-initializes the CM PTP port state machine without restarting the CPU.

What does the 0x80C8 status code mean on Modbus_Master?

0x80C8 is the slave response timeout. The Master transmitted the request but did not receive a valid response within RESP_TO milliseconds. Confirm the VFD is powered, the bus is correctly wired (A to A, B to B, common ground), and the slave address (MB_ADDR) matches the VFD configuration.

How do I size the LINE_PRE parameter for the CM PTP at different baud rates?

Modbus RTU requires a 3.5 character silence between frames. At 9600 baud, one character is roughly 1.04 ms, so set LINE_PRE to at least 5 ms. At 19200 baud use 3 ms, at 38400 baud use 1.5 ms, and at 115200 baud use 1 ms. Adjust upward if you see 0x80E3 frame structure errors on the bus.

Which hardware identifier do I use for the PORT input of Modbus_Comm_Load?

Use the hardware identifier of the ET200SP CM PTP slot, not the S7-1200 CPU's onboard RS485 port. In TIA Portal, open the device configuration, select the CM PTP module, and read the system constant "Hardware identifier" from the Properties pane. Wire that constant to the PORT input of Modbus_Comm_Load.

What is the difference between Modbus RTU, Modbus ASCII, and Modbus TCP?

Modbus RTU is a binary protocol over serial media (RS485, RS422, RS232) with a CRC-16 checksum and 3.5 character inter-frame silence. Modbus ASCII is a human-readable hex-encoded variant over the same serial media with an LRC checksum. Modbus TCP is the same PDU wrapped in an MBAP header and transported over TCP/IP, usually on port 502. For an S7-1200 controlling a VFD over RS485, RTU is the standard choice; see the Modbus protocol overview for the framing details.

Back to blog