Overview: Modbus RTU on the SIMATIC S7-1200
Modbus RTU on the S7-1200 platform is implemented through three instruction blocks from the TIA Portal "Communication" palette: MB_COMM_LOAD, MB_MASTER, and MB_SLAVE. MB_COMM_LOAD configures the serial port of a CM1241 communication module (RS232 or RS485). MB_MASTER initiates Modbus requests on the configured port; MB_SLAVE makes the S7-1200 respond as a server. The blocks operate over the PtP (Point-to-Point) layer of the CM1241 module, so the module must be inserted in the device configuration and the port parameters must match the slave device exactly.
Modbus is a master/slave protocol where a single client initiates transactions against one or more server devices on a shared bus. For a more general description of the protocol and its physical layer requirements, see the Schneider Electric reference What is Modbus and How does it work?. This article focuses on the S7-1200-specific implementation details: first-scan execution, output capture, timing parameters, and the most common synchronization errors.
Hardware: CM1241 RS232 vs CM1241 RS485
Two CM1241 communication modules are typically used for Modbus RTU:
| Module | Function | Network Type | Devices per Bus |
|---|---|---|---|
| CM1241 RS232 | Point-to-Point | RS232 (full-duplex, point-to-point only) | 1 (no bus) |
| CM1241 RS485 | Network (bus-capable) | RS485 (half-duplex, differential) | Up to 32 without repeater |
RS232 is restricted to point-to-point links. For multi-drop Modbus RTU networks the RS485 module is mandatory. The RS485 module is the correct choice for any field-installed Modbus network (drives, instruments, remote I/O) and supports up to 32 nodes on a single segment. Termination (typically 120 Ω at each end of the trunk) and biasing must be wired externally unless the slave device integrates them.
Prerequisites and System Memory Configuration
- Insert a CM1241 module in the device configuration of the S7-1200 station and assign it to a submodule slot.
- Open the S7-1200 Properties > System and Clock Memory tab and enable "Use system memory byte". This exposes a system byte whose first bit pulses for one PLC scan on the first cyclic pass after a STOP-to-RUN transition, restart, or power-on.
- Note the configured system memory byte address (default is byte 1, exposing bit
M1.0as the first-scan pulse).MB_COMM_LOADmust be wired to this bit so it executes exactly once per startup and writes the port configuration into the CM1241 module. - Create an instance data block for
MB_COMM_LOAD(e.g.MB_COMM_LOAD_DB) and a separate instance DB forMB_MASTERorMB_SLAVE.
MB_COMM_LOAD and do not need to match the field; only the MB_COMM_LOAD parameters are authoritative.MB_COMM_LOAD: One-Shot Port Configuration
MB_COMM_LOAD programs the CM1241 port with the baud rate, parity, data bits, stop bits, and flow control. It must run exactly once at startup; subsequent calls are not harmful but are unnecessary because the parameters remain latched in the module.
| Input Pin | Meaning | Typical Modbus RTU Value |
|---|---|---|
REQ |
Trigger to (re)write configuration. Use M1.0 (first scan). |
M1.0 |
PORT |
HW identifier of the CM1241 submodule (system constant). | CM1241 RS485 identifier |
BAUD |
Baud rate | 9600 (most common) |
PARITY |
0 = None, 1 = Odd, 2 = Even | 2 (Even, Modbus RTU standard) |
FLOW_CTRL |
0 = None, 1 = Hardware | 0 for RS485 |
RTS_ON_DLY |
RTS (RS On) delay in ms | 0 (not used on RS485) |
RTS_OFF_DLY |
RTS (RS Off) delay in ms | 0 (not used on RS485) |
RESP_TO |
Slave response timeout in ms | 1000 ms (range 100 – 65535) |
The RTS_ON_DLY and RTS_OFF_DLY parameters have no meaning on an RS485 module. The CM1241 RS485 port does not expose an RTS handshake line in half-duplex Modbus RTU, so leave both at 0. Setting them to non-zero values does not cause harm, but they will have no observable effect on the bus.
RESP_TO. The two parameters are functionally identical and both represent the time the master waits for a slave response before considering the request failed.MB_MASTER and MB_SLAVE: Polled Execution
MB_MASTER and MB_SLAVE can be called every scan. They are not restricted to the first-scan pulse. The REQ input of MB_MASTER is a level-triggered edge: a positive edge initiates a new request. The block handles queuing, turn-around timing, and CRC generation internally.
| Pin | Type | Description |
|---|---|---|
REQ |
Bool (pulse) | Rising edge triggers a Modbus transaction. Use a clock bit or a logic condition that pulses once per request. |
MB_ADDR |
USInt (0–247) | Modbus slave address on the bus. 0 = broadcast (write only). |
MODE |
USInt | Function code: 1=Read Coils, 2=Read Discrete, 3=Read Holding, 4=Read Input, 5=Write Single Coil, 6=Write Single Register, 15=Write Multiple Coils, 16=Write Multiple Registers. |
DATA_ADDR |
UInt | Starting Modbus register/coil address (0-based in the block; some slaves are 1-based; account for offset). |
DATA_LEN |
UInt | Number of coils/registers to access. |
DATA_PTR |
Variant | Pointer to a data block for the payload. The block's data type must match the access (Bool array for coils, Int/Word/Real array for registers). |
DONE |
Bool (output) | True for one scan when the transaction completes successfully. |
BUSY |
Bool (output) | True while a request is in progress. |
ERROR |
Bool (output) | True for one scan when the transaction fails. |
STATUS |
Word (output) | Modbus error code when ERROR rises. |
MB_SLAVE uses a similar interface: it exposes MB_ADDR, a holding-register pointer (MB_HOLD_REG), and the same set of DONE/BUSY/ERROR/STATUS outputs. The slave block does not need REQ; it answers automatically when the master addresses its station.
Timing Parameters: RESP_TO and Retransmission
RESP_TO is the most important timing parameter. It defines the maximum time (in milliseconds) the master waits for a slave response after transmitting a request. MB_MASTER retransmits a failed request up to three times before reporting an error. Between each retry, the block waits the configured RESP_TO interval.
The total time before a transaction is declared failed is therefore roughly:
TotalTimeout ≈ 3 × (transmission_time + RESP_TO)
For a typical 8-byte query/response at 9600 baud 8N1 (≈ 9.6 ms per character, ≈ 96 ms per frame), a RESP_TO of 1000 ms yields a worst-case fail time near 3.3 seconds. If the application polls multiple slaves cyclically, this becomes the lower bound of the cycle time. Reduce RESP_TO to a few hundred milliseconds for fast slaves and increase it for slow devices (wireless gateways, cellular RTUs, or slaves with long processing delays).
RESP_TO too low causes spurious timeouts on a noisy bus or with slow slaves. Setting it too high makes the master appear sluggish and can mask genuine bus faults. Start at 1000 ms and tune to the slowest legitimate response observed in the field.Output Validity and Data Capture
The status outputs of MB_MASTER and MB_SLAVE (DONE, BUSY, ERROR, STATUS) are valid for only one PLC scan when the corresponding event occurs. Likewise, the data written to DATA_PTR is overwritten in place only when a read transaction completes; if the application logic does not sample it on the same scan, the data is replaced by the next transaction.
To capture diagnostic information reliably, latch the values into global markers or a diagnostic data block. A common pattern is:
// Capture error code on rising edge of ERROR
IF "MB_Master_DB".ERROR THEN
"LastModbusError" := "MB_Master_DB".STATUS; // Word
"ErrorTimestamp" := SYSTEM_RTC(); // DTL or Date_And_Time
END_IF;
// Capture read data on rising edge of DONE
IF "MB_Master_DB".DONE THEN
// Copy from DATA_PTR to a holding DB here
END_IF;
For diagnostic data that must persist across scans (last error code, transaction counters, slave response time), use a global DB rather than a marker word; markers are limited to 16 bits and are vulnerable to cross-references in the program.
Error Codes and the 16#81E7 Synchronization Error
Error codes returned on the STATUS output come from two sources: the Modbus protocol layer (standard exception codes 1, 2, 3, 4, etc., returned by the slave) and the CM1241/PtP layer (S7-1200 internal errors). The most common synchronization error is 16#81E7.
| STATUS (hex) | Meaning | Typical Cause | Remedy |
|---|---|---|---|
| 16#0000 | No error | Transaction completed cleanly | — |
| 16#80xx | Modbus exception from slave (xx = slave-returned exception code, e.g. 02 = illegal data address) | Slave rejected the request | Check DATA_ADDR and DATA_LEN against slave's register map; verify the function code is supported. |
| 16#8181 | Wrong MODE / unsupported function | Mode not in the supported list | Use only codes 1, 2, 3, 4, 5, 6, 15, 16. |
| 16#8182 | Data pointer invalid |
DATA_PTR not a DB or wrong type |
Pass a DB of matching type (Bool array, Int/Word/Real array). |
| 16#81E4 | Slave response parity/CRC error | Electrical noise, baud mismatch, wrong parity | Verify BAUD/PARITY; check shield grounding; reduce baud on long cables. |
| 16#81E5 | Slave response timeout |
RESP_TO too low, or slave offline |
Increase RESP_TO; verify slave address and wiring. |
| 16#81E7 | Synchronization error between CM1241 and Receive_P2P |
MB_COMM_LOAD did not run, or the system memory byte is not enabled |
Wire MB_COMM_LOAD.REQ to the first-scan bit (M1.0) and confirm the system memory byte is enabled in device configuration. |
| 16#81EA | Configuration error in MB_COMM_LOAD
|
Invalid baud, parity, or flow control | Verify all MB_COMM_LOAD parameters are within range. |
The 16#81E7 error is the most frequently reported problem in field installations and almost always traces to MB_COMM_LOAD not being executed. The CM1241 port remains in an uninitialized state, the internal Receive_P2P buffer is not synchronized, and any Modbus request is rejected before leaving the master block.
Verification with Modbus Test Tools
Bench-test every Modbus link with a known-good master or slave simulator before commissioning. Two commonly used tools on the bench are:
- Modscan32 (Win-Tech) — simulates a Modbus master, useful when the S7-1200 is the slave.
- Modsim32 (Win-Tech) — simulates a Modbus slave, useful when the S7-1200 is the master and you need a deterministic peer.
Modscan32 and Modsim32 are trial-licensed; the trial cuts the connection after a short interval but is sufficient for verification. Always confirm a round-trip read and write between the simulator and the PLC before connecting the real field device.
- Start Modsim32. Configure slave ID 1, holding registers starting at 40001, and a small register count (e.g. 10).
- On the S7-1200, configure
MB_COMM_LOADfor 9600 8E1 (the Modbus RTU default) andRESP_TO= 1000 ms. - In
MB_MASTER, setMB_ADDR= 1,MODE= 3 (Read Holding Registers),DATA_ADDR= 0 (address 40001),DATA_LEN= 10. - Pulse
REQfrom a clock memory bit or a manual input. - Monitor
DONE,ERROR, andSTATUSin the watch table. On success, the destination DB shows the simulated values. - Repeat with
MODE= 16 (Write Multiple Registers) to verify both directions.
If the test passes with a simulator but fails with the real field device, the problem is almost always electrical (wiring, termination, grounding) or parameter mismatch (slave's baud/parity, register base). Re-verify the slave's communication settings against the values programmed in MB_COMM_LOAD.
Commissioning Procedure for an RS485 Network
- Confirm the CM1241 RS485 module is seated and visible in the device configuration. Note the HW identifier for the
PORTinput. - Enable the system memory byte and confirm the address matches the first-scan bit in the program (default
M1.0). - Place
MB_COMM_LOAD,MB_MASTER(orMB_SLAVE), and their instance DBs in the program. WireMB_COMM_LOAD.REQtoM1.0. - Compile, download, and go to RUN. In a watch table, verify that
MB_COMM_LOAD.DONErises on the first scan and stays latched. - Send a single diagnostic request to each slave on the bus at low baud, one at a time, to isolate wiring and address problems before adding the full polling table.
- Once every slave responds, increase baud to production rate and add the cyclic polling logic.
Troubleshooting Matrix
| Symptom | Likely Root Cause | Diagnostic Step | Resolution |
|---|---|---|---|
| STATUS = 16#81E7 from the first request |
MB_COMM_LOAD not executed |
Watch MB_COMM_LOAD.DONE; check the first-scan bit is wired |
Enable the system memory byte; wire REQ to M1.0
|
| STATUS = 16#81E5 on every request | No response from slave | Verify wiring and slave address; try Modsim32 to confirm the master works | Check A/B polarity, termination, and slave power; increase RESP_TO
|
| STATUS = 16#81E4 intermittently | Electrical noise or baud mismatch | Loop the master to a known simulator; check shielded cable grounding | Lower baud to 9600 or 19200; verify parity matches slave |
| STATUS = 16#80xx (modbus exception) | Slave rejected the request | Decode xx: 01 = illegal function, 02 = illegal address, 03 = illegal value, 04 = slave device failure | Cross-check function code, address range, and value limits against the slave's documentation |
| Reads return zeros despite DONE = TRUE |
DATA_PTR mismatch or register base offset |
Inspect the destination DB in the watch table; confirm the address the slave maps to | Use the correct DB type; remember Modbus "40001" is base 0 in DATA_ADDR
|
| Done never rises, BUSY stuck TRUE |
REQ pulsed too quickly; queue backed up |
Check the request interval is longer than transaction time | Add a delay or condition between requests; verify REQ is a single-shot edge |
| Communication works on bench with Modsim, fails on site | Wiring, termination, or grounding | Swap to a short known-good cable; measure A-B voltage with slave idle | Install 120 Ω termination at both ends; tie cable shield to ground at one end only |
Frequently Asked Questions
Why does the CM1241 RS485 ignore the RTS On/Off Delay parameters?
RS485 is a half-duplex, differential bus with no RTS handshake line. The RTS_ON_DLY and RTS_OFF_DLY inputs of MB_COMM_LOAD only affect the RS232 module where RTS is used to switch between transmit and receive. On RS485, leave both at 0; the module handles bus turn-around internally.
What does Modbus error 16#81E7 mean and how do I clear it?
16#81E7 is a synchronization error between the CM1241 module and its internal Receive_P2P function. It almost always means MB_COMM_LOAD never ran. Enable the system memory byte in the CPU's device configuration and wire MB_COMM_LOAD.REQ to the first-scan pulse bit (default M1.0). After a STOP-to-RUN transition, verify that MB_COMM_LOAD.DONE rises once and stays latched.
How is RESP_TO on the S7-1200 different from the S7-200 Timeout parameter?
They are functionally identical. The S7-200 Modbus library used the name Timeout; the S7-1200 library uses RESP_TO (response timeout) in MB_COMM_LOAD. Both are the maximum time in milliseconds the master waits for a slave response, and both are entered with the same numeric range.
Do MB_MASTER outputs stay valid after a transaction completes?
No. DONE, ERROR, and STATUS are valid for one PLC scan only. Capture them on the rising edge of DONE or ERROR and move the values into a persistent data block if you need to display or log them. Reading the block tags directly without latching will give stale or zero values on most scans.
How many times does MB_MASTER retry a failed request before reporting an error?
The block retries the request up to three times, waiting the configured RESP_TO between attempts. After the third failure it reports an error with a timeout STATUS code. Total worst-case latency is therefore approximately 3 × (transmission_time + RESP_TO). Tune RESP_TO to balance fast failure detection against tolerance for slow slaves.
For a deeper reference on Modbus protocol fundamentals (frame structure, addressing, exception codes, RS485 electrical characteristics) see the Schneider Electric Modbus overview and the Siemens FAQ entry on establishing Modbus-RTU communication with STEP 7 (TIA Portal) V11 for the SIMATIC S7-1200, available on the Siemens Industry Online Support portal.