Configuring FB41 CONT_C PID Controller in S7-300: Setup Guide

David Krause15 min read
S7-300SiemensTutorial / 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

1. Overview of PID Control on S7-300 / S7-400

The SIMATIC S7-300 and S7-400 CPUs ship with a Standard PID Control library that contains the FB41 "CONT_C" continuous-action PID block used in countless closed-loop applications (pressure, flow, temperature, level, position, gas concentration). FB41 is a software PID function block — not a hardware controller — that runs in OB35 (or any cyclic interrupt OB) and is fully integrated in STEP 7 V5.3 and later. The block is located in the Standard Library → "PID Control Blocks" program folder and can be copied into any S7-300 / S7-400 user program without licensing.

FB41 implements a parallel (non-interacting) PID structure with anti-windup, derivative filtering, ramp-rate limited setpoint, manual-to-auto bumpless transfer, and dual output paths (analog LMN in 0.0–100.0 % and LMN_PER as a peripheral word 0–27648). When the task is a single continuous actuator (proportional valve, thyristor power controller, variable-speed drive in torque mode) FB41 is the default choice. For pulse-width modulated outputs use FB42 "CONT_S"; for step controllers with integral actuator (motorised valve) use FB43 "PULSEGEN" with FB41.

The reference for parameter behaviour is the Siemens Standard PID Control manual (entry ID 10859203) and the TIA Portal help page "Controller structures (S7-300, S7-400)" (see Controller structures (S7-300, S7-400)).

2. Prerequisites and Installation

Before instantiating FB41 confirm the engineering environment and hardware interface points meet the following requirements:

  • STEP 7 V5.3 or later (recommended V5.5 + SP4 / HF7 for Windows 10 compatibility). The PID Control library is installed with the default STEP 7 setup; if missing, run the SETUP.EXE from the Standard Library DVD.
  • SIMATIC S7-300 CPU 312C through 319F-3 PN/DP, or S7-400 CPU 412–417. FB41 occupies 590 bytes of instance-DB work memory and 1 FB slot.
  • One analog input channel (4–20 mA, 0–10 V, RTD, or TC) wired to the process variable (PV) sensor.
  • One analog output channel (4–20 mA or 0–10 V) for the actuator reference, or a PROFIBUS/PROFINET word to a drive.
  • Cyclic interrupt OB (OB35) configured for a 100 ms–1 s cycle. Standard loop time for thermal loops = 1 s; pressure/flow = 100–250 ms; fast position = 50–100 ms.
Note: FB41 is sample-time dependent. The block internally expects SAMPLE_T to match the OB35 cycle. If you change OB35 cycle, update SAMPLE_T on the block (input CYCLE in seconds) to keep the integral/derivative terms dimensionally correct.

3. FB41 CONT_C Block Architecture

The block diagram from the Siemens Standard PID Control manual is reproduced in the schematic below. The error signal ER = SP_INT − PV is fed into a parallel PID branch. The P, I, and D branches are summed, clipped to 0–100 %, and exported as LMN. A separate scaled path produces LMN_PER for direct output to a peripheral word (0–27648).

SP_INT (setpoint) PV_IN / PV_PER Σ ER = SP − PV P (GAIN) I (TI) D (TD) Anti-windup + Limiter LMN (0–100 %) LMN_PER (0–27648)

The derivative action is applied to the process variable (not the error) by default, eliminating derivative kicks on setpoint changes. A first-order low-pass filter TM_LAG smooths the derivative channel. Internal integrator clamping prevents wind-up when the actuator saturates (this is the "anti-windup" block in the diagram above).

4. I/O Pin Map of FB41

The complete input / output list from the Standard PID Control manual (Siemens entry 10859203) is shown below. The instance-DB (e.g. DB30) exposes all I/O as named tags; you read/write them with symbolic access (e.g. DB30.SP_INT) or with the LAD/FBD instance DB view.

