Configuring S7-1200 Cascade PID for Level and Flow Limiting

David Krause15 min read
S7-1200SiemensTutorial / How-to
Licensed PE Working through this on a live machine? A Maine-licensed engineer can take it from here — included with IMD hardware, by the hour for everything else. Book an engineer

Problem Overview: Level Control with a Hard Flow Cap

The standard single-loop PID use case on a SIMATIC S7-1200 is straightforward: a process variable (PV) is measured, a setpoint (SP) is supplied, and the controller drives a final control element. The original system uses one PID_Compact block to hold a tank level by positioning a control valve. The operator then requested an additional constraint: a hard cap on the maximum flow rate that the valve can pass, in m³/h.

Implementing this on a Siemens S7-1200 (CPU 1214C DC/DC/DC) under TIA Portal V11 Update 2 requires either a configurable output limit on the existing PID or a true cascade of two PID_Compact blocks. Both approaches are valid; the choice depends on whether the flow cap is a slow supervisory limit (Option A) or a fast, hard-responding constraint (Option B). This article documents the hardware, the PID_Compact parameter set, working SCL code for both options, a tuning sequence, and a troubleshooting matrix.

Why a Cascade Is Often the Right Answer

Clamping the master output to a flow value does work, but if the level setpoint changes drastically, the flow loop will see a step change in setpoint and overshoot. A true cascade — where the inner flow loop tracks its setpoint continuously — removes this overshoot and gives a much faster recovery when the level setpoint is changed, when the incoming feed changes, or when the valve characteristic drifts. The same pattern is used in DCS systems (Honeywell, Emerson DeltaV, ABB 800xA) and is exposed in the S7-1200 through two PID_Compact instances and a small SCL wrapper.

Prerequisites and Hardware

Item Specification Notes
CPU SIMATIC S7-1200, CPU 1214C DC/DC/DC (6ES7214-1AE30-0XB0) Firmware V3.0 or higher; TIA V11 supports up to V4.x
Engineering TIA Portal V11 Update 2 (or later) with STEP 7 Basic Project must be migrated if opened in V13/V14
Flow transmitter SITRANS MAG5000 (Siemens 7ME6910-1AA30-1AA0) 4–20 mA + HART, 24 V DC loop-powered, ±0.4 % of rate accuracy
Level transmitter Hydrostatic, ultrasonic, or guided-wave radar (e.g. SITRANS P500, Probe LU) 4–20 mA into SM 1231
Control valve Pneumatically actuated with positioner, or electric actuator (e.g. SIPART PS2) 4–20 mA input from SM 1232
Analog input SM 1231 AI4 × 13-bit (6ES7231-4HD32-0XB0) or AI8 Two channels: level and flow
Analog output SM 1232 AQ2 × 14-bit (6ES7232-4HB32-0XB0) or AQ4 One channel: valve command

The 1214C has two on-board analog inputs (0–10 V only) which are not suitable for a 4–20 mA loop without an external 500 Ω resistor. Use a signal module instead. Reference the Siemens Industry Online Support portal for the current S7-1200 system manual entry ID 91696622.

Cascade Control Architecture on the S7-1200

The loop is split into two SISO controllers running at the same OB1 cycle:

  1. Outer (master) loop: PV = tank level (%), SP = level setpoint (%), Output = flow setpoint (m³/h).
  2. Inner (slave) loop: PV = measured flow (m³/h), SP = outer-loop output (m³/h), Output = valve position (%).

The inner loop runs 3–10× faster than the outer loop in tuning. On the S7-1200 both blocks run in OB1 (cyclic, default 100 ms). When faster inner-loop dynamics are needed, move the slave PID_Compact into a fixed-time OB (e.g. OB30 at 10 ms) — this is supported on the 1214C firmware V3.0 and above.

Field note: The Mag5000 has a low-flow cutoff (factory default ~0.1 m/s velocity). Verify that the cutoff does not mask real flow during the tuning ramp. The Mag5000 totalizer must be configured in forward only mode if reverse flow is impossible, otherwise the internal integrator will drift when the valve closes.

Option A: Single PID with Output Clamping

