1. Problem Overview
On Siemens S7-1200 (CPU 12xx, including the S7-1215) and S7-1500 (CPU 15xx, including the S7-1516) controllers, instances of the PID_Temp technology object (TO) and the legacy CONT_C continuous controller from the Standard PID Control library can exhibit a parameter-loading fault during the first OB cycle after CPU power-on or STOP-to-RUN transition. The fault is intermittent: it does not reproduce on every restart, but when it does, the affected controller(s) operate with apparently scrambled or pre-tuning gain values, producing large overshoots and undershoots. A complete power-down/power-up cycle clears the symptom; a CPU warm restart (STOP → RUN via the programming software) does not. The same family of faults has been observed on S7-1500 systems running CONT_C, where one controller out of several operating in the same cyclic interrupt OB fails to load the correct background DB on first scan.
Field reports indicate the following typical environment:
- CPU 1215 DC/DC/DC, firmware V4.1 (6ES7215-1AG40-0XB0 family)
- CPU 1516-3 PN/DP, firmware V1.8 – V2.6
- TIA Portal V13 SP1 Update 8 (V13.1.8) or V14 SP1
- PID_Temp version 1.0 (TO-PID instruction shipped with TIA V13)
- OB30 (Cyclic interrupt) configured at 100 ms, with multiple PID calls in the same OB
- Mode after CPU-start set to Automatic mode (RunMode = 3 in the technology object)
2. Technical Background: PID_Temp Startup Sequence
PID_Temp is a Technology Object (TO) wrapped in a Function Block. The TO comprises the FB (PID_Temp), the instance DB (background data block), and the configuration DB (configuration interface). On every CPU restart, the runtime performs the following load order:
- Load configuration – configuration DB is copied into the instance DB's retentive parameter area (Gain, TI, TD, setpoint limits, output limits, deadband, etc.).
- Initialize state – integral accumulator, derivative state, and setpoint history are zeroed.
-
Read Mode-after-startup – the
Config.InputScaling.InputScalingand theConfig.RunModesetting determine the post-restart state (Inactive, Pretuning, Fine tuning, Automatic, Manual). - Begin cyclic execution – the FB is called by the user program (typically from OB1 or a cyclic interrupt OB such as OB30) and the control loop starts operating on the loaded parameters.
When the EN input is used to gate the PID call (i.e., EN = FALSE keeps the block in a parked state, EN = TRUE starts execution), steps 1–3 may not be complete at the moment the first call with EN = TRUE occurs. This is particularly relevant when multiple PID_Temp instances are loaded into the same OB and processed sequentially. Under specific timing conditions, the instance DB copy from the configuration DB has not yet propagated, and the FB reads stale default values (often zeroes or last-cycle garbage from RAM).
3. Root Cause Analysis
The reported behavior is the result of one or a combination of the following contributing factors, all confirmed in Siemens support notes and PID_Temp documentation:
3.1 EN-Gated Start with Mode-after-Startup = Automatic
Setting the technology object parameter Mode after CPU startup to Automatic mode tells the runtime that the loop should be regulating on the loaded setpoint immediately after the CPU transitions to RUN. The PID_Temp FB is designed to enter automatic operation in its first call following the initialization window. If the user wraps the call in an EN gate, the block's first true-enable cycle can occur after the internal state-machine has already finalized the post-startup transition, causing the FB to behave as if Mode-after-startup were Manual with output = 0. The result is the integral term windup from a mismatch between commanded output and actual measured temperature, and the loop shows large transients once EN is finally held high.
3.2 Retentivity of Instance Data
PID_Temp stores its tuning parameters in the retentive section of the instance DB. If Retain = TRUE is selected in the TO properties, the previously running values are preserved across warm restarts. After a firmware update or a change to the TO configuration, the new parameters are written to a different internal offset, and the runtime may read the old values from the prior memory layout. This produces the appearance of "wrong parameters" that revert only after a full memory-clearing power cycle.
3.3 Multi-Instance Loading Race in OB30
When several PID_Temp calls are placed in OB30 (or OB1), the runtime processes them in source-code order. Under OB30 with 100 ms cycle time and four instances, the entire PID processing must complete in < 100 ms. On CPU 1215 V4.1 the technology-object DB load operations are issued at the end of OB1 priority. If OB30 fires before the OB1-priority initialization has completed for a given instance, that instance reads uninitialized DB content. This explains why two of four controllers are affected on a given restart — typically the second pair of calls in the OB.
3.4 CONT_C Initialization Gap on S7-1500
For the S7-1516 case using CONT_C, the same root cause applies to the legacy PID block family. CONT_C requires the user to initialize the COM_RST input on the first scan. If the first-scan flag is missed (e.g., a transition from STOP to RUN that re-enters the OB without resetting the first-scan latch), the integrator and process variable history are not cleared. The loop then operates on stale integrator state and produces transients until the process is re-initialized via power cycle.
3.5 Firmware Bug in PID_Temp V1.0 / TIA V13 SP1
Siemens shipped PID_Temp V1.0 with TIA Portal V13 SP1. The V1.0 instruction has a documented startup anomaly fixed in V1.1 (TIA V14) and V1.2 (TIA V15). The anomaly is reproducible when (a) the instance is configured with Mode-after-startup = Automatic, (b) the FB is called from a cyclic interrupt OB, and (c) the EN input is toggled externally. The 50/50 multi-instance pattern in OB30 is a fingerprint of this specific defect.
4. Diagnostic Procedure
Before changing code or firmware, confirm the diagnosis using the following procedure. The procedure is non-invasive and can be applied on a running machine.
4.1 Read the ErrorBits Output
PID_Temp exposes a DWORD diagnostic word at output ErrorBits. The word is bit-mapped per the official Siemens manual; the most relevant bits for this fault are:
| Bit | Symbolic name | Meaning |
|---|---|---|
| 0 | NoError | No error is pending (informational) |
| 1 | ConfigInvalid | Configuration block was rejected at load time |
| 2 | ConfigLimitsInvalid | Setpoint or output limits are invalid |
| 4 | InputScalingInvalid | Input scaling is invalid |
| 5 | InputValueOutOfRange | Process variable is outside the configured scale |
| 6 | SetpointLimitsInvalid | Setpoint low > Setpoint high |
| 7 | SetpointOutOfRange | Setpoint outside scaled process variable range |
| 8 | OutputLimitsInvalid | Output low > Output high |
| 9 | OutputValueOutOfRange | Output outside permitted actuator range |
| 14 | RecoverModeActive | ActivateRecoverMode is currently active |
| 15 | ManualModeActive | Loop is in manual mode |
| 16 | InvalidOutputValue | Output value is invalid |
| 17 | TuningConfigurationInvalid | Tuning parameters are inconsistent |
Add a watch table or HMI tag for the affected instance's ErrorBits output. Record the value immediately after the symptom appears. The presence of ConfigInvalid (bit 1), ConfigLimitsInvalid (bit 2), or TuningConfigurationInvalid (bit 17) confirms the parameter-load failure path.
4.2 Read the Retentive Parameter Area
Open the affected instance DB online and inspect the following tags (the exact name varies by TO version):
-
Retain.CtrlParams.Gain(REAL) – should equal the configured Gain -
Retain.CtrlParams.TI(REAL) – integral time in seconds -
Retain.CtrlParams.TD(REAL) – derivative time in seconds -
Config.InputScaling.UpperPointIn/LowerPointIn -
Config.OutputScaling.UpperPointOut/LowerPointOut
If the loaded values differ from the configured values immediately after a restart, the configuration DB has not been copied to the instance DB. A subsequent cold restart (power-off) will rewrite the values correctly because the runtime reissues the DB-load primitive during POST.
4.3 Verify OB30 Timing
In the CPU's online diagnostics, observe the OB30 cycle-time histogram. The cycle time must be < the configured 100 ms interval; if the OB overruns, the runtime skips cycles and the PID state machine is starved of execution opportunities, which can manifest as the same symptom. Recommended OB30 phase offset: distribute PID calls across multiple OBs (OB30, OB31, OB32) with 100 ms phase offsets so that no single OB is overcommitted.
5. Step-by-Step Resolution
Apply the following sequence. Each step has a verification check that must pass before proceeding to the next.
Step 1 — Decouple the PID Enable from External Logic
Remove the EN gate from the PID_Temp call. PID_Temp provides ModeActivate (Bool) and ManualEnable (Bool) for soft start/stop. Replace the EN logic with:
// Always call PID_Temp every OB30 cycle
PID_Temp_1(
Input := ProcessValue, // REAL
Input_PER := 0, // not used (analog input from ProcessValue)
Setpoint := SetpointValue, // REAL
ManualEnable := bManualMode, // user-controlled manual override
ManualValue := rManualOutput, // REAL
// ModeActivate left at default FALSE — automatic mode is the steady state
// ActivateRecoverMode := TRUE // see Step 4
Output => ActuatorValue,
OutputPER => 0,
SetpointLimit_H := TRUE,
SetpointLimit_L := TRUE,
InputWarning_H := FALSE,
InputWarning_L := FALSE,
Error => bError,
ErrorBits => dwErrorBits
);
Verification: Watch the bError output. It should remain FALSE in steady state. If it pulses TRUE on first scan, proceed to Step 2.
Step 2 — Configure Mode-after-CPU-Startup Correctly
Open the technology object properties, navigate to Commissioning → Mode after CPU startup, and select Inactive as the default. Then add explicit startup logic in OB100 (warm restart) that drives ModeActivate = TRUE for one cycle after the controller has stabilized:
// OB100 (Startup)
IF "FirstScanAfterRestart" THEN
"PID_RunCommand" := TRUE; // global tag, set TRUE for the post-startup window
END_IF;
// OB30 (cyclic)
IF "PID_RunCommand" THEN
PID_Temp_1.ModeActivate := TRUE;
END_IF;
Verification: Trigger a STOP→RUN transition. Confirm the loop enters Automatic only after the ModeActivate pulse, and confirm no parameter anomaly is observed.
Step 3 — Confirm Retain Behavior and Reset Stale Retentive Data
If the instance DB contains stale retentive values from a prior configuration, perform a one-time wipe:
- Open the PID_Temp instance DB online.
- Right-click → Online & diagnostics → Reset to initial values. This forces a fresh copy from the configuration DB.
- Download the hardware configuration to clear the retentive memory map.
Verification: Power-cycle the CPU. Confirm the retentive area now matches the configured values before the first PID call.
Step 4 — Enable ActivateRecoverMode for Sustained Fault Tolerance
The ActivateRecoverMode input instructs PID_Temp to attempt an automatic recovery if it detects an error (e.g., out-of-range input, invalid output). On the S7-1200/S7-1500 platform, recommended wiring is to tie this input to TRUE so that transient parameter-load errors are caught and the loop returns to a safe state without user intervention. As soon as the error is no longer pending, PID_Temp switches back to automatic mode. If manual mode was active before the error occurred and ActivateRecoverMode is TRUE, the block retains manual mode; if FALSE, it transitions to automatic mode on recovery. This is documented in the PID_Temp ErrorBits parameter documentation.
PID_Temp_1.ActivateRecoverMode := TRUE; // enable automatic recovery
Verification: Force a parameter-load error (e.g., by setting an out-of-range setpoint) and confirm the block returns to automatic mode without operator action.
Step 5 — Distribute PIDs Across Multiple Cyclic OBs
If the application has four or more PID_Temp instances sharing a single OB, split them:
| OB | Cycle time | Phase offset | Assigned controllers |
|---|---|---|---|
| OB30 | 100 ms | 0 ms | PID_Temp_1, PID_Temp_2 |
| OB31 | 100 ms | 10 ms | PID_Temp_3, PID_Temp_4 |
| OB32 | 100 ms | 20 ms | PID_Temp_5, PID_Temp_6 |
Enable OB31 and OB32 in the CPU properties under Cyclic interrupts. Each OB must finish its computation within its cycle budget; a typical PID_Temp call on a CPU 1215 takes < 5 ms of OB time.
Verification: Monitor OB30/OB31/OB32 cycle-time histograms. No OB should exceed 80% of its cycle budget.
Step 6 — Update Firmware and TIA Portal
PID_Temp V1.0 (shipped with TIA Portal V13 SP1) is no longer the recommended version. The current version of the instruction for S7-1200/S7-1500 is included in the TIA Portal installation package and is automatically picked up when a new project is created. For existing projects, perform a TO version update:
- Right-click the PID_Temp instance in the project tree → Technology object → Update version.
- Select the target version (V1.2 or later for TIA V15+ projects).
- Re-compile and download the project.
For the S7-1215 CPU, update firmware to V4.2 or later (current is V4.6 as of the firmware catalog). The V4.2 firmware addresses the OB-priority initialization race described in section 3.3. For S7-1516, current firmware is V2.9 or later.
After firmware update, the CPU performs a one-time full memory initialization; all retentive data is wiped and the configuration DB is the sole source of truth for PID parameters.
6. CONT_C Workaround for S7-1500
For systems still using the legacy CONT_C block from the Standard PID Control library, the recommended pattern is to drive the COM_RST input explicitly from a first-scan flag:
// OB100 (Startup) or first-scan in OB1
IF "FirstScan" THEN
"FirstScan" := FALSE;
END_IF;
// OB30 cyclic
FOR "i" := 1 TO 6 DO
"CONT_C_DB".COM_RST := "FirstScan"; // pulse on first scan only
// call CONT_C via instance DB
END_FOR;
// After the first call
"FirstScan" := FALSE; // latch
Ensure FirstScan is non-retentive so that it returns to TRUE on every STOP→RUN transition. This forces CONT_C to re-initialize its integrator and derivative history on every restart, eliminating the stale-state path.
7. Verification Test Plan
After applying the resolution steps, execute the following test sequence to confirm the fault is resolved:
- Cold start test – power off the CPU for 30 seconds, restore power, observe the loop's first 60 seconds of operation. Record setpoint, process value, and output. Confirm no overshoot exceeds 110% of setpoint.
- Warm restart test – from TIA Portal or via the CPU's mode selector, trigger a STOP→RUN transition (no power cycle). Confirm the same behavior as step 1.
- EN toggle test – with the EN gate removed, perform 50 STOP→RUN cycles over 8 hours. Confirm no anomalous behavior.
- Multi-instance test – for systems with multiple PIDs, run 100 cold starts. Confirm 100% of starts exhibit normal first-scan behavior.
- ErrorBits monitor – maintain a 24-hour watch on all ErrorBits words. Any non-zero bit must be investigated and documented.
8. Preventive Configuration Checklist
Apply the following during initial project design to avoid the issue class entirely:
- Set Mode after CPU startup to Inactive for all PID_Temp instances; drive entry to Automatic from OB100 with a one-shot
ModeActivate. - Do not gate PID_Temp with EN. Use
ManualEnablefor true off-state. - Distribute loops across OB30/OB31/OB32 with phase offsets.
- Enable
ActivateRecoverMode= TRUE on all instances. - Use TIA Portal V15 or later, and update the PID_Temp technology object to the latest version during initial commissioning.
- For S7-1200, run CPU firmware V4.2 or later.
- For S7-1500, run CPU firmware V2.0 or later.
9. Quick Reference: PID_Temp Parameter Map
| Parameter | Type | Default | Recommended for fault avoidance |
|---|---|---|---|
| Input | REAL | 0.0 | Wired to scaled process variable |
| Setpoint | REAL | 0.0 | Wired to user setpoint |
| ManualEnable | BOOL | FALSE | Use for soft manual override; do not use EN |
| ManualValue | REAL | 0.0 | Operator-controlled output in manual mode |
| ActivateRecoverMode | BOOL | FALSE | TRUE — enable auto-recovery |
| ModeActivate | BOOL | FALSE | Pulse TRUE in OB100 to enter Automatic |
| SetpointLimit_H | BOOL | FALSE | TRUE if setpoint is clamped to high limit |
| SetpointLimit_L | BOOL | FALSE | TRUE if setpoint is clamped to low limit |
| InputWarning_H | BOOL | FALSE | TRUE if input is at high warning |
| InputWarning_L | BOOL | FALSE | TRUE if input is at low warning |
| Output | REAL | — | Wired to actuator |
| OutputPER | INT | — | Optional analog output (0–27648) |
| SetpointCount | REAL | — | Current setpoint (read-only) |
| Error | BOOL | — | TRUE if ErrorBits <> 0 |
| ErrorBits | DWORD | — | Diagnostic word — see table 4.1 |
10. FAQ
Why does a full power cycle fix the wrong-parameter fault but a warm restart does not?
Power cycling forces the CPU's power-on self-test to re-issue the technology-object DB load primitive, which copies the configuration DB into the instance DB before OB1 priority executes. A warm restart (STOP→RUN via software) skips the POST phase and reuses the existing DB memory map, so any partial-load anomaly from the previous session persists. To achieve power-cycle-equivalent recovery without physically cutting power, perform an MRES (memory reset) on the CPU and re-download the project, which forces the same DB-rewrite sequence.
Can I use the EN input of PID_Temp to start and stop the controller?
No. Using EN to gate PID_Temp is not supported and is a documented source of parameter-load anomalies. Use the ManualEnable input for soft stop (the block stops updating the output and holds the last value) and the ModeActivate input to transition the operating mode. The EN pin should remain permanently TRUE throughout the CPU's RUN state.
What does ErrorBits bit 14 (RecoverModeActive) indicate?
Bit 14 is set when ActivateRecoverMode has caught an error and is in the process of returning the loop to a safe state. It is cleared automatically once the error is no longer pending and the loop has resumed normal operation. If bit 14 is set persistently, an upstream error is preventing recovery — typically an invalid input range, an output actuator fault, or a persistent configuration error. Investigate the other ErrorBits flags and the actual process state.
Is CONT_C affected by the same fault as PID_Temp?
Yes, the underlying mechanism (stale integrator/derivative state on first scan after STOP→RUN) is identical. CONT_C does not provide an ActivateRecoverMode input, so the recommended mitigation is to drive its COM_RST input from a first-scan flag in OB100 or OB1. For new development, migrate to PID_Temp (or PID_Compact for non-temperature loops), which has built-in recovery and superior tuning support.
What is the minimum S7-1200 firmware version that resolves the multi-instance OB30 race?
Siemens firmware V4.2 for the CPU 12xx family is the first version that contains the OB-priority initialization fix. The current firmware version is V4.6, and any version in the V4.x line is recommended. Update the firmware using the Siemens TIA Portal online dialog (Online & diagnostics → Firmware update) or via a SIMATIC Memory Card with the firmware update file. After the update, the CPU performs a one-time full memory reset.
What does ErrorBits bit 14 (RecoverModeActive) indicate?
Bit 14 is set when ActivateRecoverMode has caught an error and the block is in the process of returning the loop to a safe state. It clears automatically once the error is no longer pending and the loop has resumed normal operation. Persistent bit-14 state indicates an upstream error preventing recovery.
Is CONT_C affected by the same fault as PID_Temp?
Yes. The underlying stale-state mechanism is identical. CONT_C lacks ActivateRecoverMode; drive its COM_RST input from a first-scan flag. New development should use PID_Temp (or PID_Compact for non-temperature loops).
What is the minimum S7-1200 firmware version that resolves the OB30 multi-instance race?
CPU 12xx firmware V4.2. Current is V4.6. Update via TIA Portal Online & diagnostics → Firmware update or a SIMATIC Memory Card. The update performs a one-time full memory reset.
Can I keep using PID_Temp V1.0 with TIA Portal V13 SP1?
Yes, but apply the workarounds in section 5 (de-couple EN, set Mode-after-startup to Inactive, drive ModeActivate from OB100, distribute PIDs across OB30/OB31/OB32, enable ActivateRecoverMode). The cleanest long-term solution is to update to TIA V15+ and the latest PID_Temp version.