Pin Direction Type Range / Units Function
SP_INT IN REAL -100.0 to 100.0 % Internal setpoint in engineering units (0–100 % normalised). Set via HMI / recipe.
PV_IN IN REAL -100.0 to 100.0 % Process value already scaled to 0–100 %.
PV_PER IN WORD 0–27648 Raw peripheral value (e.g. PIW 288). Use when PVPER_ON = TRUE.
PVPER_ON IN BOOL TRUE / FALSE TRUE = use PV_PER, FALSE = use PV_IN.
GAIN IN REAL ≥ 0 Proportional gain (dimensionless). Typical 0.5–5.0.
TI IN REAL ≥ 0.0 s Integral action time (reset time). Set to 0.0 to disable I.
TD IN REAL ≥ 0.0 s Derivative action time. Set to 0.0 to disable D.
TM_LAG IN REAL ≥ 0.0 s Time constant of derivative low-pass filter (typical = TD).
DEADB_W IN REAL ≥ 0.0 % Dead band width on error. 0 = off.
LMN_HLM IN REAL LMN_LLM–100.0 Manipulated-value high limit (e.g. 100.0).
LMN_LLM IN REAL 0.0–LMN_HLM Manipulated-value low limit (e.g. 0.0).
PV_FAC IN REAL — Multiplier applied to PV_PER before scaling to %.
PV_OFF IN REAL — Offset added to PV after multiplication.
LMN_FAC OUT REAL — Factor applied to LMN to produce LMN_PER.
LMN_OFF OUT REAL — Offset added to LMN to produce LMN_PER.
MAN IN REAL 0.0–100.0 % Manual manipulated value.
MAN_ON IN BOOL TRUE / FALSE TRUE = manual mode, FALSE = automatic.
CYCLE IN REAL ≥ 0.001 s Sample time of the block, must match OB35 period.
SP_INT_HLM / SP_INT_LLM IN REAL 0–100 Setpoint ramp high/low clamps.
LMN OUT REAL 0.0–100.0 % Effective manipulated value (scaled).
LMN_PER OUT WORD 0–27648 Manipulated value for direct output to PQW.
PV OUT REAL 0.0–100.0 % Scaled effective process value.
ER OUT REAL -100.0 to 100.0 % Effective error.

Internal status outputs LMN_P, LMN_I, LMN_D, I_ITVAL, and DISV are visible only in the instance DB and are useful for online tracing of each branch contribution during commissioning.

5. Step-by-Step Configuration

  1. Open STEP 7 and the project. In SIMATIC Manager, expand the S7-300 station and double-click the Blocks folder.
  2. Open the PID library. File → Open → Library → "Standard Library" → "PID Control Blocks". You will see FB41 through FB43, plus the UDTs (data type 1 for CONT_C).
  3. Copy FB41 into the project. Drag FB41 from the library into the project Blocks folder. Confirm the version (FB41 V5.0 ships with STEP 7 V5.3+; V5.1 in V5.4 SP1+).
  4. Create the instance DB. In the project Blocks folder, insert a new DB and assign "FB41" as the function block. Rename the DB to something meaningful, e.g. DB30 "PID_N2_PRESS". STEP 7 auto-generates the instance view with all I/O.
  5. Call FB41 from OB35. Open OB35 (Cyclic Interrupt). In the first network insert:
    CALL  "PID_N2_PRESS" , DB30
       SP_INT   := MD100       // setpoint %, 0.0–100.0
       PV_IN    := MD104       // process value already normalised to 0–100 %
       PV_PER   := MW106       // e.g. PIW288 (4–20 mA, 0–27648)
       PVPER_ON := M110.0      // TRUE = use PV_PER
       GAIN     := 1.2         // tuning parameter
       TI       := T#30s       // reset time
       TD       := T#0s        // derivative disabled
       MAN      := 0.0
       MAN_ON   := M110.1
       LMN_HLM  := 100.0
       LMN_LLM  := 0.0
       CYCLE    := 0.1         // 100 ms OB35
       LMN_PER  := PQW 290     // 4–20 mA to actuator
       LMN      := MD200
    
  6. Wire the peripheral I/O. In HW Config, ensure the AI module (e.g. SM331 6ES7331-1KF02-0AB0) is configured for 4-wire 4–20 mA and that the AO module (SM332 6ES7332-5HD01-0AB0) is 0–10 V or 4–20 mA. FB41's PV_PER input maps to the PIW, LMN_PER output to the PQW.
  7. Configure OB35 cycle. HW Config → CPU properties → Cyclic Interrupts → set OB35 to 100 ms. Alternatively, change CYCLE on FB41 to match any other OB35 period.
  8. Compile and download. Select the S7 program → PLC → Download. Open the instance DB online and verify the tags update each cycle.