If the flow cap is a soft limit (e.g. the customer wants the pump not to exceed 50 m³/h but a transient overshoot of 55 m³/h for 2 seconds is acceptable), use one PID_Compact and clamp the output using the built-in OutputLimit_High input. This requires no SCL code beyond wiring.

PID_Compact input Source Typical value
Setpoint HMI tag, e.g. i_LevelSP 50.0 %
Input Scale IW96 to % from SM 1231 channel 0 0.0–100.0 %
SetpointLimit_High HMI tag, fixed at 100 % 100.0
SetpointLimit_Low Fixed at 0 % 0.0
OutputLimit_High HMI tag, e.g. r_MaxFlowSP 50.0 m³/h
OutputLimit_Low Fixed at 0 0.0

Because Output is a flow setpoint in m³/h, the actuator scaling must be handled externally: take PID_Master.OutputPerc and rescale it through a NORM_X / SCALE_X pair to drive the valve via SM 1232 (0–27648 → 0–100 % valve position). The OutputLimit_High directly limits the flow setpoint, so the valve cannot command a flow above the cap.

Limitations of Option A

  • Disturbance rejection is slow: a step in upstream pressure can push the flow above the cap for several seconds while the level error decays.
  • Valve hysteresis and non-linearity are visible at the flow loop level because there is no inner regulator to linearize them.
  • Dead time from valve stroking adds directly to the level loop.

For these reasons, Option B (true cascade) is the recommended architecture for any process where the flow cap is a contractual or safety constraint.

Option B: True Cascade with Two PID_Compact Blocks

Instantiate PID_Compact_1 (master, level → flow SP) and PID_Compact_2 (slave, flow → valve %). Both blocks ship with the STEP 7 Basic installation and require no extra library.

Tag and Instance DB Layout

Create a shared data block (DB10) with the following tags. All values are REAL unless noted.

DATA_BLOCK "ProcessData"
VERSION : 0.1
NON_RETAIN
  STRUCT
    r_LevelPV       : REAL;   // % from level xmtr
    r_LevelSP       : REAL;   // % from HMI
    r_FlowPV        : REAL;   // m3/h from Mag5000
    r_FlowSPmax     : REAL;   // hard cap from HMI (m3/h)
    r_ValveOut      : REAL;   // % to SM 1232 AQ
    b_MasterAuto    : BOOL;   // 1 = auto, 0 = manual
    b_SlaveAuto     : BOOL;
    r_MasterManual  : REAL;   // manual flow SP (m3/h)
    r_SlaveManual   : REAL;   // manual valve %
    r_CascadeOn     : REAL;   // 1.0 = cascade, 0.0 = slave direct
  END_STRUCT;
END_DATA_BLOCK

Master PID_Compact Configuration (TIA V11)

Configuration field Value Reason
Input scaling — lower / upper 0.0 / 100.0 Level in %
Setpoint scaling — lower / upper 0.0 / 100.0 Level SP in %
Output scaling — lower / upper 0.0 / 100.0 Output in m³/h, scaled in HMI
OutputLimit_High Tag r_FlowSPmax Hard cap on flow setpoint
OutputLimit_Low 0.0 No reverse flow
Retain.CtrlParams.Gain 1.0 (initial) Tune in step 3 below
Retain.CtrlParams.Ti 20.0 s (initial) Tune in step 3
Retain.CtrlParams.Td 0.0 s Level loop is generally PI only
Retain.CtrlParams.InputScaling.UpperPointIn / UpperPointOut 27648 / 100.0 SM 1231 raw to %

Slave PID_Compact Configuration

Configuration field Value
Input scaling — lower / upper 0.0 / r_Mag5000_FullScale (e.g. 100.0 m³/h)
Setpoint scaling — lower / upper 0.0 / 100.0
Output scaling — lower / upper 0.0 / 100.0
OutputLimit_High 100.0 (valve fully open cap)
OutputLimit_Low 0.0
Retain.CtrlParams.Gain 0.5 (initial, often negative on direct-acting valves)
Retain.CtrlParams.Ti 2.0 s (initial)
Retain.CtrlParams.Td 0.0 s

