Overview of Cascade Control for Twin-Tank Level Systems
Cascade control is a multi-loop control strategy where the output (manipulated variable) of a primary (master) controller becomes the setpoint of a secondary (slave) controller. In a twin-tank hydraulic system the controlled variable is typically the level of Tank 2, and the secondary variable is the level of Tank 1. Because Tank 1 responds faster to changes in pump flow, it forms the inner loop and is tuned first; Tank 2 forms the outer loop and uses the master controller to reject disturbances seen only at the downstream tank.
This reference covers implementation on a SIMATIC S7-300 CPU programmed with TIA Portal V13, including project migration from legacy STEP 7, PID block selection (CONT_C / FB41, PID_Compact, PID_CP, PID_ES), process-value input selection (PV_PER vs. PV_IN), wiring of master manipulated variable to slave external setpoint, PWM actuator integration, and the recommended inner-to-outer tuning sequence.
Prerequisites
- Controller: SIMATIC S7-300 CPU 31x (tested with CPU 315-2 PN/DP and CPU 317-2 PN/DP). S7-300 supports CONT_C / FB41 and the TIA Portal PID instruction set.
- Software: TIA Portal V13 (V13 SP1 or V13 SP2 strongly recommended for stable CONT_C migration). For PID_Compact / PID_CP / PID_ES, the optional "PID Professional" add-on must be installed.
- I/O: At least one analog input (AI8x12Bit, 6ES7331-1KF02-0AB0 or equivalent) for the two level sensors, and one analog output (AO8x12Bit, 6ES7332-5HF00-0AB0) if the pump accepts a 0–10 V reference. For PWM pumps, a digital output (DO16, 6ES7322-1BH01-0AA0) plus a solid-state relay or driver stage is required.
- Sensors: 4–20 mA hydrostatic level transducers with 24 V loop power. Tank 1 full-scale ≈ 12 in. water column; Tank 2 full-scale ≈ 6 in. water column.
- Actuator: 12 V or 24 V DC diaphragm pump driven through a PWM stage (TIP120, BTS7960, or DRV8871 driver) whose duty cycle maps 0–100 % to 0–5 V or 0–10 V reference.
- Engineering time: Allow at least four hours for step-test identification, inner-loop tuning, and outer-loop trim.
Cascade Control Theory for Twin Tanks
The two-tank system is a textbook cascade application because the inner loop (Tank 1 level ↔ pump flow) is roughly three to ten times faster than the outer loop (Tank 2 level ↔ Tank 1 outflow). When disturbance enters the inner loop (pump line-voltage sag, partial clogging, valve hysteresis), the slave controller rejects it before it propagates to Tank 2.
| Loop | Controlled Variable | Setpoint Source | Manipulated Variable | Typical Time Constant |
|---|---|---|---|---|
| Inner (slave) | Tank 1 level (PV_in1) | Master MV (= Tank 1 SP) | Pump duty cycle | 1–3 s |
| Outer (master) | Tank 2 level (PV_in2) | Operator / recipe | Master LMN → slave SP | 8–30 s |
The two loops are coupled by a single wire: the master's LMN output is fed into the slave's SP_EXT (or SP_INT in cascade mode). The master never drives the actuator directly.
PID Block Selection in TIA Portal V13
Multiple PID instruction blocks are available. Choose based on actuator type, project age, and required features.
| Block | Library / Source | Best Use | Analog Output | Pulse Output | External SP |
|---|---|---|---|---|---|
| CONT_C (FB41) | Standard library, legacy STEP 7 | Migration, generic continuous control | Yes (LMN_PER) | No (requires external pulse gen.) | Yes (SP_EXT) |
| PID_Compact (FB1100…) | TIA Portal built-in | Modern projects, auto-tuning | Yes | Yes (configurable) | Yes (via Config.InputScaling) |
| PID_CP (FB1101…) | PID Professional add-on | Continuous, multi-loop cascade master | Yes | No | Yes (SP_Ext) |
| PID_ES (FB1102…) | PID Professional add-on | Step / pulse output (valve, relay) | Limited | Yes (Q_PULSE, Q_PWM) | Yes (SP_Ext) |
LMN of the master to SP_INT of the slave and select "Automatic mode with external setpoint" (cascade) on the slave. PID_CP / PID_ES are not required for a continuous 0–100 % signal.Project Setup in TIA Portal V13
- Open TIA Portal and create a new project named "TwinTank_Cascade_V13".
- Add a new device: Controllers → SIMATIC S7-300 → CPU 315-2 PN/DP (or your model).
- Insert the rack and add the AI8 module in slot 4 and AO4 module in slot 5. The CPU auto-assigns I addresses (e.g.,
IW96for Tank 1,IW98for Tank 2,QW80for analog MV if used). - Open Project tree → PLC_1 → Program blocks and add a new FB ("Cascade_Control") of type SCL or LAD/FBD.
- Add two instances of
CONT_Cfrom the Instructions → Technology → PID Control → Compact PID palette, or pull in FB41 from the legacy standard library if migrating. - Create a global DB "Tank_Data" with the following tags:
DATA_BLOCK "Tank_Data"
{ S7_Optimized_Access := 'FALSE' }
VERSION : 0.1
NON_RETAIN
STRUCT
PV_Tank1_REAL : REAL; // Level Tank 1, inches
PV_Tank2_REAL : REAL; // Level Tank 2, inches
SP_Tank2_REAL : REAL; // Operator SP, inches
MV_Master_REAL : REAL; // 0–100 %
MV_Slave_REAL : REAL; // 0–100 %
PWM_Duty_INT : INT; // 0–1000 (×0.1 %)
Manual_Auto : BOOL; // 0=Auto, 1=Manual
Pump_Enable : BOOL;
END_STRUCT;
END_DATA_BLOCK
Wiring the Master to the Slave (Cascade Connection)
The defining wiring of cascade control is a single connection from the master LMN to the slave external setpoint.
- Master (outer) loop:
CONT_Cinstancei_Master-
PV_IN← "Tank_Data".PV_Tank2_REAL (already scaled fromIW98via SCALE block) -
SP_INT← "Tank_Data".SP_Tank2_REAL (operator entry) -
MAN← "Tank_Data".Manual_Auto -
LMN→ wires to slaveSP_EXT
-
- Slave (inner) loop:
CONT_Cinstancei_Slave-
PV_IN← "Tank_Data".PV_Tank1_REAL -
SP_EXT←i_Master.LMN← this is the cascade wire -
LMN→ "Tank_Data".MV_Slave_REAL (and onward to PWM generation)
-
SP_INT instead of SP_EXT, the slave is in internal setpoint mode and the cascade is broken. Always set the slave to "Cascade / External SP" (in TIA: parameter Config.SP_Ext_Mode = TRUE for PID_Compact, or wire the master LMN to SP_EXT for CONT_C and leave SP_INT unused).Process-Value Input: PV_PER vs. PV_IN
| Property | PV_PER | PV_IN |
|---|---|---|
| Data type | WORD (I/O integer, 0–27648) | REAL (IEEE-754 float, engineering units) |
| Pre-scaled by block | Yes (uses PV_FAC / PV_OFF) |
No — you scale it yourself |
| Typical source | Direct %IW word |
Output of SCALE / NORM_X block |
| Recommended for cascade | Simple, fast — two wires only | Use when you need AI diagnostics, replacement-value handling, or HMI scaling |
PV_PER is a 16-bit word that mirrors the raw analog input (0 to 27 648 for Siemens AI modules in 4–20 mA range). PV_IN is a 32-bit REAL (floating-point) number already in engineering units (e.g., inches of water). For students, a WORD is a 16-bit unsigned integer; a REAL is a 32-bit IEEE-754 single-precision float that can represent fractional values like 3.4571.
For the twin-tank project, scaling the analog input to inches is best done outside the PID block so that HMI tags, alarms, and recipe values all share a common engineering range. Therefore prefer PV_IN:
// In OB1 / cyclic task, before CONT_C calls:
"Tank_Data".PV_Tank1_REAL := NORM_X(
VALUE := IW96, // raw 0–27648
MIN := 0.0,
MAX := 27648.0
) * 12.0; // 12 in. full scale
"Tank_Data".PV_Tank2_REAL := NORM_X(
VALUE := IW98,
MIN := 0.0,
MAX := 27648.0
) * 6.0; // 6 in. full scale
Scaling the Master Output to Match the Slave Range
When the master outputs a 0–100 % signal (the default CONT_C range) and the slave setpoint is in inches (0–12 in. for Tank 1), a linear range converter is required so that 100 % from the master corresponds to the physical upper limit of the slave's process variable.
// Linear mapping: Master LMN [%] → Tank 1 SP [in.]
"Tank_Data".SP_Tank1_REAL := ("Tank_Data".MV_Master_REAL / 100.0) * 12.0;
// This value is then wired to slave SP_EXT via CONT_C configuration.
This is the "scaler between primary output and secondary input" the original poster asked about. It is a simple two-point linearization: SP_Tank1 = (LMN/100) × SP_Tank1_max. For non-linear pumps, replace with a polynomial block or a lookup table in a separate FB.
PWM Output Generation for the DC Pump
CONT_C does not produce a pulse-width modulated output directly. Add a PWM generator block between the slave's LMN (0–100 % REAL) and the digital output word that drives the pump's switching transistor.
- Convert the REAL percentage to an integer count for a PTO/PWM output, or drive a software PWM task in OB35 (cycle 100 ms).
- Use a 1 kHz PWM (1 ms period) for diaphragm pumps ≤ 12 V, or 100 Hz for larger brushed DC pumps.
- Wire to a digital output module channel Q0.0 of the SM322 DO16.
// In OB35 (cyclic interrupt, 100 ms period):
"Tank_Data".PWM_Duty_INT := REAL_TO_INT("Tank_Data".MV_Slave_REAL * 10.0);
// Clamp to 0–1000 (×0.1 %)
IF "Tank_Data".PWM_Duty_INT > 1000 THEN
"Tank_Data".PWM_Duty_INT := 1000;
END_IF;
IF "Tank_Data".PWM_Duty_INT < 0 THEN
"Tank_Data".PWM_Duty_INT := 0;
END_IF;
// Software PWM using time accumulator:
IF "PWM_Acc" < "Tank_Data".PWM_Duty_INT THEN
%QW0.0 := TRUE; // Pump on
ELSE
%QW0.0 := FALSE; // Pump off
END_IF;
"PWM_Acc" := "PWM_Acc" + 10; // Increment by 10 per 100 ms cycle
IF "PWM_Acc" >= 1000 THEN "PWM_Acc" := 0; END_IF;
Tuning the Cascade: Inner Loop First
When tuning a cascade, the inner loop is always tuned first and independently of the outer loop. With the master in manual mode (its output held at a fixed value), the slave is closed against a constant setpoint that equals the steady-state value of Tank 1 level.
-
Step-test the inner loop. Place the master in manual (
MAN := TRUE) and forceMV_Masterto 40 %. Let Tank 1 settle. Apply a step on the slave SP (e.g., 4 in. → 5 in.) and record the Tank 1 response. Estimate the process gain Kp, dead time L, and time constant T from the open-loop step test. -
Tune the slave with Ziegler-Nichols or Lambda. For a first-order-plus-dead-time process use Lambda tuning:
Kc = T / (Kp × (L + λ));Ti = T;Td = 0. Set λ = T for a balanced response. - Verify the inner loop is faster than the outer loop. The closed-loop time constant of the slave should be at least three to five times smaller than the open-loop time constant of Tank 2.
-
Switch the master to auto. Step-test the outer loop by changing
SP_Tank2from 2 in. to 3 in. Observe the master output; it should be smoother than the slave's MV and never exceed 12 in. equivalent for Tank 1. - Tune the master. Lambda tuning again, but now the "plant" for the master is the closed-loop slave + Tank 2 combination. Reduce Kc by 30 % if oscillation appears between the two loops.
Commissioning and Verification
- Download the hardware configuration and program to the S7-300 CPU.
- Open an online watch table on "Tank_Data" and confirm that
PV_Tank1_REALandPV_Tank2_REALtrack the HMI faceplate values. - Place the master in manual, set
MV_Master = 50 %. Verify the slaveSP_EXTreads 6.0 in. (50 % × 12 in.). - Place the master in automatic, set
SP_Tank2 = 3.0 in.. Verify that Tank 2 rises to 3.0 in. within the expected time constant and settles with <5 % overshoot. - Introduce a disturbance: partially block the Tank 1 outflow and confirm that Tank 2 deviation recovers faster than a single-loop controller would allow.
- Force a slave saturation (
MV_Slave = 100 %). The master output should clamp to its configured limit and the loop should remain stable, never reaching integrator windup. EnableLMN_FAC/LMN_OFFon CONT_C for anti-windup if not already active.
Troubleshooting Matrix
| Symptom | Likely Cause | Fix |
|---|---|---|
| Slave ignores master setpoint | Slave is in internal-SP mode; SP_EXT not wired |
Set slave to external SP (cascade) mode and verify SP_EXT connection |
| Tank 1 saturates at 12 in. while master is at 50 % | Master output not scaled to Tank 1 range | Apply linear scaler SP_Tank1 = (LMN/100) × 12
|
| PV_PER shows 0 even though sensor is connected | Wrong channel address; AI module not configured for 4–20 mA | Check hardware config, set channel measurement type to "4WireCurrent" or "2WireCurrent" |
| PV_IN shows correct value but CONT_C reads garbage | REAL and WORD wired to the wrong input | Use PV_IN for REAL, PV_PER for the raw IW word |
Pump runs at full speed regardless of MV_Slave
|
Wiring the wrong DO; software PWM accumulator overflow | Verify Q address, add boundary clamp 0–1000 |
| Tank 2 oscillates and Tank 1 is stable | Inner loop too aggressive relative to outer | Reduce slave GAIN by 30 %, increase master TI
|
| Both loops oscillate at the same frequency | Loops coupled too tightly or the inner loop is slower than the outer | Re-test inner loop step response; add integrator anti-windup |
| Block not visible in TIA Portal palette | PID Professional add-on not installed | Install "PID Professional" option package or fall back to PID_Compact / CONT_C |
Migration Notes: STEP 7 V5.x to TIA Portal V13
The original "Configurating of Cascade Control" Siemens publication and the "Controlling with SIMATIC" handbook both target the SIMATIC Manager (STEP 7 V5.5) environment. To use these examples on a school computer that only has TIA Portal V13:
- Open the legacy .S7P project in STEP 7 (any lab machine), then File → Save as → TIA Portal project file, or use the TIA Portal "Migrate project" wizard.
- Confirm the FB41 instance DB names are preserved; TIA Portal will create a new instance DB for each CONT_C call.
- The wire
LMN_master → SP_EXT_slaveworks identically in TIA Portal; the connection is made in the FB body of the FBD network or in SCL. - If the migrated project fails to compile, the most common cause is a missing instance DB; regenerate it with Program blocks → FB41 → right-click → Generate instance DB.
For further Siemens TIA Portal reference on the speed-control cascade concept (general cascade structure for drives), see the Speed controller (cascade) mode in TIA Portal documentation.
Safety and Good Practice
- Always include a hardware ESTOP that cuts pump power regardless of software state.
- Clamp the master output to 0–100 % on both ends; never let it become a negative SP that would command reverse flow on a non-reversing pump.
- Enable anti-windup on both CONT_C blocks (
LMN_FAC = 1.0,LMN_OFF = 0.0,I_ITVAL = TRUE). - Use the
PV_FAC/PV_OFFparameters or a SCALE block to convert 4–20 mA to inches; never send raw counts to the HMI. - Log
SP_Tank2,PV_Tank1,PV_Tank2,LMN_Master, andLMN_Slaveat 100 ms for one hour after every tuning change.
FAQ
Can I implement cascade control on a Siemens S7-300 with TIA Portal V13 using only two CONT_C blocks?
Yes. Connect the master LMN output to the slave SP_EXT input, set the slave to external-setpoint (cascade) mode, and apply a linear scaler between the master percentage and the slave's engineering-unit range. No PID Professional add-on is required.
What is the difference between PV_PER and PV_IN on a Siemens CONT_C block?
PV_PER is a 16-bit WORD (0–27648) that takes the raw analog input and is scaled internally using PV_FAC/PV_OFF. PV_IN is a 32-bit REAL already in engineering units (e.g., inches) and lets you apply SCALE / NORM_X outside the PID block for diagnostics, alarms, and HMI sharing.
Which loop is tuned first in a cascade controller?
The inner (slave) loop is always tuned first while the master is in manual mode. The inner loop's closed-loop time constant should be three to five times faster than the outer loop's open-loop time constant. The master is then tuned against the closed-loop inner loop as its "plant".
Do I need PID_CP and PID_ES for cascade control on an S7-300?
No. PID_CP and PID_ES belong to the optional PID Professional add-on and are useful for split-range or pulse outputs, but a simple continuous cascade can be built with two CONT_C (FB41) blocks or two PID_Compact blocks. Choose CONT_C for migrated STEP 7 V5.x projects and PID_Compact for new TIA Portal V13 projects.
How do I generate a PWM output from a CONT_C controller for a DC pump?
CONT_C outputs a 0–100 % REAL on LMN. Convert it to a duty count (e.g., 0–1000) and drive a digital output from OB35 with a software accumulator, or use a hardware PWM module such as the FM350-1 for jitter-free switching at 1–100 Hz.
How do I migrate a STEP 7 V5.x cascade example to TIA Portal V13?
Open the legacy project in STEP 7 and use "File → Save as TIA Portal project" or the TIA Portal "Migrate project" wizard. FB41 (CONT_C) instances and their wiring carry over, but instance DBs must be regenerated in TIA Portal if they were lost during migration.