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:
- 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.
- Under normal conditions,
Modbus_Comm_Loadconfigures the port,Modbus_Masterissues read/write requests, and the VFD responds within the configured response timeout. Drive speed, status word, and control word all update on each cycle. - 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_Mastercall hangs atBUSY=1, theERRORoutput never asserts, and theSTATUSoutput freezes at the value reported at the start of the failed transaction. - Reading the VFD registers online shows stale data. The
MB_MASTERinstance DB reveals theLINE_PRE(line pre-processing time) andRETRIESparameters are still at the values from the original successful call, but no new telegram is dispatched. - 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 |
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.
- 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.
- Drag the CM PTP module into slot 1 of the ET200SP. Right-click, Properties → Module parameters → Port configuration.
- Select RS485 half-duplex (2-wire) as the operating mode. This is the only mode compatible with a standard 2-wire Modbus RTU trunk.
- 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.
- 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.
- 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.
- Compile the hardware configuration and download it to the S7-1200. Confirm the CM PTP slot reports no diagnostic errors in the online view.
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 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:
-
Watch the outputs of
Modbus_Comm_LoadandModbus_Master. The application code must inspectDONE,ERROR, andSTATUSon every cycle, not just on success. -
Re-arm
Modbus_Comm_Loadon any persistent failure. TheREQinput ofModbus_Comm_Loadmust 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_StartComminput is wired to the first-scan bit (or to an HMI reset button). It issues one rising edge toModbus_Comm_Loadat 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
rtsMastersignal is pulsed only on the rising edge oftPoll.Q, so the Master is never re-triggered whileBUSYis true. - The hardware identifier
CM_PTP_HW_IDmust 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
- Download the program to the S7-1200. Open the watch table on the
instCommLoadandinstMasterinstance DBs. - Confirm
instCommLoad.DONEpulses true on the first cycle andinstCommLoad.STATUS= 0x0000. - Confirm
o_Reg0ando_Reg1update every 250 ms and reflect the VFD's reported status and frequency. - Unplug the PROFINET cable between the S7-1200 and the ET200SP IM 155-6PN. Wait 10 seconds. Reconnect.
- Within 3 seconds of reconnection, verify that
o_Reg0ando_Reg1resume updating. TheerrCountshould rise to 3 and then reset, after which thertsCommpulse re-initializes the port. - 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. - 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.
- 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, andSTATUS. Treat any non-zeroSTATUSas a transient event and apply the recovery rules above. -
Never tie the Master
REQinput to a free-running timer alone. Gate the rising edge with the previousDONE/ERRORoutputs and the inverse ofBUSY. -
Use one-shot reconfiguration. Drive
Modbus_Comm_Load.REQfrom a one-shot pulse (first scan or a manual reset), and from an automatic error-driven reconfiguration counter. Never leaveREQcontinuously 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
0x80D2framing error the user sees on VFD power-up. -
Set
RESP_TOgenerously. A VFD that takes 300 ms to respond should be configured withRESP_TO = 1000ms to absorb startup transients. -
Match
LINE_PREto baud rate. 5 ms at 9600 baud, scaling down as baud rate rises. InsufficientLINE_PREproduces intermittent0x80E3frame 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.