S7-1200 MB_SLAVE and PID_Compact Cyclic Interrupt OB Conflict: Diagnostic and Resolution
This field reference addresses a recurring failure mode on the SIMATIC S7-1200 family (S7-1214C, S7-1215C, S7-1212C) where the MB_SLAVE Modbus RTU slave instruction and the PID_Compact technology object share a cyclic interrupt organization block (OB30–OB38). Symptoms include loss of slave response, asynchronous Tx/Rx LED activity on the CM 1241, and PID output pinning at 0.0. The article consolidates the root cause, the resolution patterns verified on TIA Portal V15–V20 firmware, and the architectural rules required to keep Modbus deterministic on the S7-1200 platform.
1. Problem Statement and Observable Symptoms
Engineers integrating closed-loop process control with Modbus RTU slave communication on the S7-1200 routinely place the PID_Compact technology object in a cyclic interrupt OB to enforce a fixed controller sample time. When the same OB is reused for the MB_SLAVE instruction — which is the default placement recommended by the Modbus RTU library sample project — the bus traffic collapses to a one-way receive (Rx LED blinking, Tx LED dark) and the master observes communication timeouts.
Reproducible symptoms documented in field reports:
- Only the Rx LED on the CM 1241 module blinks; the Tx LED remains off or flickers irregularly.
- The Modbus master reports exception code 0x0B (Gateway Target Device Failed to Respond) or timeout errors.
-
PID_Compact.Output stays at 0.0% even whenSetpointandInputare valid scaled values. - Removing the
MB_SLAVEinstance from the cyclic interrupt OB restores PID operation; removing thePID_Compactinstance restores Modbus response. - Placing the two blocks in two different cyclic interrupt OBs (e.g. OB30 and OB35) does not resolve the failure — the OB priority is the deciding factor, not the OB count.
2. S7-1200 Organization Block Execution Model
The S7-1200 CPU executes organization blocks under a fixed priority scheme inherited from the SIMATIC architecture. Understanding this priority map is essential before any PID/Modbus co-location analysis.
| OB Number | Type | Priority (S7-1200) | Default Cycle / Trigger |
|---|---|---|---|
| OB1 | Main (cyclic) | 1 | Free cycle, watchdog-resetting |
| OB10–OB17 | Time-of-day | 2 | Configured date/time, once or periodic |
| OB20 | Time-delay | 3 | Configured delay (ms) |
| OB30 | Cyclic interrupt | 7 | Cycle time 5 ms to 60000 ms |
| OB31 | Cyclic interrupt | 8 | Cycle time 5 ms to 60000 ms |
| OB32 | Cyclic interrupt | 9 | Cycle time 5 ms to 60000 ms |
| OB33 | Cyclic interrupt | 10 | Cycle time 5 ms to 60000 ms |
| OB34 | Cyclic interrupt | 11 | Cycle time 5 ms to 60000 ms |
| OB35 | Cyclic interrupt | 12 | Cycle time 5 ms to 60000 ms |
| OB36 | Cyclic interrupt | 13 | Cycle time 5 ms to 60000 ms |
| OB37 | Cyclic interrupt | 14 | Cycle time 5 ms to 60000 ms |
| OB38 | Cyclic interrupt | 15 | Cycle time 5 ms to 60000 ms |
| OB40 | Hardware interrupt | 16 | Rising/falling edge, configurable |
| OB80 | Time error | 26 (fixed) | Fired on OB1 overflow |
| OB82 | Diagnostic interrupt | 26 (fixed) | Fired on diagnostic event |
| OB100 | Startup (warm restart) | 27 (fixed) | Once at CPU start-up |
| OB121 | Programming error | Priority of OB that caused it | Fired on synchronous error |
| OB122 | I/O access error | Priority of OB that caused it | Fired on direct I/O access fault |
The cyclic interrupt OBs are launched at equidistant intervals based on the configured phase offset and cycle time. Per the S7-1200 system manual, the cyclic interrupt is part of the system interrupt class and is serviced immediately when its scheduled start time elapses, preempting OB1 if the priority is higher.
Reference: Cyclic interrupt OB — SIMATIC S7-1200 G2 Manual Collection.
3. Why PID_Compact and MB_SLAVE Conflict in a Single OB
The conflict is a combination of three distinct failure mechanisms. Each is independently sufficient to break the slave; together they make co-location nearly impossible without architectural changes.
3.1 Watchdog and OB1 Refresh Deferral
The S7-1200 watchdog is reset only by OB1. When a high-priority cyclic interrupt OB (priority ≥ 7) is invoked, OB1 is suspended. If the cyclic OB overruns its configured cycle time, OB1 execution is deferred past the watchdog window and the CPU enters STOP with diagnostic buffer entry "OB1 watchdog overflow". The Modbus RTU library (LCom library, Modbus_Comm_Load / Modbus_Slave instructions from the SIMATIC S7-1200 Programmable Controller - System Manual) is designed to run inside the standard program cycle, where it can yield between character receive interrupts. Long-running cyclic OBs starve the Modbus receive handlers that the CM 1241 driver relies upon.
3.2 Instance DB Size and Image Partition Overlap
PID_Compact instantiates a technology object DB sized between 800 and 1400 bytes depending on firmware version. When the DB is placed in process image partition 1 (PIP 1) — the default for cyclic interrupt OBs — and the MB_SLAVE instance DB is also placed in PIP 1, the UPDAT_PI / UPDAT_PO implicit calls performed by MB_SLAVE can partially overlap the PID background data. The library does not guard against aliasing when both DBs share the same process image. The error manifests as a frozen Output = 0.0 because the integrator accumulator in the PID background is overwritten during the Modbus update.
3.3 MB_COMM_LOAD Port Misconfiguration
The most common co-location bug observed in field reports is calling MB_COMM_LOAD in OB100 (warm restart) without a valid hardware port identifier. OB100 runs before the CM 1241 module has finished its hardware initialization, so the call returns STATUS = 0x80C8 (invalid port). The error bit is sticky and the MB_SLAVE instance retains ERROR = TRUE across the entire runtime. When the engineer later moves MB_COMM_LOAD to OB1 with a valid port, the conflict with PID_Compact is also resolved because OB1 is the proper execution context for Modbus.
Error codes encountered in this failure mode:
| STATUS (hex) | Meaning | Resolution |
|---|---|---|
| 0x0000 | No error | — |
| 0x80C8 | Invalid port identifier (no CM module / wrong port) | Verify CM 1241 hardware ID in device configuration |
| 0x80D1 | Receiver aborted due to parity/framing error | Check baud, parity, RS485 termination (120 Ω) |
| 0x80D2 | Receiver aborted due to buffer overflow | Increase cyclic OB time or move Modbus call to OB1 |
| 0x80E1 | Frame received with CRC error | Check cable shielding, baud rate mismatch |
| 0x80E2 | Reply not sent because no master request | Verify slave ID and master poll sequence |
4. Root Cause Verification Procedure
Before applying any structural change to the program, run the following diagnostic sequence on the failing CPU. All checks use online tools available in TIA Portal without rewiring.
- Go online with the CPU and open Online & Diagnostics > Diagnostic buffer. Record the most recent error entries. OB80 (time error), OB121 (programming error), and OB122 (I/O error) entries point to OB priority / access conflicts.
- Open Watch table on the
MB_SLAVEinstance DB. ForceNDR,ERROR,STATUS, andMB_HOLD_REGinto a new watch table. IfSTATUSreturns16#80C8, the port is invalid. - Open Watch table on the
PID_Compactinstance DB. InspectRetain.CtrlParams.bRunModeandsRet.i_Status. Ifi_Status = 0andOutput = 0.0whileInputandSetpointare valid, the controller is in inactive state, not in error — indicating the background task is not being serviced. - In Project tree > PLC tags > Default tag table, expose the system clock
%Sbits and useRD_SYS_Tin a watch table to timestamp cyclic OB execution. If the delta between two consecutive triggers exceeds the configured cycle time, the OB is overrunning. - Open the CPU operator panel and verify the RUN LED is solid green and the ERROR LED is off. A blinking ERROR LED confirms a diagnostic interrupt pending in the buffer.
5. Resolution Patterns
Three patterns are field-proven on the S7-1200 platform. The first is mandatory; the second and third are recommended when the controller must remain in a cyclic interrupt OB.
5.1 Move MB_SLAVE to OB1 (Recommended Baseline)
The Modbus RTU library is designed to run inside the main cyclic OB. The CM 1241 point-to-point driver schedules character receive on the hardware interrupt OB40; the user-side MB_SLAVE call processes the assembled frame in OB1 where the watchdog is refreshed.
Implementation:
- Cut the
MB_SLAVEandMB_COMM_LOADcalls from the cyclic interrupt OB. - Paste both calls into a network in OB1.
MB_COMM_LOADmust be the first call, executed unconditionally on first scan only (use a rising edge on a startup flag). - Verify the hardware port identifier on the
MB_COMM_LOADPORTinput matches the CM 1241 hardware ID from the device configuration. The hardware ID is found in Device view > CM 1241 properties > System constants > Hardware identifier. - Call
MB_SLAVEunconditionally every OB1 cycle. Do not gate it on anENinput condition.
Sample OB1 network for Modbus RTU slave:
// Network 1 — Initialize Modbus port once on first scan
IF "FirstScan" THEN
"MB_COMM_LOAD_DB"(REQ := TRUE,
PORT := 269, // CM 1241 hardware ID
BAUD := 115200, // baud rate
PARITY:= 0, // 0=None, 1=Odd, 2=Even
FLOW_CTRL := 0, // 0=None (RS485 2-wire)
TIMEOUT := 1000, // ms
DONE => "mbLoadDone",
ERROR => "mbLoadErr",
STATUS => "mbLoadStatus");
"FirstScan" := FALSE;
END_IF;
// Network 2 — Process Modbus slave requests
"MB_SLAVE_DB"(MB_ADDR := 1, // Modbus slave address
MODE := 0, // 0=RTU
HOLD_REG := "ModbusHolding", // Pointer to holding register DB
DONE => "mbSlaveDone",
ERROR => "mbSlaveErr",
STATUS => "mbSlaveStatus");
5.2 Keep PID_Compact in Cyclic OB, Isolate the Instance DB
When the application demands a deterministic PID sample time, keep PID_Compact in a cyclic interrupt OB (commonly OB35 at 100 ms for thermal loops, OB30 at 10 ms for fast hydraulic control). Apply the following isolation rules:
- Place the
PID_Compactinstance DB in process image partition 0 (PIP 0, the default cyclic partition) so it does not collide with the Modbus hold register area. - Disable the
UPDAT_PI/UPDAT_POinstructions on the cyclic interrupt OB. Right-click the OB > Properties > Process image > uncheck "Update process image automatically". - Never use the
ENinput ofPID_Compactas a process condition.ENis a system attribute, not a process enable. UseManualEnableto switch into manual mode andManualValueto drive the output during commissioning. - Call
PID_Compactevery cycle of the cyclic OB. Do not wrap it in a conditional branch.
5.3 Cycle Time Sizing for the Cyclic OB
The configured cycle time of the interrupt OB must exceed the worst-case execution time of all instructions placed in it, with a minimum 25% headroom for the PID background task scheduling.
| PID Application | Recommended Cycle Time | Recommended OB |
|---|---|---|
| Temperature (slow thermal) | 1000 ms | OB35 (12 priority) |
| Temperature (furnace) | 500 ms | OB35 (12 priority) |
| Flow / pressure | 100 ms | OB35 (12 priority) |
| Level / position | 50 ms | OB33 (10 priority) |
| Hydraulic servo | 10 ms | OB30 (7 priority) |
The cycle time and phase offset are configured in the OB properties dialog in TIA Portal. The phase offset allows multiple cyclic OBs to be staggered so they do not collide with each other on the priority stack.
Reference: Cyclic interrupt OBs (S7-1500) — STEP 7 V20. While the article targets the S7-1500, the equidistant timing model is identical on the S7-1200 and the priority/phase offset behavior maps directly.
6. CM 1241 Wiring and Timing Caveats
Beyond the program-side fix, the physical layer must be sized for the bus. The CM 1241 RS485 (6ES7241-1CH32-0XB0) supports baud rates 300 to 115200 bps. At 115200 bps the inter-character timeout is 750 µs and the inter-frame timeout is 3.5 character times (≈ 304 µs). Any cyclic OB that overruns these windows will drop characters and the slave will not respond.
| Baud (bps) | Inter-frame Timeout (3.5 char) | Max OB Cycle for Stable Modbus |
|---|---|---|
| 9600 | 3.65 ms | < 3 ms |
| 19200 | 1.82 ms | < 1.5 ms |
| 38400 | 0.91 ms | < 0.8 ms |
| 57600 | 0.61 ms | < 0.5 ms |
| 115200 | 0.30 ms | < 0.25 ms |
For 115200 bps the cyclic OB has only 250 µs of headroom. With a 10 ms cyclic interrupt the Modbus frame is delivered to the slave instruction long after the master has already timed out. This is the underlying mathematical reason that placing MB_SLAVE in a 10 ms cyclic OB fails while placing it in OB1 succeeds: OB1 runs at 1–3 ms typical and the frame is processed within the master's poll window.
RS485 wiring requirements specific to CM 1241:
- Install 120 Ω termination at both ends of the trunk, switched in via the on-board DIP switch (position ON for end nodes).
- Shield the cable and ground the shield at one end only (typically the master) to avoid ground loops.
- Maximum cable length: 1200 m at 9600 bps, 30 m at 115200 bps. For long runs, drop to 19200 bps or add an RS485 repeater (e.g. 6ES7972-0AA02-0XA0).
- Hold the
SEND/RECVline biasing in the OFF position for full-duplex RS485, ON for half-duplex.
7. Putting It Together — Working Program Skeleton
The following skeleton resolves the documented failure and is the configuration that has been verified to operate for sustained polling at 115200 bps on an S7-1214C DC/DC/DC with CM 1241 RS485.
7.1 OB1 (Main Cyclic OB)
// Network 1 — One-shot Modbus port load
IF "FirstScan" THEN
"MB_COMM_LOAD_DB"(REQ := TRUE,
PORT := 269,
BAUD := 115200,
PARITY := 2, // Even parity recommended for Modbus RTU
FLOW_CTRL := 0,
TIMEOUT := 1000,
DONE => "Static_1",
ERROR => "Static_2",
STATUS => "Static_3");
END_IF;
// Network 2 — Modbus slave processing (called every OB1 cycle)
"MB_SLAVE_DB"(MB_ADDR := 1,
MODE := 0,
HOLD_REG := P#DB100.DBX0.0 BYTE 200,
DONE => "Static_4",
ERROR => "Static_5",
STATUS => "Static_6");
// Network 3 — HMI tag refresh, scaling, alarms (no cyclic dependency)
7.2 OB35 (Cyclic Interrupt OB, 100 ms)
// Network 1 — PID_Compact, called every OB35 cycle
"PID_Compact_DB"(Setpoint := "Process".SP,
Input := "Process".PV_scaled,
Input_PER := 0,
ManualEnable := "Process".ManualMode,
ManualValue := "Process".ManualOutput,
Output => "Process".CV_percent,
OutputPER => "Process".CV_per,
SetpointLimit_H := "Process".SP_Hi,
SetpointLimit_L := "Process".SP_Lo,
InputScaling.UpperPointIn := 27648.0,
InputScaling.LowerPointIn := 0.0,
InputScaling.UpperPointOut := 100.0,
InputScaling.LowerPointOut := 0.0);
7.3 OB100 (Startup)
Leave OB100 empty of MB_COMM_LOAD. Port loading in OB100 is the most common cause of the documented 0x80C8 error. If a one-shot initialization is required, use a "FirstScan" flag set in OB100 and consumed in OB1 as shown above.
8. Verification Checklist
After applying the structural changes, validate with the following 10-point procedure.
- Compile and download the project to the CPU. Confirm a clean download with no compile errors.
- Place the CPU in RUN. The RUN LED must be solid green; the ERROR LED must be off.
- Open the online watch table and confirm
MB_COMM_LOAD_DB.STATUS = 16#0000within 2 seconds of start-up. - Connect the Modbus master (e.g. another S7-1200 configured as
MB_CLIENT, a third-party SCADA, or Modbus Poll). Read holding register 0 (word). Confirm the value is returned without exception. - Force a process variable into the
PID_CompactInputvia the watch table. ConfirmOutputmoves within 3 OB35 cycles (≈ 300 ms at 100 ms cycle time). - Toggle the
ManualEnableinput to TRUE. ConfirmOutputtracksManualValuewithin one OB35 cycle. - Disconnect the RS485 cable. Confirm the diagnostic buffer records the cable break (if line monitoring is configured) and the Modbus STATUS transitions to 16#80D1 or 16#80E1 within one OB1 cycle.
- Reconnect the cable. Confirm the slave resumes normal operation without a CPU restart.
- Run a 24-hour soak test. Confirm the diagnostic buffer shows zero OB80, OB121, or OB122 entries.
- Capture a Modbus traffic trace with a tap (e.g. HMS Anybus X-gateway or Wireshark on a serial tap). Confirm Tx and Rx frames are interleaved and each master request receives exactly one slave response.
9. Troubleshooting Matrix
| Symptom | Likely Root Cause | Diagnostic Step | Resolution |
|---|---|---|---|
| Only Rx LED blinks on CM 1241 | MB_SLAVE in high-priority cyclic OB, watchdog starvation | Watch MB_SLAVE.STATUS and PID_Compact.sRet.i_Status | Move MB_SLAVE to OB1 |
| STATUS = 16#80C8 at start-up | MB_COMM_LOAD called in OB100 without port | Inspect OB100 contents | Remove MB_COMM_LOAD from OB100; call from OB1 with FirstScan flag |
| PID_Compact output pinned at 0.0 | EN input used as process condition; instance DB in same PIP as Modbus hold register | Inspect EN logic; check PIP allocation | Use ManualEnable / ManualValue; move PID instance DB to PIP 0 |
| Tx and Rx LEDs blink but not simultaneous | Cyclic OB time too long for 3.5 character timeout at 115200 bps | Measure cyclic OB execution time with RD_SYS_T | Increase OB cycle to ≥ 5 ms at 115200 bps, or move to OB1 |
| CPU enters STOP with OB80 | OB1 watchdog overflow; cyclic OB preempts OB1 | Diagnostic buffer OB80 entry with OB1 priority info | Reduce cyclic OB frequency; move non-time-critical code to OB1 |
| Intermittent timeouts under load | Background communication OB80 events degrade Modbus timing | Watch OB80.PRIORITY and OB80.OB_NUMBER | Increase OB1 cycle or reduce cyclic OB priority |
| No communication at all | Wrong CM 1241 hardware ID in MB_COMM_LOAD PORT input | Device view > CM 1241 > System constants | Update PORT input to match HW ID (typical: 269, 270, 271 depending on slot) |
10. Architectural Rules of Thumb
- OB1 is the natural home for Modbus RTU. Treat the cyclic interrupt OBs as time-critical islands; do not push communication infrastructure into them.
- One technology object per cyclic OB is a good ceiling. If you need two PID_Compact loops at 100 ms, use one OB35 and call both; do not create OB35 and OB36 with the same cycle time and phase offset, because they will collide on the priority stack.
- The PID sample time should be 4 to 10× the process time constant. For a thermal process with T = 30 s, sample at 3–7 s, not 100 ms. Faster sampling wastes CPU bandwidth and increases the chance of OB1 starvation.
- Use phase offsets to stagger cyclic OBs. With two cyclic OBs at 100 ms, set OB35 phase = 0 ms and OB36 phase = 50 ms so the OBs interleave.
- Never tie Modbus polling to the PID sample time. The Modbus master owns the bus timing. The slave must be ready to respond on every OB1 cycle regardless of the PID state.
11. Frequently Asked Questions
Why does the Modbus slave stop responding only when PID_Compact is added to the same cyclic interrupt OB?
The cyclic interrupt OB runs at priority 7 to 15, preempting OB1. The CM 1241 receive handlers rely on OB1 execution to drain the receive buffer. When the cyclic OB overruns or holds the CPU, MB_SLAVE cannot complete its response within the master's 3.5-character inter-frame timeout, and the master logs a gateway timeout. Move MB_SLAVE into OB1 so the slave instruction runs on the same scan that the watchdog refreshes.
Can I keep MB_SLAVE in the cyclic interrupt OB and just increase the OB cycle time?
At 115200 bps the inter-frame timeout is only 304 µs, far below any realistic cyclic OB time. The maximum bus rate that a 10 ms cyclic OB can sustain is roughly 19200 bps, and even then only if the OB does not service anything else. For anything above 19200 bps, MB_SLAVE must run in OB1.
Why is calling MB_COMM_LOAD in OB100 the wrong place to initialize the Modbus port?
OB100 fires during warm restart, before the CM 1241 module has finished its hardware initialization. The hardware identifier is not yet valid and MB_COMM_LOAD returns STATUS = 16#80C8, which is sticky on the MB_SLAVE instance. Move the port load to OB1 and execute it once on a FirstScan flag set in OB100.
What is the difference between gating PID_Compact with the EN input versus ManualEnable?
EN is a binary system enable that stops the instruction from executing its internal code. Gating PID_Compact with EN during a process condition pauses the background integrator and produces output = 0.0. ManualEnable is a process-level switch that hands the output to ManualValue while the controller remains active. Use ManualEnable to switch between automatic and manual mode, never EN.
Which cyclic interrupt OB and cycle time should I choose for a temperature loop with PID_Compact on the S7-1200?
For thermal processes with a time constant above 10 s, use OB35 at 1000 ms. For faster thermal responses (T = 2 to 5 s), use OB35 at 100 ms. The configured cycle time must exceed the worst-case execution time of the OB body by at least 25% to avoid OB80 time errors.
Does this conflict affect the S7-1500 as well?
Yes. The architectural cause is identical: high-priority OBs preempt OB1 and starve the Modbus RTU library. On the S7-1500 the cyclic OBs are OB30 to OB38, with priorities 7 to 17. The same fix applies — move MB_SLAVE to OB1, keep PID_Compact in the cyclic OB. The Modbus RTU library on the S7-1500 uses the same Modbus_Comm_Load and Modbus_Slave instructions under the names MB_COMM_LOAD and MB_SLAVE.
What is the maximum number of PID_Compact instances I can run in a single S7-1214C cyclic interrupt OB?
On an S7-1214C DC/DC/DC the cyclic OB budget is roughly 2 ms at 100 ms cycle. Each PID_Compact instance consumes 0.15 to 0.30 ms depending on firmware. In practice, 3 to 5 PID_Compact instances fit in a 100 ms OB35 on the S7-1214C before OB1 starts to starve. The S7-1215C doubles that headroom.