Action sign — this is the most common commissioning error. If opening the valve increases flow, the slave is direct-acting (Gain > 0). If a pneumatic valve with an air-to-close actuator is used, opening the signal decreases flow, and the slave must be configured as reverse-acting (Gain < 0). The PID_Compact Config.InputScaling and Config.OutputScaling invert the sign if you swap upper and lower values, but the cleanest way is to set Retain.CtrlParams.Gain negative for a reverse-acting loop.

SCL Wrapper for Cascade and Bumpless Transfer

The wrapper sits in OB1 between the two PID_Compact blocks. It performs three jobs: (1) select cascade or slave-only mode, (2) pass master output to slave setpoint with hard clamp, (3) drive the analog output with the slave OutputPerc value.

// Cascade wrapper for S7-1200, TIA V11
// Author: process automation note
FUNCTION_BLOCK "CascadeLevelFlow"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 1.0
   VAR_INPUT
      i_MasterSP   : REAL;   // %
      i_LevelPV    : REAL;   // %
      i_FlowPV     : REAL;   // m3/h
      i_FlowSPmax  : REAL;   // m3/h
      i_CascadeOn  : BOOL;
      i_MasterAuto : BOOL;
      i_SlaveAuto  : BOOL;
      i_MasterMan  : REAL;   // m3/h
      i_SlaveMan   : REAL;   // % valve
   END_VAR
   VAR_OUTPUT
      q_ValveOut   : REAL;   // % 0..100
      q_FlowSP     : REAL;   // m3/h, clamped
      q_MasterOut  : REAL;   // m3/h, unclamped
   END_VAR
   VAR
      // placeholder for inlined PID_Compact calls
   END_VAR
BEGIN
   // ---- Master mode selection ----
   IF #i_MasterAuto THEN
      "PID_Compact_1".ManualEnable := FALSE;
      "PID_Compact_1".Setpoint      := #i_MasterSP;
      "PID_Compact_1".Input         := #i_LevelPV;
      "PID_Compact_1".OutputLimit_High := #i_FlowSPmax;
   ELSE
      "PID_Compact_1".ManualEnable := TRUE;
      "PID_Compact_1".ManualValue  := #i_MasterMan;
   END_IF;

   // ---- Pass master output (clamped by OutputLimit_High already) to slave SP ----
   #q_MasterOut := "PID_Compact_1".Output;
   #q_FlowSP    := "PID_Compact_1".Output;   // already in [0 .. FlowSPmax]

   // ---- Hard redundancy clamp in case OutputLimit is misconfigured ----
   IF #q_FlowSP > #i_FlowSPmax THEN
      #q_FlowSP := #i_FlowSPmax;
   END_IF;
   IF #q_FlowSP < 0.0 THEN
      #q_FlowSP := 0.0;
   END_IF;

   // ---- Slave mode selection (cascade or direct) ----
   IF #i_SlaveAuto THEN
      "PID_Compact_2".ManualEnable := FALSE;
      IF #i_CascadeOn THEN
         "PID_Compact_2".Setpoint := #q_FlowSP;
      ELSE
         // direct mode: slave follows a local flow SP from HMI
         "PID_Compact_2".Setpoint := #i_MasterMan;
      END_IF;
      "PID_Compact_2".Input := #i_FlowPV;
   ELSE
      "PID_Compact_2".ManualEnable := TRUE;
      "PID_Compact_2".ManualValue  := #i_SlaveMan;
   END_IF;

   #q_ValveOut := "PID_Compact_2".OutputPerc;
END_FUNCTION_BLOCK

The slave's OutputPerc is already in the 0–100 % range. Scale it to the SM 1232 raw value:

// In OB1, after the cascade FB call
"DB10".r_ValveOut  := "CascadeLevelFlow".q_ValveOut;
"AQW80"            := REAL_TO_INT("CascadeLevelFlow".q_ValveOut * 276.48);
// 0..100 % valve → 0..27648 raw → 0..20 mA on the SM 1232

Anti-Windup and Bumpless Transfer

The PID_Compact block has built-in anti-windup: the integral action stops accumulating when the output saturates at OutputLimit_High or OutputLimit_Low. With TIA V11 this is enabled by default and cannot be disabled in the configuration UI. Verify by looking at the Tuning tab in the PID_Compact configuration editor: the Anti-windup box is greyed out and checked.

