Problem Definition
A Siemens S7-1500 system using a CM PtP (Communication Module, Point-to-Point) configured as a Modbus RTU master reports a 100 ms latency between raising the REQ input on the MB_MASTER instance DB and the assertion of the DONE output. The slave response itself is correct (8-byte request, 7-byte reply), but the polling cycle observed at the master is dominated by what appears to be ~90 ms of dead time per transaction. With 17 slaves on the bus, the full scan reaches 1.7 seconds at this rate, which is unacceptable for any time-sensitive application.
| Parameter | Value |
|---|---|
| Master controller | S7-1500 CPU (e.g., CPU 1515-2 PN / CPU 1518-4 PN/DP) |
| Serial module | CM PtP (Point-to-Point communication module) |
| Protocol | Modbus RTU, RS-485 two-wire half-duplex |
| Baud rate | 19200 bit/s, 8N1 or 8E1 per slave |
| Slave count | 17 |
| Master request | 8 bytes (1 start, 8 data, 1 stop = 10 bits/char) |
| Slave response | 7 bytes (output coils) |
| OB1 cycle | 10–15 ms |
| MB_MASTER call site | OB1 (cyclic main) |
| Recv start condition | Start of any character |
| Recv end condition | After character delay time elapses (default) |
Modbus RTU Timing Analysis at 19200 Baud
Modbus RTU mandates a 3.5 character inter-frame silence between consecutive frames. At 19200 bit/s with 10 bits per character (1 start + 8 data + 1 stop, no parity), one character time is:
t_char = 10 / 19200 = 0.5208 ms (520.8 µs)
The required silent interval between frames is:
t_silent = 3.5 × t_char = 1.823 ms
| Phase | Calculation | Duration |
|---|---|---|
| Master request (8 bytes) | 8 × 0.5208 ms | 4.167 ms |
| Inter-frame silence | 3.5 × 0.5208 ms | 1.823 ms |
| Slave response (7 bytes) | 7 × 0.5208 ms | 3.646 ms |
| Inter-frame silence (next poll) | 3.5 × 0.5208 ms | 1.823 ms |
| Total wire time per transaction | – | ≈ 11.46 ms |
| Full 17-slave scan | 17 × 11.46 ms | ≈ 195 ms |
The 100 ms observed at the master therefore contains ~89 ms of unaccounted latency. This is not a baud-rate problem; the wire transaction itself completes in ~11 ms. The remaining 89 ms is spent inside the controller, not on the bus.
Root Cause Analysis
The observed latency arises from three independent sources that stack on top of the wire transaction. Disaggregating these is the key to fixing the problem.
-
MB_MASTER state-machine processing in OB1:
MB_MASTERis a multi-instance instruction that advances one internal state per call (REQUEST → WAIT_FOR_REPLY → READ → DONE). In OB1 (10–15 ms cycle), the maximum throughput is one state transition per cycle. Each transition involves a handshake with the CM PtP over the backplane bus, which itself takes 1–3 ms. Four state transitions per transaction therefore consume 40–60 ms before DONE is asserted. - Default character-delay end-of-message detection: when the receive end condition is set to "After character delay time elapses", the CM PtP must observe 3.5 character times of silence AFTER receiving the last byte of the response before signalling the buffer complete. The firmware also adds a debounce window on top of this timer, inflating the close-out phase to ~4–6 ms even when the slave response is exactly the expected length.
- Receive-condition interaction: pairing "Start of any character" with the default character-delay end condition prevents the CM from optimising the receive state machine for short, fixed-length responses. Some CM PtP firmware revisions offer "Message end after receipt of n characters" or "Receive complete after character delay (configurable)" modes that shorten the close-out phase to <0.5 ms.
CM PtP Receive Condition Configuration
Open the CM PtP device configuration in TIA Portal and navigate to Port configuration → RECV conditions. The following parameters directly control the end-of-message evaluation and overall per-transaction latency:
| Parameter | Option | Effect on latency |
|---|---|---|
| End of message detection | "After character delay time elapses" (default) | Waits ~1.82 ms after last byte; safe for variable-length slaves. |
| End of message detection | "After receipt of n characters" | Closes immediately on byte count match; lowest latency, requires known fixed-length responses. |
| End of message detection | "After character delay with timeout" | Hybrid: closes on delay OR after hard timeout; recommended when slave response length varies. |
| Start of receive | "Start of any character" | Lowest trigger latency (~520 µs); disable only if the line has noise. |
| Start of receive | "After character delay" | Adds 1.82 ms filter before accepting a frame; reduces false starts. |
| Character delay time | 0.5–10 ms (in 0.5 ms steps) | Keep at 1.823 ms (3.5 × t_char) per Modbus RTU spec for 19200 baud. |
For a 17-slave poll with fixed response lengths, switching the end condition to "After receipt of n characters" typically reduces the close-out phase from ~5 ms to <0.5 ms. This configuration is documented in the official Siemens Modbus RTU application example at Siemens application example 68202723 (S7-1500 Modbus RTU DOC v21) and in the TIA Portal reference at Overview of Modbus communication (S7-1500).
MB_MASTER Call Placement Strategies
The MB_MASTER instruction must be called cyclically. The OB in which it runs controls how fast the state machine advances:
| Call location | Typical latency per transaction | Recommendation |
|---|---|---|
| OB1 (main cycle, 10–15 ms) | 60–100 ms (4–8 state calls) | Acceptable for ≤4 slaves; not for 17. |
| OB35 (cyclic interrupt, 10 ms default) | 40–60 ms | Better but still bound by OB period. |
| Cyclic interrupt OB, 5 ms | 20–35 ms | Optimal for 17 slaves at 19200 baud. |
| Cyclic interrupt OB, 2 ms | 15–25 ms | Use only when CPU has headroom; monitor OB1 cycle. |
Recommended procedure:
- Add a new cyclic interrupt OB (e.g., OB32 or OB35) with a 5 ms time interval in the device configuration under CPU properties → Cyclic interrupts.
- Move the MB_MASTER call from OB1 into the new cyclic OB.
- Keep all other cyclic logic (HMI update, alarming, etc.) in OB1.
- Ensure the cyclic OB priority is higher than OB1 priority 1 (typical priority 8–12).
// OB32 (Cyclic interrupt, 5 ms)
// MB_MASTER call example for one polled slave
#MB_MASTER_DB.MODE := 0; // 0 = RTU
#MB_MASTER_DB.MASTER_ID := W#16#0001; // CM PtP hardware ID from device config
#MB_MASTER_DB.SLAVE := #current_slave;
#MB_MASTER_DB.READ_LEN := 1;
#MB_MASTER_DB.WRITE_LEN := 0;
#MB_MASTER_DB.WRITE_PTR := P#M 100.0 BYTE 20;
#MB_MASTER_DB.READ_PTR := P#M 200.0 BYTE 20;
#MB_MASTER_DB.REQ := #req_pulse;
#MB_MASTER_DB();
IF #MB_MASTER_DB.DONE OR #MB_MASTER_DB.ERROR THEN
#req_pulse := FALSE;
#current_slave := #current_slave + 1;
IF #current_slave > 17 THEN
#current_slave := 1;
END_IF;
END_IF;
Polling Strategy for 17 Slaves
Sequential polling of 17 slaves at 15 ms per transaction yields a 255 ms scan time at the wire. To shrink this further, consider the following tactics:
- Grouped requests: many slaves support FC 15 (Write Multiple Coils), FC 16 (Write Multiple Registers), or FC 23 (Read/Write Multiple Registers) that consolidate several logical requests into one frame. One FC 16 request for 16 coils replaces 16 single-coil reads.
- Asymmetric polling: poll critical slaves every cycle, slow-changing slaves every 5th or 10th cycle. Use a modulo counter in the sequencer to skip non-critical slaves.
- Baud-rate increase: 115200 bit/s reduces wire time per transaction from ~11.5 ms to ~1.9 ms. Combined with the above, the full 17-slave scan fits in <40 ms.
- Broadcast writes: Modbus slave address 0 is reserved for broadcast. Use FC 5/FC 6/FC 15/FC 16 with slave address 0 to push common setpoints to all slaves in a single frame.
Step-by-Step Optimization Procedure
-
Capture baseline: connect an oscilloscope or logic analyser (Saleae, PicoScope) to the RS-485 A/B differential lines and measure t_REQ→DONE using a digital input wired to the
DONEbit of the MB_MASTER instance DB. - Verify baud rate: in CM PtP configuration, set 19200 bit/s (8E1 or 8N1 per slave datasheet). Mismatched parity is the most common cause of phantom latency on first deployment.
- Tune receive end condition: switch from "After character delay" to "After receipt of n characters" if response length is fixed, or shorten the character delay to 1.823 ms explicitly (instead of relying on the firmware default).
-
Move MB_MASTER to a cyclic OB: create OB32 with a 5 ms period; transfer the MB_MASTER call from OB1. Verify the cyclic OB is not overloaded by adding OB32 runtime measurement via the
OB1_DATE_TIMEstamping or a TON block. - Increase baud rate: 38400 or 115200 bit/s if cable length (<100 m) and all slaves permit. Verify RS-485 termination (120 Ω at both ends) and bias resistors (fail-safe bias, typically 680 Ω to +5 V and GND on the master) are installed.
- Group slaves: combine coils/status into multi-bit FC 15 / FC 16 transactions where the slave firmware supports it.
- Re-measure: confirm per-transaction latency <25 ms (at 19200 baud with OB32) and full-scan latency <500 ms for all 17 slaves.
Verification and Measurement
Use the following checklist after optimisation. The wire-time value must match the baud-rate calculation within ±10 %.
| Check | Expected value |
|---|---|
| Per-transaction DONE latency (19200 baud, OB32 @ 5 ms) | ≤ 25 ms |
| Per-transaction DONE latency (115200 baud, OB32 @ 5 ms) | ≤ 15 ms |
| Full 17-slave scan (19200 baud, OB32 @ 5 ms) | ≤ 425 ms |
| STATUS word of MB_MASTER on success | 0x0000 |
| STATUS word of MB_MASTER on slave timeout | 0x0007 |
| STATUS word of MB_MASTER on CRC error | 0x0008 |
| CM PtP diagnostics buffer | No persistent 0x0007 / 0x0008 entries |
| Scope: total wire time per transaction (19200 baud) | ≤ 11.46 ms |
| Scope: total wire time per transaction (115200 baud) | ≤ 1.92 ms |
Reference for STATUS codes and Modbus RTU parameter structure: TIA Portal Modbus RTU documentation for S7-1500 (V20).
CM PtP Firmware and Hardware Considerations
Firmware updates on the CM PtP have resolved receive-state-machine timing issues in earlier revisions. Check the firmware version in the device properties (online → diagnostics → module information) and update to the latest release available via TIA Portal's online support. The Siemens Modbus RTU application example referenced above includes version notes for each firmware revision that affects timing behaviour.
Troubleshooting Matrix
| Observed symptom | Likely cause | Fix |
|---|---|---|
| ~100 ms per transaction at 19200 baud | MB_MASTER called in OB1 (10–15 ms cycle) | Move call to cyclic interrupt OB @ 5 ms |
| DONE latency grows with slave count | Sequential polling, single MB_MASTER instance | Group slaves using FC 15/16; or split across multiple MB_MASTER instances |
| STATUS = 0x0007 (timeout) on a few slaves only | Total scan time exceeds slave response timeout | Reduce per-transaction latency first; raise slave timeout |
| STATUS = 0x0008 (CRC error) | Baud/parity mismatch or RS-485 termination missing | Verify baud/parity; install 120 Ω termination; check cable |
| STATUS = 0x0006 (illegal function) | Slave does not support FC 15/16/23 used for grouping | Fall back to single-register FC 03/06 |
| Intermittent ~5 ms extra delay per response | Default character-delay timer; long debounce | Switch to "After receipt of n characters" if response is fixed |
| Wire transaction ≤ 12 ms but DONE > 80 ms | Backplane handshake dominates | Reduce OB1 load; move MB_MASTER to faster cyclic OB |
FAQ
Why does my MB_MASTER instance take 100 ms to assert DONE at 19200 baud?
The wire transaction itself completes in ~11 ms (8-byte request + 7-byte response + 3.5 char inter-frame gaps). The remaining ~89 ms is dominated by MB_MASTER state-machine transitions in OB1 (4–8 state calls per transaction at the 10–15 ms OB1 cycle) and the CM PtP receive-end-condition default. Move the call to a 5 ms cyclic interrupt OB (e.g., OB32) and switch the receive end condition to "After receipt of n characters" to reduce latency to ~20 ms.
Which OB should I call MB_MASTER in for fastest throughput?
Call MB_MASTER in a cyclic interrupt OB configured to 2–5 ms (OB30–OB38 depending on CPU). OB1 cycle time (typically 10–15 ms) is too slow to advance the state machine quickly enough for more than a handful of slaves. Avoid calling MB_MASTER from multiple OBs simultaneously, as this creates state-machine collisions and STATUS errors.
What is the difference between "After character delay" and "After receipt of n characters" receive end conditions?
"After character delay" closes the receive buffer when 3.5 character times of silence are observed after the last byte (default Modbus RTU behaviour; ~1.82 ms at 19200 baud). "After receipt of n characters" closes the buffer as soon as the configured byte count is reached, eliminating the silent-period wait. The latter is faster but requires fixed-length responses from every polled slave.
Can I increase baud rate to reduce latency on a 17-slave Modbus RTU network?
Yes. Increase the baud rate to 38400 or 115200 bit/s on both the CM PtP and every slave. At 115200 the wire transaction drops from 11.46 ms to ~1.9 ms. Verify cable length (≤ 100 m recommended at 115200), RS-485 termination (120 Ω at both ends), and that every slave supports the higher baud rate.
What STATUS codes indicate a Modbus RTU timing problem versus a slave error?
STATUS = 0x0007 indicates a frame timeout (no response received within timeout), 0x0008 indicates a CRC error (line noise or baud mismatch), and 0x0006 indicates an invalid slave address or function code. For latency tuning, monitor 0x0000 (success) and confirm that the wire time measured on an oscilloscope matches the configured baud-rate calculation before adjusting software timing.