Stopping S7-1200 PID_Compact Output on a Safety Alarm in TIA Portal V15.1
A recurring field issue on S7-1200 temperature-control applications is the PID_Compact block continuing to drive a heater even after the operator toggles the block enable (EN) to FALSE in response to a safety alarm such as a blower-fault, over-temperature interlock, or door-open switch. The integrator expects the output to drop to 0.0 percent, but the actuator stays energized because the internal integral term was never cleared. This reference explains the root cause, enumerates four approved ways to bring the output to zero on alarm, and provides tested SCL and ladder snippets for TIA Portal V15.1 with PID_Compact V2.2.
1. Problem Statement
The reported scenario is a temperature-controlled chamber with the following configuration:
- Controller: SIMATIC S7-1200 (CPU 1214C / 1215C family)
- Firmware: CPU firmware V4.2 or higher (required for PID_Compact V2.x)
- Engineering: TIA Portal V15.1 with STEP 7 Basic / Professional
- Technology object: PID_Compact V2.2 (single-loop PID with anti-windup)
- Actuator: SSR-driven resistive heater, output mapped to
OutputPER(PWM) or analogOutput(REAL 0.0–100.0 %) - Alarm sources: blower fault, over-temperature, door interlock, level switch, watchdog
When any alarm sets TRUE the integrator wants the heater to drop to zero immediately. The intuitive approach — turning the PID block's EN input OFF — does not work: the block continues to hold the last manipulated variable at its output. Worse, if the integrator later re-asserts EN, the integral term instantly resumes from the latched value, producing a kick that can re-energize the heater just after the alarm has cleared.
2. Root Cause: Why Disabling EN Does Not Zero the Output
PID_Compact V2.2 is implemented as a runtime technology object referenced through an FB (FB 1139 in the Siemens PID_Compact V2 instruction library). Its relevant internal variables are:
| Internal tag | Type | Meaning |
|---|---|---|
i_IntegralValue |
REAL | Cumulative integral of error (the integrator state) |
o_OutputValue |
REAL | Manipulated variable 0.0–100.0 % |
o_OutputPER |
INT | Scaled analog or PWM output |
i_bInhibit |
BOOL | TRUE while EN = FALSE |
When EN transitions from TRUE to FALSE the block sets i_bInhibit = TRUE. Anti-windup logic freezes the integral component, but the previously written o_OutputValue is not cleared to 0.0. The block simply stops updating it; whatever value was written on the last cycle (for example 47.6 %) remains on the process image and continues to drive the analog output or PWM until the next OB1 scan overwrites it. If the integrator then re-enables the block, the integrator resumes from the retained i_IntegralValue, and the output may briefly snap back to that latched value before the loop re-converges.
Three additional behaviors compound the problem:
- The
Modeinput stays at its last value during inhibit — the block does not auto-switch to manual. - The
ManualEnableinput is ignored whenENis FALSE. - The
Resetinput is only effective whileENis TRUE; clearing it does not by itself zero the output.
The correct remedy is therefore to never use EN as a safety shut-off. Instead, use one of the four control-loop-native mechanisms described in Section 4.
3. PID_Compact V2.2 Interface Reference
The following table summarizes the inputs and outputs that influence output shutdown behavior. Refer to the official Siemens function manual — PID_Compact V2 (entry ID 100746039) and the S7-1200 Programmable Controller System Manual (entry ID 109755202) for the authoritative parameter list.
| Pin | Direction | Type | Effective value / meaning |
|---|---|---|---|
Setpoint |
IN | REAL | Process setpoint in configured unit |
Input |
IN | REAL | Process value (scaled) |
InputPER |
IN | WORD | Analog process value (raw) |
ManualEnable |
IN | BOOL | TRUE: switch to manual mode |
ManualValue |
IN | REAL | Manual output 0.0–100.0 % when in manual |
Reset |
IN | BOOL | TRUE for one cycle: clears I component to 0 |
Mode |
IN/OUT | INT | 0 = inactive, 1 = manual, 2 = automatic, 3 = substitute output value |
Output |
OUT | REAL | Manipulated variable 0.0–100.0 % |
OutputPER |
OUT | INT | Scaled analog / PWM output |
SetpointLimit_H |
OUT | BOOL | Setpoint high limit reached |
InputWarning_H |
OUT | BOOL | Process value above warning limit |
The Mode tag is bidirectional. Writing a new value switches the operating mode; reading it back gives the current mode. Writing 0 (Inactive) does not by itself force the output to zero — it freezes the integrator and stops writing new values, behaving similarly to EN = FALSE. Writing 3 (Substitute output value) substitutes the configured substitute value, which can be set to 0.0 % in the technology object configuration (Configuration → Output settings → Substitute output value).
4. Solution Comparison
| Solution | Output behavior on alarm | Integral state on alarm | Restarts cleanly? | Recommended use |
|---|---|---|---|---|
| 1. Switch to Manual, ManualValue = 0.0 | Jumps to 0.0 % | Retained | Yes — integrator resumes from current error | Best general-purpose choice |
2. Pulse Reset then switch to Manual |
Jumps to 0.0 % | Cleared to 0 | Yes — smoothest restart | Long-duration shutdowns |
| 3. Conditional output gate downstream of PID | External move writes 0.0 | Continues integrating internally (see warning) | Yes — but disables anti-windup | Multiple alarm sources / supervisory override |
| 4. Mode = 3 (substitute) with substitute = 0.0 | Jumps to 0.0 % | Cleared (replaced by substitute) | Yes | Field-replaceable controllers without code edit |
Reset on the rising edge of the alarm-clear signal to clear the integral before re-engaging the PID output.5. Solution 1 — Manual Mode with ManualValue = 0.0
This is the cleanest pattern for a single alarm source. On alarm-asserted: raise ManualEnable and write 0.0 to ManualValue. On alarm-cleared: drop ManualEnable. The block continues to run with EN = TRUE, so the integrator stays synchronized with the live process value, but the manipulated variable is clamped at 0.0 %.
5.1 SCL Implementation
// Inputs
"DB_Alarms".bBlowerFault := "I0.0"; // any safety signal
"DB_Alarms".bOverTemp := "I0.1";
"DB_Alarms".bDoorOpen := "I0.2";
"DB_Alarms".bAnySafetyStop := "DB_Alarms".bBlowerFault
OR "DB_Alarms".bOverTemp
OR "DB_Alarms".bDoorOpen;
// PID gating
IF "DB_Alarms".bAnySafetyStop THEN
"iDB_PID".ManualEnable := TRUE;
"iDB_PID".ManualValue := 0.0;
ELSE
"iDB_PID".ManualEnable := FALSE;
// ManualValue ignored while ManualEnable = FALSE
END_IF;
// Call block
PID_Compact_1(
Setpoint := "DB_Setpoints".rChamberSP,
Input := "DB_Process".rChamberPV,
InputPER := 0,
ManualEnable := "iDB_PID".ManualEnable,
ManualValue := "iDB_PID".ManualValue,
Reset := FALSE,
Mode := 2 // automatic request
);
5.2 Ladder Logic Implementation
Network 1 — Aggregate safety stop
|
|--[ "DB_Alarms".bBlowerFault ]--(
|--[ "DB_Alarms".bOverTemp ]-----+--("DB_Alarms".bAnySafetyStop)
|--[ "DB_Alarms".bDoorOpen ]---- |
|
Network 2 — Manual enable on safety stop
|--[ "DB_Alarms".bAnySafetyStop ]--[ NOT "iDB_PID".ManualEnableLatch ]--("iDB_PID".ManualEnable)
|
Network 3 — Force ManualValue to 0.0 on safety stop
|--[ "DB_Alarms".bAnySafetyStop ]--(
MOVE 0.0 -> "iDB_PID".ManualValue
)
Observe that Mode is left at 2 (automatic). The block will report mode = 1 internally whenever ManualEnable is asserted; you do not need to also rewrite Mode. The HMI tag PID_Compact_1.Mode reflects the effective mode.
6. Solution 2 — Pulse Reset to Clear the Integral
For long-duration shutdowns (for example, an oven with a one-hour cooldown after a thermal cutoff) it is wise to clear the integrator entirely before the loop resumes. Without this, the integrator will have accumulated error from the entire alarm period and will slam the heater to 100 % on release.
Reset is level-sensitive while EN = TRUE. The recommended pattern is a one-shot on the rising edge of the alarm-clear transition:
// Edge detection on alarm clear
"iDB_PID".bResetTrig := "DB_Alarms".bAnySafetyStop AND
NOT "iDB_PID".bResetTrigMem;
"iDB_PID".bResetTrigMem := "DB_Alarms".bAnySafetyStop;
// Hold Reset HIGH for one OB1 cycle
IF "iDB_PID".bResetTrig THEN
"iDB_PID".bResetPulse := TRUE;
END_IF;
// Call block with pulse
PID_Compact_1(
Setpoint := "DB_Setpoints".rChamberSP,
Input := "DB_Process".rChamberPV,
InputPER := 0,
ManualEnable := FALSE,
ManualValue := 0.0,
Reset := "iDB_PID".bResetPulse,
Mode := 2
);
"iDB_PID".bResetPulse := FALSE; // auto-clear next cycle
Alternatively, place the rising-edge detection inline at the Reset pin of the FBD/LAD block using the standard P (rising-edge) coil. PID_Compact V2 requires only one OB1 cycle of TRUE on Reset to clear i_IntegralValue; the rest of the block updates are unaffected.
7. Solution 3 — Conditional Output Override (Supervisory Gate)
Where multiple alarms from different subsystems must each independently suppress the heater (for example a multi-zone furnace), a single supervisory tag may be more maintainable than cascading into the PID FB arguments. The standard idiom is to evaluate the PID output, then conditionally overwrite the actuator:
// Normal PID
PID_Compact_1(Setpoint := sp, Input := pv, Output => rPIDout);
// Supervisory override
IF "DB_Alarms".bAnySafetyStop THEN
"DB_Actuator".rHeaterOutput := 0.0;
// Pulse Reset on the alarm-cleared edge to clear windup
ELSE
"DB_Actuator".rHeaterOutput := rPIDout;
END_IF;
Combine this with Solution 2 on the falling edge of bAnySafetyStop to clear the integral, otherwise the loop will release a 100 % pulse when the alarm clears.
8. Solution 4 — Mode = 3 (Substitute Output Value)
PID_Compact V2 supports a fourth operating mode, Substitute output value, that overrides the output with a parameter configured in the technology object. The default substitute value is 0.0 %. Switching to Mode = 3 is therefore equivalent to forcing the output to the configured substitute.
IF "DB_Alarms".bAnySafetyStop THEN
PID_Compact_1.Mode := 3; // substitute
ELSE
PID_Compact_1.Mode := 2; // automatic
END_IF;
To configure the substitute value: in TIA Portal, open the PID_Compact technology object → Configuration → Output settings → set Substitute output value to 0.0. The substitute value is also what the block outputs when the CPU transitions from RUN to STOP, providing a uniform fail-state.
9. Alarm-to-PID Mapping Worksheet
Use this table to populate the safety matrix. A TRUE in the Action column is OR'd together to form bAnySafetyStop.
| Alarm tag | Source | Priority | Action on TRUE |
|---|---|---|---|
| bBlowerFault | DO from VFD or pressure switch | High | Stop heater, lock operator start until manual reset |
| bOverTemp | Redundant thermostat or PV > hard limit | High | Stop heater, raise alarm on HMI |
| bDoorOpen | Door limit switch | Medium | Stop heater, allow auto-resume on door closed |
| bLevelLow | Capacitive level sensor | Medium | Stop heater, manual reset |
| bWatchdog | Heartbeat from safety relay | High | Stop heater, lock out until power cycle |
| bEStop | Hardwired E-stop loop | High | Cut heater via contactor (independent of PLC) |
The E-stop row is deliberately kept outside the PID gating logic; it must drop the heater via a hardwired contactor to satisfy machinery-safety expectations. See S7-1200 System Manual, Section on Safety Integration, for the recommended wiring topology.
10. Step-by-Step Implementation in TIA Portal V15.1
Step 1 — Add the PID_Compact technology object
- Project tree → PLC_1 → Technology objects → Add new object.
- Select PID_Compact V2.2. Assign a name (for example
PID_ChamberTemp). - Configure Basic settings: input scaling (e.g. 0.0 – 100.0 °C), output in %.
- Set Substitute output value = 0.0 %.
Step 2 — Declare safety tags
- Open PLC data types and create
UDT_Alarmswith the BOOLs listed in Section 9. - Create an instance DB
DB_Alarmsof that UDT. - Map the BOOLs to physical inputs or upstream tag in the default tag table.
Step 3 — Insert the PID call in OB1
- Drag PID_Compact from the Instructions task card into a new network in OB1.
- Assign the instance DB to the technology object.
- Wire the inputs per Solution 1 (Section 5.1) or the alternative you have selected.
Step 4 — Insert the safety aggregation network
- Above the PID network, insert the OR-aggregation of all safety inputs into
DB_Alarms".bAnySafetyStop. - Add the conditional MOVE block that drives
ManualEnableandManualValue.
Step 5 — Compile and download
- Project tree → PLC_1 → Compile → Software (rebuild all).
- Connect to the CPU, download the project, and switch the CPU to RUN.
11. Verification and Commissioning Checklist
-
Step response test (no alarm). Apply a setpoint step from 25 °C to 75 °C with the chamber empty. Verify
Outputclimbs to ~100 %, settles, and converges with no overshoot exceeding the configured limit. -
Alarm-assert test. Force
bBlowerFaultTRUE from the watch table. Within one OB1 cycle,ManualEnablemust read TRUE,ManualValuemust read 0.0, and the heater current (clamp meter) must drop to zero. -
Alarm-clear test. Force
bBlowerFaultFALSE.ManualEnablemust drop to FALSE,ManualValuemust be ignored, and the PID must resume without a >5 % output transient. -
Reset edge test. With Solution 2 in use, observe that on the rising edge of
bAnySafetyStopfalling, the integral componentiDB_PID".i_IntegralValueis cleared to 0 within one OB1 cycle. - EN behavior test. Toggle the PID block's EN to FALSE while the output is at 60 %. Observe the output is held at 60 %, confirming the documented inhibit behavior. Re-assert EN; the output continues without a step.
-
CPU STOP test. Switch the CPU to STOP.
OutputPERmust drop to the substitute value (0 %). The heater contactor must drop out. -
HMI mode display. Confirm that
PID_Compact_1.Modereads 1 (manual) whilebAnySafetyStopis TRUE.
12. Troubleshooting Matrix
| Symptom | Likely cause | Corrective action |
|---|---|---|
| Heater stays ON after alarm | Integrator used EN to gate the PID | Replace EN gating with ManualEnable / ManualValue pattern |
| Output spikes to 100 % on alarm clear | Integrator wound up during shutdown | Add rising-edge Reset pulse on falling edge of alarm |
| Mode = 0 in HMI after alarm | Code writes Mode = 0 (inactive) on alarm | Use Mode = 3 (substitute) or ManualEnable = TRUE instead |
| PID block reports error 0800h | Process value invalid or sensor open | Check InputWarning_H, scale InputPER correctly |
| OutputPER does not drop on alarm | PWM hardware configured for "freeze on manual" | Set PWM to "Stop output" in CPU properties |
| ManualValue ignored | ManualEnable not wired, or Mode = 0 | Verify both ManualEnable = TRUE and Mode ≠ 0 |
| Reset pulse has no effect | EN = FALSE at the moment of pulse | Ensure EN stays TRUE throughout the alarm; only switch modes |
| Output floats when alarm cleared | Substitute value not configured | Set technology object → substitute output value = 0.0 |
The hexadecimal error codes that PID_Compact can return to the diagnostic buffer are listed in the PID_Compact V2 function manual, Section "Error handling". The most relevant for this topic are:
| Error code | Meaning |
|---|---|
| 0000 | No error |
| 0080h | Setpoint out of limits |
| 8001h | Invalid process value scaling |
| 8010h | Configuration error — gain / TI / TD invalid |
| 8020h | Permitted output limits violated during commissioning |
13. Functional Safety and Hardwired Interlocks
The patterns in this article are intended for process control of a heater, not for personnel safety. Functional safety on a chamber typically requires:
- A hardwired overtemperature thermostat wired in series with the heater contactor.
- A safety relay (for example a SIRIUS 3SK1) that drops the contactor on E-stop, independent of the S7-1200.
- A second independent temperature sensor (redundant) feeding the safety relay.
- Compliance with IEC 60204-1 and, where applicable, IEC 61508 / ISO 13849 on the safety function.
The S7-1200 family does not provide SIL-rated I/O for the safety function itself. The PLC is permitted to issue a request to the safety system; the safety system performs the de-energize. See the S7-1200 System Manual, Chapter "Safety of Electronic Control Systems", for the recommended architecture.
14. Migration Notes — PID_Compact V1 vs V2
Projects originally built with PID_Compact V1 (TIA Portal V13 / V14) behave differently:
| Feature | V1 (deprecated) | V2 (current) |
|---|---|---|
| Manual mode input | ManualEnable only | ManualEnable + ManualValue + Mode write |
| Reset input | Not present | Available, clears integral in one cycle |
| Mode = 3 (substitute) | Not available | Available, output set to configured substitute |
| Tuning panel | Basic auto-tune | Pre-tuning + fine-tuning with progress feedback |
| CPU firmware | V4.0 | V4.0 minimum, V4.2 recommended |
For V1 projects, the equivalent of Solution 1 is to write 0.0 to ManualValue and assert ManualEnable; the equivalent of Solution 2 is to issue a Retain → Reset on the technology object. V1 is deprecated; plan a migration to V2 for new projects.
15. Field-Proven Variants
15.1 Multiple PID loops with a shared alarm
A multi-zone oven may use several PID_Compact instances. Aggregate the safety stop into a single tag and wire it to each instance's ManualEnable. For HMI display, expose each instance's Mode tag so the operator can see which zone is in manual.
15.2 Bumpless transfer on alarm clear
To prevent a step on returning to automatic mode, copy the current ManualValue into the integral term before dropping ManualEnable. PID_Compact V2 performs this automatically when anti-windup is enabled (the default), but for very fast loops (sub-second) you can additionally clamp the I-component with a custom FB.
15.3 HMI-side forced manual
If the HMI must be able to put the loop in manual (operator override), expose the ManualEnable and ManualValue tags as HMI tags and OR them with the safety stop:
"iDB_PID".ManualEnable := "DB_Alarms".bAnySafetyStop
OR "DB_HMI".bOperatorManual;
IF "DB_Alarms".bAnySafetyStop THEN
"iDB_PID".ManualValue := 0.0;
ELSIF "DB_HMI".bOperatorManual THEN
"iDB_PID".ManualValue := "DB_HMI".rOperatorMV;
ELSE
"iDB_PID".ManualValue := 0.0; // ignored while ManualEnable = FALSE
END_IF;
Safety takes priority: while a safety alarm is asserted the operator input is ignored and the value is forced to 0.0 %.
16. Summary
Disabling the PID_Compact block via its EN input does not zero the output and is unsafe as a safety shut-off mechanism. The integrator state is retained, and the next enable cycle can produce a kick. The four approved methods are:
- Switch to manual mode (
ManualEnable= TRUE,ManualValue= 0.0) while leaving EN TRUE. - Pulse the
Resetinput to clear the integral, then leave the loop in manual at 0.0 %. - Override the actuator output downstream while pulsing Reset on the alarm-clear edge.
- Switch
Modeto 3 (substitute output value) with the substitute preconfigured to 0.0 %.
All four are non-intrusive to the loop dynamics and survive a CPU STOP transition cleanly. Pair any of them with a hardwired safety contactor for compliance with machinery-safety standards.
17. FAQ
Why does my S7-1200 PID_Compact output stay ON after I disable the EN input?
The PID_Compact V2 block retains its internal integrator value when EN transitions to FALSE; the previously computed manipulated variable stays on the output until the next cycle writes it. Always control the output via ManualEnable/ManualValue or Mode = 3 instead of EN.
How do I clear the integral component in PID_Compact V2.2?
Drive the Reset input TRUE for one OB1 cycle. A rising-edge trigger on the alarm-clear transition is the typical implementation. PID_Compact then sets the integrator to 0.0 so the loop restarts from a known state.
Can I keep the PID_Compact block enabled (EN = TRUE) and still force the heater output to zero on alarm?
Yes. Assert ManualEnable = TRUE and write 0.0 to ManualValue. The block continues to execute, anti-windup remains active, and the manipulated variable is clamped to 0.0 %. Drop ManualEnable on alarm clear.
What is Mode = 3 on PID_Compact, and when should I use it?
Mode = 3 is "substitute output value". The block writes the substitute value configured in the technology object (default 0.0 %) to the output and replaces the integrator. Use Mode = 3 when you want a single-mode switch instead of writing both ManualEnable and ManualValue.
Does toggling PID_Compact EN to FALSE satisfy safety requirements for a heater?
No. EN toggling is a control-loop function, not a safety function. Heaters driving personnel-accessible chambers must be de-energized by a hardwired contactor controlled by an independent safety relay (e.g. SIRIUS 3SK1) and a redundant thermostat, per IEC 60204-1.