6. Scaling the Process Variable

If PVPER_ON = TRUE the block performs scaling internally:

PV (in %) = ( PV_PER / 27648 ) * PV_FAC + PV_OFF

Use this when your sensor is already in the same engineering range (e.g. 4 mA = 0 %, 20 mA = 100 %). For a 0–10 bar pressure transmitter with 4–20 mA and 0 % = 0 bar, 100 % = 10 bar, set PV_FAC = 100.0, PV_OFF = 0.0. For a 4–20 mA transmitter that maps 4 mA to 0.5 bar and 20 mA to 8 bar use the FC105 SCALE block (Standard Library → TI-S7 Converting Blocks) upstream and pass the scaled REAL to PV_IN with PVPER_ON = FALSE. The FC105 formula is:

OUT = [ (FLOAT(IN) - K1) / (K2 - K1) ] * (HI_LIM - LO_LIM) + LO_LIM

For LMN_PER to drive a 4–20 mA output the block computes:

LMN_PER = ( LMN * LMN_FAC + LMN_OFF ) * 276.48

With default LMN_FAC = 1.0 and LMN_OFF = 0.0, LMN = 50.0 % produces LMN_PER = 13824 ≈ 12 mA on a 4–20 mA output.

7. Tuning Procedure

FB41 does not include an auto-tuner; tuning is performed with the closed-loop step-response method (Chien-Hrones-Reswick, Ziegler-Nichols) or with the open-loop "bump test" technique. The recommended field procedure for an S7-300 application is:

  1. Put the controller in manual (MAN_ON = TRUE) and drive the actuator to 30 %, 50 %, 70 % while logging PV from a WinCC trend or the STEP 7 variable table.
  2. Determine the plant gain Kp = ΔPV / ΔMV (in %/% in this normalised world) and the dominant time constant T1 (time to reach 63 % of the steady-state PV) plus the dead time Tt (time between MV step and the start of PV movement).
  3. Calculate tuning constants using the Chien-Hrones-Reswick (CHR) formulas for 0 % overshoot, setpoint regulation:
Mode GAIN (Kc) TI TD
PI (no overshoot, regulator) 0.3 * (Tt / Kp)⁻¹ = 0.3 / Kp * Tt⁻¹ 3.3 * Tt 0
PI (0 % overshoot, servo) 0.35 / Kp * Tt⁻¹ 1.2 * T1 0
PID (CH-R 0 % overshoot) 0.6 / Kp * Tt⁻¹ 1.0 * T1 0.5 * Tt
PID (CH-R 20 % overshoot) 0.95 / Kp * Tt⁻¹ 1.4 * T1 0.47 * Tt
  1. Write GAIN, TI (seconds), TD (seconds) into the instance DB. If TI = 0.0 the I branch is disabled, likewise TD = 0.0 disables D. Initialise TM_LAG = TD / 5 to prevent derivative noise amplification.
  2. Set MAN_ON = FALSE (auto). Drive a small setpoint step (5 % of span). Observe the trend; if the loop oscillates, halve GAIN; if sluggish, increase GAIN by 25 %.
  3. For pressure/level control with integrating behaviour, disable D and tune PI only; a too-aggressive D on a noisy PV creates jitter in the actuator.
Safety: Before bumping the actuator in manual, confirm the process safety system (burner management, over-pressure relief, soft-start VFD) is enabled. Hard-wire a watchdog that drives MAN_ON = TRUE with MAN = 0 % on CPU STOP, because FB41 freezes the last LMN on STOP and may leave the actuator in a dangerous position.

8. Commissioning and Verification

