Overview
The PID_Compact instruction shipped with the S7-1200 CPU firmware and TIA Portal is the standard closed-loop block for temperature, level, flow, and pressure loops. In TIA Portal V13 with firmware V4.x, the block ships as PID_Compact V2.x, which has a stricter enable contract than the older V1.x block used on firmware V3.x. Field engineers most often hit three problems: the block never turns green (Input/Input_PER out of range), an aggressive output that slams to 100% the instant the loop is enabled, and the inability to simulate the V2.x block inside S7-PLCSIM V13. This reference covers the root cause, the working signal ranges, the simulation downgrade path, bumpless transfer, output slew limiting, PWM configuration, and a practical SCL scaffold for adaptive gain.
Prerequisites
- SIMATIC S7-1200 CPU (any V4.x firmware; tested behavior on 1212C, 1214C, 1215C, 1217C, 1500S-compatible 1200G).
- TIA Portal V13 SP1 / V13 Update 9 or later, with PID_Compact V2.x installed from the HSP or library.
- SM1231 analog input module or onboard AI for the differential-pressure (DP) cell.
- For commissioning without real plant: S7-PLCSIM V13 (note the simulation limitation described below).
- Project background OB (typically OB1, OB35 cyclic interrupt at 100 ms for level loops).
PID_Compact Block Architecture
PID_Compact is a self-tuning, fixed-cycle controller with anti-windup, setpoint ramp, output scaling, and three output modes (analog, PWM, motor stepper). The V2.x block exposes a richer I/O image than V1.x, including Input (floating-point process value, % of scaled range), Input_PER (raw peripheral word, e.g. 0–27648), Setpoint, Disturbance, ManualEnable, and a multi-instance Config / Retain / Cycle structure. The controller sub-state machine is exposed on Instance.State (numeric) and Instance.StateString (text), which the operator faceplate reads directly.
| Field | Type | Range / Units | Notes |
|---|---|---|---|
| Input | REAL | −100.0 … +100.0 (%) by default; user-scalable | Engineering units after scaling block |
| Input_PER | INT | 0 … 27648 (unipolar) or ±27648 (bipolar) | Direct from %IW |
| Setpoint | REAL | Same range as Input | User units, e.g. 0–500 mm H₂O |
| Output / Output_PER / Output_PWM | REAL / INT / BOOL | 0–100 % (analog) or 0–100 % duty (PWM) | Mode selected in Config |
| Cycle | TIME | ≥ 0.1 s (PID) / ≥ 0.01 s (PWM) | OB1 default vs. OB35 |
| Retain.CtrlParams.Gain | REAL | 0.0 … +∞ | Tuned value |
| Retain.CtrlParams.Ti / Td | TIME | 0.0 s disables I / D | Integral and derivative time |
Enable Conditions and Input Range
The block refuses to leave the NotEnabled state (faceplate stays gray) when one of the following preconditions is violated:
-
Process value out of range.
Inputmust lie within the configured scale (default −100 % to +100 %, equivalent to the high/low limits ofConfig.InputScaling). A negative-only DP cell mapped to 0–100 % with a transient negative ADC count will trip the check. - Input_PER wiring error. Disconnected or reversed 4-wire DP cell produces 0 counts or 32767 (overflow), both rejected as "out of range." A broken cable produces ±27648 with sign noise, again rejected.
- Setpoint outside scale. If the scale is 0–500 mm and the setpoint is 600 mm, the loop is logically inconsistent and the block stays in Inactive.
- ManualEnable / ManualValue conflict. ManualEnable=TRUE with ManualValue outside the output range also blocks enable.
Diagnosis path:
- Go online, open the PID_Compact instance, and watch the "Status" tab. State 0 = Inactive, 1 = NotEnabled, 2 = Manual, 3 = Automatic. NotEnabled means the input check failed.
- Force
Instance.Inputwith the watch table to a value inside the configured scale. If the block enables, the I/O wiring is the problem. - Inspect the analog module channel: a SM1231 4AI module on the S7-1200 must have Diagnostics disabled for unused channels, otherwise a single open wire on a sibling channel drags the diagnostic interrupt into the input check and freezes the block.
- Confirm the DP cell excitation (24 V) at the terminals. A voltage drop on a long cable produces a calibrated but unstable reading; mechanical noise on a poor connector reads as 0 / 27648 jumps, which the block rejects. Replace the shielded twisted pair and re-terminate at the analog module.
TIA Portal V13 and S7-PLCSIM Compatibility
PID_Compact V2.x cannot be simulated in S7-PLCSIM V13 against an S7-1200 plant. The block is generated, downloaded, and executes, but its internal state never advances past NotEnabled. The root cause is that V2.x requires firmware V4.1 features (specifically the PRD/WRD runtime services for the controller DB) that PLCSIM V13 does not emulate for the 1200. The symptom is identical to a real wiring fault, so a real CPU and a simulated CPU must be diagnosed differently.
| Scenario | Block version | CPU | Result | Fix |
|---|---|---|---|---|
| Real CPU, real I/O | V2.x | S7-1200 FW 4.x | Works | None |
| Real CPU, broken sensor | V2.x | S7-1200 FW 4.x | NotEnabled | Repair wiring / scale |
| PLCSIM V13, V2.x block | V2.x | S7-PLCSIM 1200 | Stuck NotEnabled | Downgrade block to V1.x |
| PLCSIM V13, V1.x block | V1.x | S7-PLCSIM 1200 | Works | Use V1.x |
| PLCSIM V14+ | V2.x | S7-PLCSIM 1200 | Works | Upgrade PLCSIM |
Downgrade procedure:
- Open the project in TIA Portal V13 SP1.
- Right-click the PID_Compact instance → Change to version → select V1.x from the list.
- Re-compile and re-download. The instance DB retains scaled values; I/O names and Config substructure are preserved.
- Confirm
Instance.Versionshows V1.0 in the watch table.
Long-term recommendation: upgrade the engineering environment to TIA Portal V15.1 or later and PLCSIM V15.1, where the V2.x and V3.x blocks simulate cleanly on the 1200 plant. The Siemens support entry 109740509 - PID_Compact V2 in S7-PLCSIM confirms the limitation and lists the supported PLCSIM versions.
Wiring and Signal Conditioning for DP Cells
A differential-pressure level loop uses a DP cell with H (high) leg at the bottom tap and L (low) leg vented. Standard 4-wire excitation is 24 V at 4 mA loop, 4–20 mA return on a single pair. The SM1231 AI4 (6ES7231-4HD32) accepts 4–20 mA on channel 0 when configured for "Current 4-wire" with the 500 Ω sense resistor on the terminal block.
- Use shielded twisted pair, drain grounded at the cabinet end only.
- Route the analog cable in a separate conduit, at least 200 mm from VFD output cables and contactor coils.
- Bridge the unused analog channel with a 100 Ω resistor between + and − to defeat floating input noise on adjacent channels.
- Scale the input in PID_Compact:
Config.InputScaling.HighLimit = 500.0(mm H₂O at 20 mA),LowLimit = 0.0(at 4 mA). The scaledInputin % corresponds to (mm / 500) * 100.
Output Behavior: Bumpless Transfer and Slew Rate Limiting
When PID_Compact switches from manual to automatic, the I-term is pre-loaded with the current output, producing a bumpless transition. If the loop is enabled from cold (output = 0%, process value far below setpoint), the integral wind-up is zero and the proportional path can drive the output to 100 % in a single cycle when the gain is high. This is normal closed-loop behavior, not a bug, and it is the most common complaint in tank level applications where the PV starts empty and SP is mid-range.
Three correction strategies, in order of priority:
- Pre-position in manual. Hold the loop in Manual, drive the output to a value that produces PV ≈ SP (e.g. open the inlet valve until the level reads near the setpoint), then flip to Automatic. The I-term is initialized to the manual output, and the first automatic step is near zero error.
-
Conservative tuning. Reduce
Gainby 50 %, increaseTiby 2×, and disableTdfor the first pass. Tune by Ziegler–Nichols open-loop step or use the built-in Controller tuning panel (PID_Compact V2.x: faceplate → Tuning → "Pretuning" / "Fine tuning"). The tuner injects a step, identifies the process gain and time constant, and writes conservative defaults. -
Output rate limiter. Add an SCL block between
Instance.Outputand the analog output that caps the per-cycle change. A typical 0.5 %/s limit on a 100 % range gives a 200-second ramp, which is well within the time constant of a tank but eliminates the perceived "100 % slam."
SCL rate-limiter pattern:
// Rate-limited output
IF bEnable THEN
IF rPID_Out > rLastOut + rMaxStep THEN
rOut := rLastOut + rMaxStep;
ELSIF rPID_Out < rLastOut - rMaxStep THEN
rOut := rLastOut - rMaxStep;
ELSE
rOut := rPID_Out;
END_IF;
ELSE
rOut := rPID_Out;
END_IF;
rLastOut := rOut;
Call this FB in the same OB as PID_Compact (OB35 at 100 ms). With rMaxStep = 0.05 (%/cycle) the output moves 0.5 %/s. Tie the rate-limiter bypass to a permissive so bumpless recovery from a fault does not slam the valve.
PWM Output Configuration
For a solenoid or proportional valve driven from a digital output, PID_Compact exposes Output_PWM (BOOL) and Output_PWM_Period (TIME). Set the period to 1.0 s for valve duty control, 0.1 s for heater SSR. The duty cycle is the PID output mapped 0–100 %; the BOOL is high for the on-fraction of the period and low for the off-fraction.
- Minimum period 10 ms (CPU cycle-bound) and 100 ms (recommended for valve life).
- Connect
Output_PWMto a digital output wired to the relay/SSR. Add a flyback diode across DC loads. - When OutputMode is PWM, do NOT connect
Output_PERto the analog module; the two paths are mutually exclusive in the Config substructure.
Manual / Automatic Handover and Bumpless Transfer
The block's ManualEnable input and ManualValue (REAL, 0–100 %) drive manual mode. On the rising edge of ManualEnable the block freezes the integral term and holds the output at ManualValue. On the falling edge the block pre-loads the I-term to the current output and resumes automatic. To verify bumpless behavior:
- Force the loop into manual: set ManualEnable=TRUE, ManualValue=40.0, observe the output settle at 40 %.
- Watch
Instance.IntegralSumin the watch table; it tracks the held output. - Drop ManualEnable to FALSE. The output should not jump; the next PID computation begins with the I-term at 40 %.
If a step appears on transition, the block was re-initialized by a CPU restart, a power cycle, or a re-download of the instance DB. Re-trigger bumpless initialization by writing to Instance.Restart = TRUE for one cycle, or by entering manual, holding for at least one OB35 cycle, and releasing.
Adaptive Control with SCL
PID_Compact is a fixed-gain PI/PID controller. It does not include gain scheduling, model-reference adaptive control, or auto-tuning beyond the built-in pretuning/fine tuning passes. Engineers who need adaptive gain (e.g. a tank with a 5× change in cross-section between the cone and the cylinder, or a nonlinear valve curve) must implement the adaptation externally and overwrite Instance.Retain.CtrlParams.Gain / Ti / Td on a slow update.
A practical gain-scheduling pattern:
FUNCTION_BLOCK FB_AdaptiveGain
VAR_INPUT
rPV : REAL; // process value in %
rSetpoint : REAL;
rGainLow : REAL := 0.4;
rGainHigh : REAL := 1.2;
rPV_Threshold : REAL := 60.0; // switch at 60 % level
bUpdate : BOOL;
END_VAR
VAR_OUTPUT
rGain : REAL;
rTi : TIME;
END_VAR
VAR
rLastPV : REAL;
rRampGain : REAL;
END_VAR
BEGIN
// Schedule gain on PV region
IF rPV < rPV_Threshold THEN
rGain := rGainLow;
rTi := T#20S;
ELSE
rGain := rGainHigh;
rTi := T#8S;
END_IF;
// Slew the gain update to avoid step on the loop
rRampGain := rLastPV * 0.9 + rPV * 0.1;
rLastPV := rRampGain;
// Push into PID_Compact retain
IF bUpdate THEN
Instance.Retain.CtrlParams.Gain := rGain;
Instance.Retain.CtrlParams.Ti := rTi;
END_IF;
END_FUNCTION_BLOCK
Calling pattern: invoke FB_AdaptiveGain in OB35 at 100 ms with bUpdate gated by a 5-second timer to avoid writing the retain structure on every cycle. For more advanced schemes (MRAC, self-tuning regulators, fuzzy PID) implement a discrete estimator in SCL and overwrite the controller parameters only on convergence; never write to CtrlParams mid-cycle from OB1.
For time-proportional output (e.g. heater on/off with a window comparator and duty-cycle timer), the recommended path is to keep PID_Compact in PWM mode and let the built-in PWM generator produce the duty cycle. Custom time-proportional logic outside the block is rarely necessary on S7-1200.
Tuning the PID
Sequential procedure for a level loop driven by a 4–20 mA proportional valve:
- Set
Gain = 0.3,Ti = T#30s,Td = T#0s. Hold the loop in manual. - Drive ManualValue to 30 %, record PV for 60 s, then to 60 %, record for 60 s. Compute open-loop gain K = ΔPV / ΔMV (in %/%).
- Compute dead time L and time constant T from the step response.
- Apply Ziegler–Nichols open-loop: Kp = 1.2 * T / (K * L), Ti = 2 * L, Td = 0.5 * L.
- Or run the built-in pretuning (faceplate → Tuning → Pretuning) with the loop in manual and the process at a stable point.
- Switch to automatic with the calculated or tuned values. Watch for overshoot; if overshoot exceeds 10 %, halve Kp and double Ti.
For an integrating process (tank with pump-out), use Ziegler–Nichols closed-loop: increase Kp until sustained oscillation, record ultimate gain Ku and period Pu, then Kp = 0.45 * Ku, Ti = Pu / 1.2, Td = Pu / 8.
Verification
After each change, run the following check sequence:
-
Watch table: confirm
Instance.State= 3 (Automatic) andInstance.StateString= "Automatic". -
Input check:
Instance.Inputreads 0–100 %, matches the SCADA display in engineering units. -
Output check:
Instance.Outputfollows the PID calculation. If OutputMode is analog,Instance.Output_PERreads 0–27648 scaled. If OutputMode is PWM,Instance.Output_PWMtoggles at the configured period. - Step test: bump the setpoint by 5 % and observe rise time, overshoot, settling time. For a 500 mm tank level, target rise time 60–120 s, overshoot less than 5 %.
- Bumpless test: toggle ManualEnable and confirm the output does not step more than 0.5 % at the transition.
- Fault test: disconnect the DP cell. The block should enter NotEnabled (State=1) and not drive the actuator. Reconnect and confirm recovery within two cycles.
Troubleshooting Matrix
| Symptom | Likely Root Cause | Action |
|---|---|---|
| Faceplate stays gray, State=1 | Input out of range | Inspect wiring, scale limits, ADC count |
| Faceplate stays gray, simulation only | PID_Compact V2.x on PLCSIM V13 | Downgrade to V1.x or upgrade PLCSIM |
| Output jumps to 100 % on enable | Large initial error, aggressive Kp | Pre-position in manual, reduce Kp, slew limit |
| Output oscillates | Kp too high, Ti too low | Halve Kp, double Ti, run pretuning |
| Output drifts after setpoint change | Ti = 0 (no integral action) | Set Ti ≥ 0.1 * T_process |
| Output chatters on PWM | Period too short for valve | Increase Output_PWM_Period to ≥ 1 s |
| Manual→Auto steps | Block re-initialized | Set Restart, hold manual 1 cycle, release |
| Adaptive gain is unstable | Retain written every cycle | Gate update to ≥ 5 s, slew gain change |
| PLCSIM 1200 OK, real CPU 1200 stuck | Sensor wiring / ADC overflow | Check 24 V, sense resistor, channel diagnostics |
Why does PID_Compact stay gray (NotEnabled) in TIA Portal V13 even though the input is in range?
If you are simulating with S7-PLCSIM V13 against an S7-1200 plant, PID_Compact V2.x cannot be simulated and stays in NotEnabled regardless of the input value. Downgrade the block to V1.x in TIA Portal (right-click → Change to version), or upgrade to PLCSIM V14 or later where V2.x is supported. On a real CPU, the most common cause is a wiring or scaling fault producing 0 / 27648 / negative counts; replace the cable and verify the analog channel configuration.
How do I stop the PID output from slamming to 100 % when the loop is enabled?
Three-step correction: (1) pre-position the loop in manual to bring the process value near the setpoint, then release to automatic; (2) reduce the gain by 50 % and double the integral time for the first tuning pass; (3) add a rate limiter on the PID output that caps the per-cycle change to 0.5 %/s. PID_Compact supports bumpless transfer internally, so a step on transition indicates the block was re-initialized.
Can I implement adaptive control or time-proportional control with PID_Compact?
Time-proportional (PWM) output is built-in via Output_PWM; set the period to 1.0 s and connect the BOOL to a digital output. PID_Compact does not include gain scheduling or model-reference adaptation, so adaptive control must be implemented externally in SCL: read the PV, compute the scheduled gain and Ti, and overwrite Instance.Retain.CtrlParams.Gain / Ti on a slow (≥ 5 s) update so the loop is not excited by a step in parameters.
Which PID_Compact version should I use for an S7-1200 with TIA Portal V13?
Use PID_Compact V1.x if you need to simulate in S7-PLCSIM V13. Use V2.x (the default) if you are running on a real S7-1200 CPU with firmware V4.1 or later, since V2.x exposes the richer configuration interface and supports the faceplate tuning panel. For long-term projects, upgrade to TIA Portal V15.1 or later, where V2.x simulates cleanly and V3.x is available for new features.
How do I verify that PID_Compact is in Automatic mode after enabling?
Go online, open the PID_Compact instance in the watch table, and read Instance.State (numeric) and Instance.StateString (text). Automatic corresponds to State = 3 with StateString = "Automatic". If the block reads NotEnabled (1) or Manual (2), inspect the input range, setpoint, and ManualEnable inputs to identify the blocking condition before bumping the setpoint.