Overview: Pressure Profile Control on S7-1200
Air-operated high-pressure pumps require a controlled ramp up to a target pressure, a dwell period at that pressure, a transition to the next pressure level, and a controlled bleed-down to zero. A 4–20 mA proportional valve handles pressurization while a second 4–20 mA proportional valve handles discharge. The S7-1200 CPU family (firmware V4.x and later, fully supported through TIA Portal V20) does not ship with the legacy S7-300/400 RMP_SOAK block documented for the older Ramp/soak (RMP_SOAK) S7-300/400 instruction. Instead, the equivalent functionality is built from two cooperating blocks:
-
PID_Compact (or
PID_3Stepfor valve actuators) for closed-loop control. - RampFunction, the slew-rate limiter described in the TIA Portal V20 PID auxiliary-functions manual, which converts a step change at its input into a controlled ramp at its output.
This article shows how to chain these blocks with a profile-generator data block that holds the pressure steps and dwell times, and how to expose the system to a WinCC runtime for operator entry of new profiles.
Prerequisites and System Architecture
| Item | Specification |
|---|---|
| CPU | S7-1200, firmware V4.2 or higher (V4.5+ recommended for full TIA Portal V20 support) |
| Engineering software | TIA Portal V20 with STEP 7 Basic/Professional and WinCC Basic/Comfort |
| PID instruction | PID_Compact (V2.3 or higher) for continuous control; PID_3Step for integral actuators |
| Auxiliary instruction | RampFunction (technology object "PID Auxiliary Functions") |
| Analog outputs | 2 × SM 1232 AQ 4×14 bit or signal board SB 1232 AQ 1×12 bit (one per proportional valve) |
| Analog input | SM 1231 AI 4×13 bit (pressure transducer 4–20 mA, e.g. 0–10 000 psi) |
| HMI | Comfort Panel, Unified Comfort Panel, or WinCC Runtime Advanced |
| Cycle OB | OB30 (cyclic interrupt, 100 ms typical) for deterministic profile execution |
Signal Topology
The pressure transducer delivers 4 mA at 0 psi and 20 mA at the transducer full scale (FS). With FS = 10 000 psi, the engineering conversion in PID_Compact is:
PV_Real = (Raw_AI / 27648.0) × 10000.0
The two proportional valves receive 4 mA at fully closed and 20 mA at fully open; the analog output scaling mirrors the input scaling so that 100 % controller output corresponds to 20 mA.
PID_Compact Configuration in TIA Portal V20
- Open the project and add the S7-1200 device.
- In the project tree, expand Technology objects > Add new object > PID > PID_Compact. Name the instance
PID_PumpPress. - Configure Basic settings:
- Setpoint input type:
Input / Setpointfrom a tag namedSP_Ramped(REAL, in psi). - Process value:
%IW64(or the configured AI channel), with scalingPV_Factor = 10000.0 / 27648.0. - Output: analog output
%QW80for the pressure-control valve; analog output%QW82for the bleed-down valve is wired to a separatePID_CompactinstancePID_Bleedthat is active only during the ramp-down phase. - Limit output to 0.0 %–100.0 %.
- Setpoint input type:
- Configure Controller structure > Controller type = PID and disable the derivative component if the process is dominated by first-order lag (typical for a pneumatic pump). Start with
Kp = 1.2,Tn = 8.0 s,Tv = 0.0 s. - In Process value limits set
PV_Upper_Warning = 9500 psi,PV_Upper_Error = 9800 psi, andPV_Lower_Warning = 50 psi. These limits clamp the input that is fed to PID_Compact. - Open Controller tuning, select "Pretuning" and start a tuning run on the actual pump; otherwise enter the manual values above.
RampFunction Block: Theory of Operation
The RampFunction instruction documented in the TIA Portal V20 PID auxiliary-functions manual limits the slew rate of a signal. A step jump at the input is converted to a ramp at the output whose slope is defined by RampUpTime and RampDownTime. Internally, the block maintains an internal value Output that is advanced by
Δ = (Setpoint − Output) × (CycleTime / RampUpTime)
each cycle while rising, or by an equivalent formula using RampDownTime while falling. The output therefore catches the setpoint asymptotically without overshoot, regardless of the size of the setpoint step. This makes it the ideal feed for the PID setpoint input whenever the controller itself should never see a step.
Block Interface (S7-1200 / S7-1500)
| Port | Direction | Type | Meaning |
|---|---|---|---|
| Input | IN | REAL | Target value from profile generator |
| RampUpTime | IN | REAL | Seconds to ramp from 0 to 100 % engineering units |
| RampDownTime | IN | REAL | Seconds to ramp from 100 % engineering units to 0 |
| Output | OUT | REAL | Ramped value to feed PID_Compact Setpoint |
| Busy | OUT | BOOL | TRUE while the ramp is in progress |
| Error | OUT | BOOL | TRUE on parameter error (e.g., negative ramp time) |
| Status | OUT | WORD | Error code (16#0000 = OK) |
Profile Generator: Data Block Layout
A multi-step profile needs storage for step pressure, dwell time, and a step pointer. Create a global DB named DB_Profile with the following structure:
TYPE "UDT_Step"
STRUCT
Pressure : REAL; // psi, target for this step
DwellSec : REAL; // seconds to hold before next step
RampUpSec : REAL; // local ramp-up time for this transition
RampDownSec : REAL; // local ramp-down time for next transition
END_STRUCT;
END_TYPE
DATA_BLOCK "DB_Profile"
STRUCT
Step : ARRAY[1..10] OF "UDT_Step";
StepCount : INT; // number of valid entries (operator-defined)
Index : INT; // current step (1..StepCount)
State : INT; // 0=Idle,1=RampUp,2=Hold,3=RampDown,4=Done
TimerSec : REAL; // dwell countdown
END_STRUCT;
BEGIN
// Default 2-step profile: 0 → 1000 psi @ 30 s, hold 120 s → 5000 psi @ 120 s, hold 300 s
"Step[1]".Pressure := 1000.0; "Step[1]".DwellSec := 120.0;
"Step[1]".RampUpSec := 30.0; "Step[1]".RampDownSec := 60.0;
"Step[2]".Pressure := 5000.0; "Step[2]".DwellSec := 300.0;
"Step[2]".RampUpSec := 120.0; "Step[2]".RampDownSec := 90.0;
"StepCount" := 2;
"Index" := 1;
"State" := 0;
"TimerSec" := 0.0;
END_DATA_BLOCK
Step-by-Step Implementation
1. Insert RampFunction in the Project
- Project tree > Technology objects > Add new object > PID > Auxiliary functions > RampFunction.
- Name the instance
RF_PumpSetpoint. - Set the default
RampUpTime = 30.0 sandRampDownTime = 60.0 s. These will be overwritten each cycle by the profile generator.
2. Generate the Profile in OB30 (Cyclic Interrupt)
OB30 runs every 100 ms. It (a) advances the state machine, (b) writes the current target to RampFunction, and (c) feeds the ramped output into PID_Compact.
// OB30 - 100 ms cyclic interrupt
"iCyclicTime" := 0.1; // seconds
CASE "DB_Profile".State OF
0: // IDLE - wait for operator start
IF "DB_Profile".bStart THEN
"DB_Profile".Index := 1;
"DB_Profile".State := 1;
"DB_Profile".bStart := FALSE;
END_IF;
1: // RAMP UP to Step[Index].Pressure
"iTarget" := "DB_Profile".Step["DB_Profile".Index].Pressure;
"rRampUp" := "DB_Profile".Step["DB_Profile".Index].RampUpSec;
"rRampDown" := "DB_Profile".Step["DB_Profile".Index].RampDownSec;
IF NOT "DB_Profile".RF_Busy THEN
"DB_Profile".State := 2;
"DB_Profile".TimerSec := "DB_Profile".Step["DB_Profile".Index].DwellSec;
END_IF;
2: // HOLD (dwell)
"DB_Profile".TimerSec := "DB_Profile".TimerSec - "iCyclicTime";
IF "DB_Profile".TimerSec <= 0.0 THEN
IF "DB_Profile".Index < "DB_Profile".StepCount THEN
"DB_Profile".Index := "DB_Profile".Index + 1;
"DB_Profile".State := 1; // next step ramp
ELSE
"DB_Profile".State := 3; // ramp down to zero
END_IF;
END_IF;
3: // RAMP DOWN to 0 psi via bleed valve
"iTarget" := 0.0;
"rRampUp" := "DB_Profile".Step["DB_Profile".Index].RampDownSec;
"rRampDown" := "DB_Profile".Step["DB_Profile".Index].RampDownSec;
IF "DB_PV".PV_Real < 5.0 THEN
"DB_Profile".State := 4;
END_IF;
4: // DONE
;
END_CASE;
// Drive RampFunction
"DB_Profile".RF_PumpSetpoint(Input := "iTarget",
RampUpTime := "rRampUp",
RampDownTime := "rRampDown");
"SP_Ramped" := "DB_Profile".RF_PumpSetpoint.Output;
"DB_Profile".RF_Busy := "DB_Profile".RF_PumpSetpoint.Busy;
// Feed PID_Compact
"PID_PumpPress".Setpoint := "SP_Ramped";
3. Switch Between Pressurize and Bleed During Ramp-Down
The pressurize PID (PID_PumpPress) stays in "Inactive" mode while the bleed valve takes over. In OB1:
IF "DB_Profile".State = 3 THEN
"PID_PumpPress".Mode := 1; // 1 = Inactive
"PID_Bleed".Mode := 3; // 3 = Automatic
"PID_Bleed".Setpoint := "SP_Ramped";
ELSE
"PID_PumpPress".Mode := 3; // 3 = Automatic
"PID_Bleed".Mode := 1; // 1 = Inactive
END_IF;
LAD Implementation Alternative (No SCL)
If the CPU firmware is too old to support SCL or if the engineer prefers LADDER, the slew-rate limit can be implemented with three standard math blocks driven by OB30. The minimum logic per cycle:
- Compute
Delta = Setpoint − LastOutput. - Compute
MaxStep = (CycleTime / RampUpTime) × Span(Span = engineering full scale, e.g. 10 000 psi). - If
ABS(Delta) <= MaxStepthenLastOutput = SetpointelseLastOutput = LastOutput + SIGN(Delta) × MaxStep.
| LAD Block | Computation |
|---|---|
| SUB_REAL | Delta = SP − LastOut |
| DIV_REAL then MUL_REAL | MaxStep = (0.1 / RampUp) × 10000.0 |
| ABS, GT, CMP | If ABS(Delta) > MaxStep then clamp with SIGN |
| MOVE / ADD | LastOut = LastOut + SIGN × MaxStep |
This ladder replica of the RampFunction delivers the same behavior as the technology-object version but uses about 14 network rows and a static tag LastOut in a global DB.
HMI Integration with WinCC (TIA Portal V20)
For an operator-facing profile editor, expose the following tags on the HMI:
-
DB_Profile.Step[1..10].Pressure— REAL array, writable, 0–10 000 psi -
DB_Profile.Step[1..10].DwellSec— REAL array, writable, 0–3 600 s -
DB_Profile.Step[1..10].RampUpSec/RampDownSec— REAL arrays -
DB_Profile.StepCount— INT, writable, 1–10 -
DB_Profile.bStart— BOOL, momentary pushbutton
Recommended screen layout:
-
Profile Table: a WinCC table view bound to the
Steparray, with columns Step#, Pressure, Dwell, RampUp, RampDown. -
Live Trend: trend view with three pens —
SP_Ramped,PV_Real, andPID_PumpPress".Output— to confirm that PV tracks SP without overshoot. -
State Banner: text field showing
DB_Profile.Statedecoded as IDLE / RAMPING / HOLD / BLEED / DONE.
Commissioning and Tuning Procedure
-
Static check (PLC in STOP): verify wiring polarity on both valves and the transducer. Force
PID_PumpPress".Output= 0 % and 100 % with the HMI and confirm 4 mA / 20 mA at the valve terminals. -
RampFunction-only test: disable PID_Compact and run a manual ramp 0 → 5 000 psi with
RampUpTime = 60. WatchRF_PumpSetpoint.Outputrise linearly. If the line is non-linear,RampUpTimeis being overwritten by OB30 each cycle — make sure the assignment in OB30 is correct. -
Open-loop step test: with PID_Compact in Manual, force 25 % output and observe the PV. The first-order time constant τ and steady-state gain K can be read directly from the response and entered as
Pretuningstart values. -
Pretuning: select "Pretuning" in PID_Compact with the operator setpoint at 60 % of FS. Watch for Status = 3 (Pretuning finished); record the auto-computed
Kp,Tn. -
Fine-tuning: run the full 2-step profile. If PV overshoots SP by > 5 %, reduce
Kpby 20 % and increaseTnby 30 %. If PV lags SP by > 30 s during the ramp, increaseKpby 20 %. -
Bleed test: set
DB_Profile.State = 3with PV at 5 000 psi. Confirm that the bleed valve opens proportionally and PV falls on the configuredRampDownTimecurve.
Verification Tests
| Test | Expected result | Pass criterion |
|---|---|---|
| RampFunction linearity | Output vs. time plot is a straight line | R² > 0.99 |
| Setpoint step (1 000 → 5 000 psi) | PID_Compact Setpoint rises linearly over RampUpSec | Slope within ±2 % of configured value |
| Hold accuracy | PV within ±1 % of SP during dwell | 5-minute window, |PV−SP|/FS ≤ 0.01 |
| Ramp-down to 0 | PV decays to < 5 psi in ≤ RampDownSec + 10 % | Pass/fail by timer |
| Profile advance | Index increments exactly when TimerSec ≤ 0 | Visual on HMI state banner |
| Error path | RampFunction.Status = 16#0000 | No error word flagged during full profile |
Troubleshooting Matrix
| Symptom | Likely root cause | Remedy |
|---|---|---|
| SP jumps instantly to operator value | Operator tag wired directly to PID_Compact.Setpoint instead of SP_Ramped | Re-wire SP input to RF_PumpSetpoint.Output
|
| PV overshoots each step | Kp too high or ramp too slow for the loop bandwidth | Reduce Kp by 20 %, shorten RampUpTime so PID has authority earlier |
| Ramp appears to "freeze" mid-step | RampUpTime written as 0 in OB30 (divide-by-zero inside RampFunction) | Clamp RampUpTime/RampDownTime to ≥ 0.1 s before the call |
| Bleed valve opens during pressurize | State 3 logic runs while Index < StepCount | Verify Index increments before State transition to 3 |
| RampFunction.Error = TRUE after start | Invalid Input (NaN) or RampUpTime < 0 | Validate inputs in OB30; reset Error by toggling Mode to Inactive then Automatic |
| Profile advances one step but stalls | Dwell timer never decrements | Ensure OB30 is configured and running; verify cyclic interrupt OB with TIA Portal online > Diagnostics |
| PID_Compact in "Inactive" when Automatic expected | Mode reset by HMI tag or by ModeRetain rungs | Disable any Mode := 1 writes outside the State=3 branch |
Differences from Legacy S7-300/400 RMP_SOAK
Engineers familiar with the older Ramp/soak (RMP_SOAK) block should note the following:
- RMP_SOAK stores up to 16 steps in a dedicated DB (
DB_RMPSK). On S7-1200 the profile lives in any user DB. - RMP_SOAK generates its own ramp slope; on S7-1200 the ramp slope is delegated to RampFunction, and the profile generator only orchestrates the steps.
- RMP_SOAK integrates with PID_CP / PID_ES; on S7-1200 the orchestration is done in a cyclic OB that feeds PID_Compact directly.
- RMP_SOAK supports absolute and relative setpoints; the user-DB approach above supports both, but the engineer must select a UDT field to flag the mode.
Frequently Asked Questions
Can I run the profile generator in OB1 (main cyclic) instead of OB30?
Yes, but OB30 at 100 ms gives deterministic step transitions. If OB1 cycle time drifts above 200 ms the dwell timer becomes inaccurate and the Setpoint slope varies cycle-to-cycle. Use OB30 for any profile where ramp time accuracy matters.
What happens if the operator changes a step value while the profile is running?
The change is committed to DB_Profile.Step[n] but the active step is held until the current dwell completes. To apply mid-run, write the change to iTarget directly and trigger a one-shot ramp; the cleaner approach is to interrupt the profile with bStart := FALSE and restart from Step 1.
Why does the Setpoint reach the target before PV during a fast ramp?
This is the desired behavior: RampFunction outputs the linear setpoint, PID_Compact then drives PV toward it. If PV lags too much, increase Kp or shorten RampUpTime so the controller has time to close the gap.
How do I add more than 10 steps?
Resize the Step ARRAY in DB_Profile, update the HMI table view column count, and ensure the Index range check uses the new upper bound. No PID_Compact change is required.
Is the RampFunction technology object required or can I roll my own in SCL?
It is not required. The ladder/SCL recipe shown above is functionally identical and avoids the technology-object overhead. Use the technology object when you want a pre-validated block with diagnostics and uniform error codes.