Follow this verification sequence after the initial download:

  1. Check the wiring. With PLC in STOP, measure the sensor mA at the AI terminals; verify 4 mA = 0 % and 20 mA = 100 % in the online instance DB. Reverse polarity or missing 24 V transducer supply is the most common first-day failure.
  2. Check the OB35 cycle. In OB1, add a 1 s timer and toggle a flag; compare to the OB35 instance DB field CYCLE. If they drift you have time-base corruption; re-verify with the diagnostic buffer (Diagnostic Event ID 0x2A09 "OB35 time error").
  3. Check the loop direction. Set MAN = 50 %, MAN_ON = TRUE. If PV moves opposite of expected, the actuator feedback is reversed. Either swap the PV_FAC sign, swap the analogue output wiring, or invert the error sign internally by feeding −PV_IN.
  4. Run the open-loop step test. Step MAN from 30 → 50 %, capture PV in the trend, derive Kp, T1, Tt, then enter the tuning values from §7.
  5. Run the closed-loop setpoint step. With MAN_ON = FALSE, change SP_INT by 10 %, capture the resulting PV, LMN, and ER trends. Compute rise time, overshoot, settling time, and IAE (Integral Absolute Error) as objective KPIs.
  6. Verify bumpless transfer. Toggle MAN_ON while in steady state. The LMN should not jump by more than 0.1 %; FB41 loads the internal integrator with the current LMN on every auto-to-manual transition.

9. Anti-Windup, Bumpless Transfer, and Setpoint Ramps

Anti-windup in FB41 is implemented by clamping the integrator to keep the sum of P + I + D within the configured LMN_HLM / LMN_LLM. If you wire PV_PER from a sensor that can fail to 0 mA (open wire) the controller will integrate the full error and saturate. To detect a wire-break, monitor PV_PER > 32511 (overrange) and force MAN_ON = TRUE with MAN = 0; this is the standard "sensor fail" handling pattern.

Setpoint ramps (useful in batch start-ups) are configured by setting SP_INT_HLM and SP_INT_LLM equal to the current SP_INT, then overwriting SP_INT at a controlled rate from OB35. FB41 itself does not provide an internal ramp generator; a small FB wrapper or a separate ramp block is the usual implementation. For batch thermal processes this is mandatory to avoid overshoot on start-up.

10. Common Errors and Troubleshooting Matrix

Symptom Likely Root Cause Diagnostic / Fix
LMN_PER stuck at 0 or 27648 AI wire break (0 mA) or short (≥22 mA). PV_PER overrange / underrange flag set. Check PV_PER > 32511 (overrange) or PV_PER < 0 (underrange). Verify sensor supply. Force MAN_ON = TRUE on fault.
Output cycles between 0 and 100 % at full speed Loop sign reversed (direct vs reverse acting) or GAIN negative. Verify ER = SP − PV; for heating/cooling pick the correct action and confirm wiring.
Process never reaches setpoint Anti-windup not released (LMN saturating). TI too long or P-only mode. Reduce GAIN, shorten TI, enable I. Check LMN_HLM/LMN_LLM are not artificially narrow.
High-frequency jitter on LMN Derivative noise on PV (no TM_LAG or too small). Cycle time too fast. Increase TM_LAG to TD; increase OB35 cycle to 250–500 ms; add analog input filter in HW Config.
Large bump on AUTO→MANUAL Forgotten bumpless-transfer logic; integrator initialised to 0. FB41 handles this automatically only if MAN_ON is toggled without changing MAN. Use a HMI that exposes only the AUTO/MAN button, not the MAN value field.
SF LED on CPU, OB35 startup event missing OB35 cycle below minimum, or OB35 not loaded. Diagnostic buffer ID 0x2370 "Time error". Increase cycle to ≥1 ms (CPU-dependent) or accept watchdog alarm.
FB41 input DB initial values all zero, integrator never moves Instance DB is uninitialised and CPU started in cold-restart with process data = 0. Initialise GAIN = 0.0 before first call; or feed the call from OB100 (warm restart) to preset integrator.
Loop works in simulation, oscillates on real plant Actuator dead-band (e.g. control valve with stem packing) and on-the-fly load changes not modelled. Add DEADB_W = 0.5–2.0 %; pre-load from a feedforward signal.

11. HMI / WinCC Integration

