Problem Overview
On a Siemens S7-1200 CPU equipped with a CM 1241 communication module configured as a Modbus RTU slave over RS-232, the Modbus_Comm_Load and Modbus_Slave instructions in the user program frequently display status value 16#7000 in the STATUS output. Engineers reading the block online through TIA Portal interpret this as a communication failure even when the slave is correctly responding to external Modbus masters and the process data exchange is functioning.
The status 16#7000 (decimal 28672) is the documented no job active state for every asynchronous S7-1200/S7-1500 communications instruction. It is the normal resting state of the FB and is not an error indicator. Misreading this value is one of the most common diagnostic dead ends for first-time Modbus integrators.
Root Cause Analysis
The CM 1241 RS-232 / RS-485 modules and the S7-1200 onboard serial port (when supported by the CPU firmware) use the Siemens Modbus RTU instruction library. The library contains two cooperating blocks:
-
Modbus_Comm_Load (FB 1803 / instruction in the MODBUS group): configures the serial port — baud rate, parity, data bits, stop bits, and protocol mode (RTU/ASCII). It runs once on REQ and reports the configuration result through
DONEandERROR. -
Modbus_Slave (FB 1805) or Modbus_Master (FB 1804): performs the actual Modbus data exchange. The slave block cycles every scan once
Modbus_Comm_Loadhas completed successfully.
Both blocks share a uniform internal state machine:
- Block is invoked with a rising edge on
REQ(forModbus_Comm_Load) or continuously by the cyclic OB (forModbus_Slave). - The instruction performs its task — port configuration for
Comm_Load; telegram processing forSlave. - When finished, it sets
DONE=TRUEorERROR=TRUEfor exactly one PLC scan and writes the detailed result toSTATUS. - On the next scan, the block returns to the idle state:
BUSY=FALSE,DONE=FALSE,ERROR=FALSE,STATUS=16#7000.
Online monitoring permanently shows the latest latched value of STATUS. Because the result pulse is only one scan wide, online display almost always shows the last written value, which is the idle status, even though the instruction has just completed a transaction.
STATUS word displayed online as the current bus state. Latch the STATUS value into a separate variable on the scan where DONE or ERROR is TRUE, then read that latched value for diagnostics.
Status Code Reference for Modbus Instructions
| STATUS (hex) | Decimal | Meaning | Severity |
|---|---|---|---|
| 16#0000 | 0 | Operation completed without error | Info |
| 16#7000 | 28672 | No job in progress (block idle) | Info — expected |
| 16#7001 | 28673 | Job in progress, first call | Info |
| 16#7002 | 28674 | Job in progress, subsequent call | Info |
| 16#8180 | 33152 | Incorrect IDB length / port in use | Error |
| 16#8181 | 33153 | Hardware fault (baud, parity, framing) | Error |
| 16#8184 | 33156 | Mode parameter out of range | Error |
| 16#8185 | 33157 | Pointer type / address error in DATA_ADDR/DATA_LEN
|
Error |
| 16#8186 | 33158 | Hardware fault, RS-485 repeater timeout | Error |
| 16#8280 | 33408 | Modbus exception code 01 (illegal function) | Error |
| 16#8281 | 33409 | Modbus exception code 02 (illegal data address) | Error |
| 16#8282 | 33410 | Modbus exception code 03 (illegal data value) | Error |
| 16#8283 | 33411 | Modbus exception code 04 (slave device failure) | Error |
Source: Siemens Industry Online Support — S7-1200 Modbus RTU instructions.
Internal State Machine (Slave Perspective)
The Modbus RTU protocol layer on the S7-1200 follows a finite state machine consistent with the open Modbus specification and the SimpleModbus reference implementation. Every master/slave interaction traverses the following states:
Between the Sending Response and the next Processing Request state, the driver observes the 3.5-character inter-frame silence required by the Modbus RTU specification. Blocking the call inside the cyclic OB interrupts this machine and corrupts timing, which is why Modbus_Slave must be called in a time-consistent OB such as OB1 (or OB200 for a 1217C).
Correct Status Latching in Structured Text
Because the DONE/ERROR pulse is one scan wide, the latched status must be captured in the same OB call. The following SCL (Structured Text) pattern is the recommended implementation:
// FB instance data
VAR
mbCommLoad : MODBUS_COMM_LOAD; // FB 1803
mbSlave : MODBUS_SLAVE; // FB 1805
commDone : BOOL;
commError : BOOL;
commStatus : WORD; // latched status word
slaveError : BOOL;
slaveStatus : WORD;
END_VAR
BEGIN
// 1) Run Comm_Load once on cold start or parameter change
IF NOT commDone AND NOT commError THEN
mbCommLoad.REQ := TRUE;
ELSE
mbCommLoad.REQ := FALSE;
END_IF;
mbCommLoad.PORT := "Local~CM_1241_RS232"; // hardware ID
mbCommLoad.BAUD := 9600;
mbCommLoad.PARITY := 0; // 0 = Even, 1 = Odd, 2 = None
mbCommLoad.STOP_BITS := 1;
mbCommLoad.DATA_BITS := 8;
mbCommLoad.MODE := 4; // 4 = RTU slave
mbCommLoad();
// Latch the one-scan result
IF mbCommLoad.DONE THEN
commDone := TRUE;
commStatus := mbCommLoad.STATUS;
ELSIF mbCommLoad.ERROR THEN
commError := TRUE;
commStatus := mbCommLoad.STATUS; // store for diagnostics
END_IF;
// 2) Slave only runs after Comm_Load is done
IF commDone THEN
mbSlave.MODE := 1; // 1 = Modbus RTU
mbSlave.SLAVE_ADDR := 1;
mbSlave.DATA_ADDR := 40001; // first holding register
mbSlave.DATA_LEN := 20; // 20 holding registers
mbSlave.DATA_PTR := "DB_HoldingRegs".Holding[0];
mbSlave();
IF mbSlave.ERROR THEN
slaveError := TRUE;
slaveStatus := mbSlave.STATUS;
ELSE
slaveError := FALSE;
END_IF;
END_IF;
END
DATA_PTR: the pointer must reference a global data block declared as ARRAY [0..xx] OF WORD or INT. For holding registers use WORD; for input registers use WORD read-only. Coil and discrete maps require ARRAY OF BOOL.
Modbus_Comm_Load: REQ Edge Behavior
Modbus_Comm_Load is not a continuously called driver. It is a one-shot configurator. A positive edge on REQ instructs the block to:
- Stop any active job on the port.
- Reprogram the UART parameters and protocol mode.
- Enable the port for the selected protocol (RTU slave in this case).
- Assert
DONE=TRUEfor one scan withSTATUS=16#0000on success.
If REQ is held TRUE every scan, the block repeatedly re-enters the configuration path, which can prevent the slave from processing telegrams. Always drop REQ after the first successful trigger, as shown in the SCL pattern above.
Modbus_Slave: Cyclic Operation
Unlike Modbus_Comm_Load, Modbus_Slave is called on every PLC scan. It does not require REQ — it inspects the receive FIFO of the CM 1241 and processes any frame whose address byte matches SLAVE_ADDR. The block:
- Reads incoming bytes from the UART ring buffer.
- Validates the inter-frame silence (≥ 3.5 character times at the configured baud).
- Validates the CRC-16 (Modbus polynomial 0xA001).
- Dispatches the function code to the matching handler (01/02/03/04/05/06/15/16).
- Builds the response, appends the CRC, and queues it for transmission.
- Returns to idle (
STATUS=16#7000) until the next telegram arrives.
For the official instruction help, refer to the TIA Portal inline help or the S7-1200 Modbus RTU instruction reference.
Verification with ModScan
To confirm the slave is functional despite the 16#7000 status, run ModScan32 (or any Modbus RTU master test tool) on a PC connected to the CM 1241 RS-232 port through a null-modem cable:
- Set ModScan: Connection → Serial Port → select COMx → Baud 9600 → 8E1 → RTU mode.
- Set Slave Address = 1 (matching
SLAVE_ADDR). - Set Function = 03 (Read Holding Registers) and length = 20.
- Click Connect. The Poll indicator should flash green at the configured scan rate.
- Verify the displayed register values match the data block content in TIA Portal.
If registers update continuously, the Modbus slave is fully operational. The 16#7000 online status is the documented idle state of the instruction between telegrams and can be safely ignored.
Wiring Reference: CM 1241 RS-232 to PC
| CM 1241 RS-232 pin | Signal | DB-9 PC pin (DTE) |
|---|---|---|
| 2 | TXD (out) | 2 (RXD) |
| 3 | RXD (in) | 3 (TXD) |
| 5 | GND / 0V | 5 (GND) |
| 7 | RTS (out) | 8 (CTS) — optional, loopback only if hardware flow control enabled |
| 8 | CTS (in) | 7 (RTS) — tie to RTS or leave disconnected |
Use a null-modem (crossover) cable. Do not connect DCD/DSR/DTR unless the application specifically requires them; the CM 1241 does not implement those signals on the 9-pin sub-D.
Troubleshooting Matrix
| Symptom | Likely cause | Action |
|---|---|---|
| STATUS persistently 16#7000; ModScan gets no response | Comm_Load not yet DONE; SLAVE_ADDR mismatch; wiring swapped | Check commDone; verify RS-232 crossover; check slave address |
| STATUS 16#8181 on Comm_Load | Baud/parity/data bits not supported by the connected device | Recheck protocol parameters; use 8E1 (8 data, even parity, 1 stop) |
| STATUS 16#8185 on Slave | DATA_LEN exceeds 125 holding registers or points to wrong DB | Reduce DATA_LEN ≤ 125; verify DB access mode is non-optimized |
| STATUS 16#8281 (exception 02) | Master requested address outside configured window | Expand DATA_LEN or limit master polling range |
| STATUS 16#8284 (exception 05) on Slave | Master requested unsupported function code | Restrict master to FC 03/06/16 for holding registers |
| Registers read but values are swapped bytes | Word swap between Modbus big-endian and S7-1200 little-endian | Apply byte-swap FB or use WORD_TO_BLOCK_DB reorder logic |
| Intermittent timeouts at > 19200 baud | OB1 cycle time exceeds inter-frame timing on long telegrams | Lower baud or move Slave FB call to a faster OB |
Special Case: Slave Without an Active Master
During commissioning, the slave is often running before any Modbus master is connected. The block continues to cycle through its idle state at the PLC scan rate, consuming virtually no CPU time and writing STATUS=16#7000 on every call. This is the intended behavior and does not indicate a problem. The block waits passively for a valid Modbus frame in the UART FIFO. No polling interval or watchdog must be configured; the slave is fully event-driven from the UART hardware interrupt.
Cross-Reference: Modbus Master Instruction
If the same S7-1200 must poll a remote Modbus device, replace Modbus_Slave with Modbus_Master (FB 1804). The same DONE/ERROR pulse and status-latching rules apply. A typical pattern uses a state machine that triggers Modbus_Master.REQ only after the previous transaction has reached DONE or ERROR with latched status capture. Refer to the S7-1200 System Manual, section on Modbus RTU, for the recommended ladder example.
Firmware and Library Version Notes
The Modbus instruction library has been refined across TIA Portal versions. Key compatibility points:
-
TIA Portal V13 SP1 / V14 introduced the unified
MODBUSinstruction group used by both S7-1200 and S7-1500. -
CPU firmware V4.0+ is required for the
MODEparameter supporting RTU slave on the onboard serial port of CPUs with that interface. - CM 1241 (6ES7241-1AH32-0XB0) supports baud rates up to 115 200 baud in RTU mode; the older 6ES7241-1AH30-0XB0 is limited to 38 400 baud.
For the latest firmware and HSP files, refer to the Siemens Industry Online Support portal.
Best-Practices Summary
- Treat
STATUS=16#7000as the documented idle state of every Modbus block — not as a fault. - Always latch the
STATUSword on the scan whereDONEorERRORtransitions toTRUE. - Drop
Modbus_Comm_Load.REQafter the first successful edge; never hold it permanently. - Call
Modbus_Slavein OB1 (or a cyclic OB matched to your scan time) — do not place it in a time-interrupt OB with strict deadlines. - Use a non-optimized DB for
DATA_PTRwith absolute addressing, declared asARRAY OF WORDfor registers orARRAY OF BOOLfor coils. - Verify with ModScan32 or a known-good Modbus master before assuming a fault.
- Byte-swap data when exchanging with big-endian Modbus masters (most non-Siemens devices).
What does STATUS 16#7000 mean on a Modbus_Comm_Load or Modbus_Slave block in TIA Portal?
Status 16#7000 (decimal 28672) is the documented "no job in progress" / idle state. It appears whenever the instruction has no active request and is not an error. The block returns to this state between Modbus transactions and on every scan when no work is pending.
How do I capture the real error code from a Modbus block on the S7-1200?
The DONE and ERROR outputs are active for only one PLC scan. In the same scan where ERROR transitions to TRUE, copy STATUS into a separate global variable. That latched value persists for diagnostics, while the inline STATUS word will revert to 16#7000 on the next scan.
Do I need a Modbus_Master block if I only want the S7-1200 to act as a slave?
No. A pure slave configuration only requires Modbus_Comm_Load (to set the port and protocol) plus Modbus_Slave (to serve incoming Modbus requests). Modbus_Master is only used when the S7-1200 needs to poll other Modbus devices.
Why do my Modbus registers read correctly but the byte order looks wrong?
Modbus RTU transmits 16-bit registers in big-endian order, while the S7-1200 stores WORDs in little-endian. Apply a byte-swap routine (swap the high and low bytes of each WORD) when reading from or writing to the DATA_PTR array, or use the SWAP instruction in SCL.
How many holding registers can an S7-1200 CM 1241 slave serve?
The DATA_LEN parameter on Modbus_Slave accepts up to 125 holding registers per function code 03 request, matching the Modbus specification limit. Coils, discrete inputs, and input registers are similarly capped at 2000 points, 2000 points, and 125 registers respectively.