Bumpless transfer from manual to auto must be implemented manually. Before the operator flips the mode selector, the ManualValue must be set equal to the current Output. The wrapper above assumes the HMI does this — in WinCC Basic on the Panel KTP600, add a value-change event on the auto bit that pre-loads the manual tag from the controller's output.

Commissioning and Tuning Sequence

Always tune from the inside out. A poorly tuned inner loop cannot be compensated by the outer loop.

  1. Step 1 — Slave loop manual check. Put PID_Compact_2 in manual, drive the valve from 0 to 100 % in 10 % steps, record the flow at each step. This confirms valve action (direct or reverse) and gives the process gain Kp. The SITRANS MAG5000 should be set to its engineering units (m³/h) using SIMATIC PDM or the local HMI on the transmitter.
  2. Step 2 — Slave loop auto tune. Switch the slave to auto, set a flow setpoint of 50 % of full scale, enable the “Tune” button on the PID_Compact commissioning tab. The block runs a step response, calculates Kc, Ti, Td, and writes them to the Retain.CtrlParams structure. Initial Kc is typically 0.2–1.0, Ti 1–5 s for a flow loop.
  3. Step 3 — Master loop auto tune. With the slave on auto and in cascade, set the master setpoint to the current level, then trigger the master tune. The level process is generally much slower, expect Ti 20–60 s and Kc 0.5–3.0. The Mag5000 low-flow cutoff can fool the master tune if level changes during the test cause the flow to cross the cutoff — raise the cutoff to 1 % of full scale for the duration of the tune.
  4. Step 4 — Limit verification. Lower r_FlowSPmax to 60 % of the actual observed flow. The level controller must back off, the valve must close, and the flow must settle at the new cap within 3–5 slave time constants. If the flow overshoots, increase slave Kc or shorten Ti.
  5. Step 5 — Disturbance test. Drop the level setpoint by 20 % and verify the flow ramps to the cap and stays there until the level approaches the new SP. No flow overshoot above the cap is acceptable. This is the canonical cascade test from any PID theory reference and matches the behavior expected in commercial DCS systems.
Safety note: The 1214C digital outputs are DC 24 V sourcing; if the valve is fail-closed (most pneumatic control valves), removing power to the PLC closes the valve and the tank can overfill if the inlet flow is not separately interlocked. Wire an independent high-level switch to a digital input and program a hardware-level shutdown in OB100 (warm restart) and OB1 that closes the valve on high-high level regardless of PID state. This is in line with IEC 61511 SIL 1 thinking for tank level service.

Verification Procedure

After commissioning, the following checks must pass before handover:

Test Procedure Pass criterion
Setpoint tracking Step level SP from 30 % to 70 % Level reaches 70 % within 3 time constants, no overshoot > 5 %
Flow cap adherence Set FlowSPmax = 50 m³/h, command 100 % level SP Flow stays ≤ 50.5 m³/h for the full transient
Bumpless transfer Switch master to manual, change manual SP by 10 %, switch back to auto Valve does not move on the auto transition (output step < 1 %)
Mag5000 totalizer sanity Open valve to constant 30 m³/h for 60 s Totalizer increases by 0.5 m³ within ± 2 %
Sensor break response Disconnect level loop at the terminal block PID goes to configured fault output; valve drives to a safe position (closed)

Troubleshooting Matrix

Symptom Likely cause Action
Flow spikes above the cap during level SP step changes Slave loop is in manual, or slave Kc is too low Confirm slave AutoEnable = TRUE; raise slave Kc in 20 % steps
Level oscillates slowly around the setpoint Master Ti is too short, or master is fighting with the slave Double Ti; verify OutputLimit_High on master equals FlowSPmax
Valve does not move at all Wrong action sign: Gain set positive on a reverse-acting valve Toggle Config.InputScaling upper/lower, or set Kc negative
Flow reads negative in HMI Mag5000 signal wiring reversed (terminals 5/6 swapped) Power down, swap, restart. Verify in PDM
Tune button is greyed out PID_Compact instance has Config.Mode = 0 (inactive) or the block is in manual Set Mode = 3 (auto), Mode = 1 (pretuning) for the slave first
Output stuck at 100 % OutputLimit_High left at default 100 % while flow cap is lower Wire r_FlowSPmax directly to OutputLimit_High on the master
Integral winds up and overshoots after a long disturbance Output limit not active because the SP clamp is on the wrong side Verify SetpointLimit_High/Low are not limiting the wrong direction
TIA V11 will not let me edit Retain.CtrlParams.Gain The tag is in the retentive area; switch the view in the DB to Retain or use the PID_Compact configuration editor Use the editor in the project tree, or right-click the DB and choose “Open in editor”
Hard to read flow rate Mag5000 configured in US gpm or in pulses per gallon, not in m³/h Re-engineer with PDM or the local three-key keypad; restart the transmitter