Expose the instance DB tags as WinCC variables to provide operator control of mode, setpoint, and tuning. Recommended faceplate items:

  • SP_INT — numeric I/O field, 0.0 to 100.0 %.
  • PV — output field only, 0.0 to 100.0 %.
  • LMN — output field only, 0.0 to 100.0 %.
  • MAN_ON — binary tag, "Auto / Manual".
  • MAN — numeric I/O field, visible only in manual mode.
  • GAIN, TI, TD, TM_LAG — read-only tags, password-protected write access (level "Tuning").
  • ER, LMN_P, LMN_I, LMN_D — internal branch contributions, useful for trend views during commissioning.

Group the Auto/Manual button and the MAN value with visibility animation in WinCC to enforce the rule that operators must not change MAN while AUTO is active. Place PV and SP_INT on a bar-graph display alongside LMN for a single-glance view of regulation health.

12. Migration Notes: STEP 7 V5.5 to TIA Portal

FB41 is binary-compatible. When migrating an S7-300 program to TIA Portal V16+, the block and its instance DB are ported as-is via "Migrate project". Re-instantiate the block from the "PID_Compact" library if the application is new to TIA Portal — PID_Compact (S7-1500) or PID_Basic (S7-1200) integrate auto-tuning, but the FB41 V5.x structure is still supported on S7-300 / S7-400 in TIA Portal V19 for legacy migration. If the S7-300 CPU is replaced by an ET 200SP CPU 1510SP-1 PN or S7-1500, plan a re-tuning campaign because the loop time granularity and floating-point behaviour differ.

On the S7-1500 side, PID_Compact (FB 1139) replaces FB41 with similar inputs and built-in pretuning / fine-tuning; documentation is at Controller structures (S7-300, S7-400).

Where is FB41 located in STEP 7 and which versions ship with it?

FB41 is in the Standard Library → "PID Control Blocks" folder. It is included with every STEP 7 V5.3 and later installation. Open the library from the File menu in SIMATIC Manager, drag the block into your project Blocks folder, and create an instance DB (e.g. DB30). FB41 V5.0 ships with STEP 7 V5.3+; FB41 V5.1 ships with V5.4 SP1 and later.

Which OB should call FB41, and what cycle time should I use?

Call FB41 from a cyclic interrupt OB (typically OB35) so the loop runs at a deterministic rate, not from OB1. Configure the OB35 cycle to 100 ms for pressure / flow, 250–500 ms for level, and 1 s for thermal loops. Set FB41's CYCLE input to the same value in seconds (0.1, 0.25, 0.5, 1.0) so the integral and derivative terms are dimensionally correct.

Why does LMN_PER stay at 0 or 27648 when the controller is running?

The most common cause is a sensor wire break: 0 mA or >22 mA drives PV_PER to the underrange / overrange limit and FB41 saturates. Monitor the wire-break flag (PIW > 32511 or < 0) and force MAN_ON = TRUE with MAN = 0 on fault. The second-most common cause is forgetting to wire PVPER_ON = TRUE when using PV_PER.

How do I tune FB41 without an auto-tuner?

Run a manual bump test: put the loop in manual (MAN_ON = TRUE), step MAN by 20 % of span, record PV in a trend, and read the plant gain Kp, dominant time constant T1, and dead time Tt. Apply the Chien-Hrones-Reswick formulas (0 % overshoot, regulator mode: GAIN = 0.3 / (Kp · Tt), TI = 3.3 · Tt, TD = 0). Then fine-tune in auto using small setpoint steps.

What is the difference between FB41, FB42, and FB43?

FB41 (CONT_C) is a continuous controller that outputs a 0–100 % analog signal. FB42 (CONT_S) is a step controller with binary output for integrating actuators. FB43 (PULSEGEN) is a pulse-width modulator used with FB41 to drive heating/cooling contactors from the continuous LMN signal. Use FB41 for proportional valves, drives in torque mode, and thyristor power controllers; use FB41 + FB43 for solid-state relay pulsed heating.

Why does the loop oscillate after I switch from manual to automatic?

If you change the MAN value manually while MAN_ON = TRUE and then flip to auto, FB41 keeps the internal integrator aligned with the last LMN, so the transition is bumpless only if you toggle MAN_ON without touching MAN. If oscillation persists after the transition, the sign of the loop is reversed, the derivative time constant is too short, or the dead time is larger than the integrator can compensate. Verify the process reaction direction, increase TM_LAG, and re-derive tuning constants.

Back to blog