Why the Original Idea of a “Second PID in Cascade” Was Correct

Moving from a single-loop S7-1200 application to a cascade is not a luxury — it is the standard solution in any DCS for the exact problem described: a slow outer variable (level) that must respect a hard inner constraint (flow). The same architecture is used in boiler drum level control (level/flow cascade with three-element trim), fired-heater pass temperature control, and distillation reflux control. The S7-1200 PID_Compact is functionally equivalent to a single-loop block in a DCS, so the same pattern applies unchanged. National Instruments' PID theory primer and the Wikipedia PID article cover the tuning math if deeper theory is needed.

Optional Extensions

Three enhancements are worth considering once the basic cascade is stable:

  • Feedforward from the inlet flow: add a bias to the master output proportional to a measured inlet flow. This eliminates the level error caused by a step in the inflow without waiting for the level to drift.
  • Anti-windup on the inner loop during cascade breaks: hold the slave's ManualValue at the last output when the operator opens the cascade break switch.
  • Totalizer cross-check: in parallel with the Mag5000 built-in totalizer, integrate the measured flow in OB35 (cyclic interrupt, 100 ms) and alarm if the two diverge by more than 2 %. This catches Mag5000 firmware resets and sensor drift.

Field-Proven Caveats

Two issues show up repeatedly on the S7-1200 platform that do not show up in larger PLCs:

  1. The CPU 1214C has limited work memory; two PID_Compact blocks plus the SCL wrapper fit, but adding a third (e.g. temperature cascade) can push the work memory close to 75 % — the project will compile but may fail to go to RUN if the retain area overflows. Always test go-online after adding a third PID.
  2. The on-board analog inputs of the 1214C are 0–10 V only. If a 4–20 mA level transmitter is wired there with a 500 Ω resistor, the loop becomes single-faulted (one resistor failure kills the loop) and breaks the SIL assumption. Use an SM 1231 module instead.

Can the S7-1200 PID_Compact do cascade directly, or do I need extra code?

PID_Compact itself is a single-loop SISO block. Cascade is implemented by instantiating two blocks and writing the master Output into the slave Setpoint, with the OutputLimit_High on the master used to cap the flow setpoint. The SCL wrapper shown above handles mode selection, the hard clamp, and bumpless transfer in roughly 40 lines.

What is the difference between OutputLimit_High and SetpointLimit_High on PID_Compact?

SetpointLimit_High/Low clamps the setpoint the operator can enter (the “knob” limit). OutputLimit_High/Low clamps the controller output (the “valve” limit). For a flow cap you want OutputLimit_High on the master set to the cap value, because the controller output is what becomes the slave's setpoint.

Do I need to tune the inner and outer loops separately?

Yes. Tune the slave (flow) loop first with the master in manual, then tune the master (level) loop with the slave in auto. The slave must be 3–10× faster than the master; if the slave is slower than the master, the cascade will oscillate no matter how good the individual tuning is.

Why does the valve keep moving after I stop the pump?

The PID_Compact block is still active and will keep integrating the level error. Either put the master in manual when the pump is off, or use the SetpointLimit_Low input to hold the master output at 0 when the inlet flow is zero. The latter is cleaner and is the typical DCS practice.

Can I run PID_Compact in OB30 to get a faster inner loop?

Yes, on the 1214C with firmware V3.0 or above. Put the slave PID_Compact in OB30 and set the OB30 cycle to 10–50 ms. The master stays in OB1. This is the standard way to give the inner loop the speed it needs without overloading the cyclic task.

Back to blog