How to Tune a PID Loop: A Field Guide

PID tuning — hands-on field guide

Hands-on · Process & motion control · ~12 min read

Every working controller you've ever liked — the oven that holds ±2°C, the axis that settles without a wiggle — is a PID loop somebody tuned well. This is the procedure we actually use in the field: how to prepare the loop, three tuning methods that work, the implementation details that silently decide whether your gains mean anything, and a symptom table for when it misbehaves.

PID tuning has a strange reputation: everyone learns the theory, yet most loops in industry run on defaults, folklore, or gains copied from the last machine. The result is everywhere — ovens that overshoot for ten minutes, axes that buzz, flows that cycle forever. None of that is the algorithm's fault. A PID has three knobs; tuning is the discipline of setting them deliberately instead of hopefully.

0 · The thirty-second refresher

The controller computes an actuation u from the error e = setpoint − measurement:

u(t)=Kpe(t)+Ki ⁣0te(τ)dτ+Kdde(t)dtu(t) = K_p\,e(t) + K_i\!\int_0^{t} e(\tau)\,d\tau + K_d\,\frac{de(t)}{dt}
Equation 1 — PID in parallel form

Each term has a personality, and you can diagnose most loops just by knowing them:

TermWhat it doesToo much of it
P — proportionalReacts to the error you have right nowOscillation; never quite reaches the target alone
I — integralAccumulates leftover error until it's gone; kills steady-state offsetSlow cycling, overshoot, windup after saturation
D — derivativeReacts to the rate of change; brakes before the targetAmplifies noise into actuator buzz and heat

Vendors write the same controller in different parameterizations — parallel (K_p, K_i, K_d), standard/ISA (K_p, T_i, T_d), sometimes "gain + reset rate". Before you type any number into a drive or PLC, check which form it expects:

u(t)=Kp(e(t)+1Ti ⁣0te(τ)dτ+Tdde(t)dt),Ki=KpTi,Kd=KpTdu(t) = K_p\left(e(t) + \frac{1}{T_i}\!\int_0^{t} e(\tau)\,d\tau + T_d\,\frac{de(t)}{dt}\right), \qquad K_i = \frac{K_p}{T_i},\quad K_d = K_p\,T_d
Equation 2 — standard (ISA) form, and the conversion to parallel gains

Mixing up the two forms is the single most common reason "textbook gains" fail in a real device.

Figure 1. The three personalities on one step. P alone responds fast but parks below the setpoint (permanent offset). PI closes the offset but pays in speed and a touch of overshoot. PID adds the brake — fast rise, minimal overshoot, quick settle.
Figure 1. The three personalities on one step. P alone responds fast but parks below the setpoint (permanent offset). PI closes the offset but pays in speed and a touch of overshoot. PID adds the brake — fast rise, minimal overshoot, quick settle.

1 · Before you touch a gain

Twenty minutes of preparation saves a day of frustration. In order:

  1. Fix the sample time. The loop must run at a fixed, known interval — jitter in Δt is noise injected straight into the I and D terms. Rule of thumb: sample at least 10× faster than the closed-loop response you want; for motor current loops that means tens of microseconds, for a thermal process one second is often plenty.
  2. Check the actuator and the sensor first. A sticky valve, an undersized heater, a 14-bit ADC measuring a 0.01% effect — no gain set fixes hardware that can't do the job. Step the output manually (open loop) and watch: does the process respond monotonically? How much delay before anything happens? How noisy is the measurement?
  3. Know your process type. Self-regulating processes (flow, temperature, current) settle at a new value after an open-loop step. Integrating processes (position from a velocity command, tank level) ramp until you stop them. The methods below assume self-regulating; integrating processes use different rules — and most motion loops are exactly that, which is why drive vendors ship their own tuning tools.
  4. Decide what "good" means. Disturbance rejection (hold temperature against door openings) and setpoint tracking (follow a profile) pull the tuning in different directions. Fast-with-overshoot or slow-and-certain is a requirement, not an afterthought.

2 · Method A — the manual recipe (works on almost anything)

No model, no math, safe if you go gently. This is the field workhorse:

  1. Set K_i = 0, K_d = 0. Start K_p low.
  2. Apply small setpoint steps (5–10% of range). Double K_p until the response overshoots slightly and rings for two or three cycles, then back off ~50%. You now have a P-only loop that responds briskly but won't quite reach the setpoint — the leftover gap is what the integral is for.
  3. Add integral: start T_i around the process's apparent time constant (the time the open-loop step needed to cover ~63% of its change). Halve T_i until the offset disappears at a pace you like; if slow oscillation appears, you've gone too far — back off.
  4. Add derivative only if you need it — to brake overshoot on a sluggish thermal mass, or to stiffen a motion axis. Start T_d ≈ T_i/4 and increase carefully. The moment the actuator starts buzzing, you've found your noise limit; back off and add measurement filtering (§4).
  5. Re-test with the real disturbances — door openings, load changes, direction reversals — not just pretty setpoint steps.

Tune for the disturbance you fear, not for the demo you'll show.

Figure 2. The vocabulary of a step response: rise time, overshoot, and settling time (when the output enters and stays inside the ±2% band). Every tuning decision in this guide trades these three against each other.
Figure 2. The vocabulary of a step response: rise time, overshoot, and settling time (when the output enters and stays inside the ±2% band). Every tuning decision in this guide trades these three against each other.

3 · Method B — Ziegler–Nichols, used honestly

The classic from 1942: it gives you a starting point in two measurements, and it's worth knowing both for its usefulness and its limits. Procedure (closed-loop version): with I and D off, raise K_p until the loop oscillates with constant amplitude. That gain is the ultimate gain K_u; the oscillation period is T_u. Then:

ControllerKpTiTd
P only0.50 · Ku
PI0.45 · KuTu / 1.2
PID0.60 · KuTu / 2Tu / 8

Two honest caveats. First, you must be allowed to oscillate the process — fine on a test rig, unacceptable on a live reactor or a loaded crane. Second, Z–N deliberately targets quarter-amplitude damping: each overshoot is a quarter of the previous one. That's aggressive — fast disturbance rejection, but oscillatory and not robust if the process drifts. Treat the table as a starting point and expect to cut K_p by 30–50% for production. For lifting heavy scenery over an audience, we never leave gains at Z–N values.

4 · Method C — lambda / IMC, when you can model the process

For process loops (temperature, flow, pressure), one open-loop step test gives you a first-order-plus-dead-time model — and with it, tuning where you choose the closed-loop speed instead of inheriting whatever the rules produce:

G(s)=gpetdsTs+1G(s) = \frac{g_p\,e^{-t_d s}}{T s + 1}
Equation 3 — FOPDT model: gain g_p, time constant T, dead time t_d, all read off one step response
Figure 3. Reading the FOPDT model off a single open-loop step test: the delay before anything happens is t_d, the time to reach 63% of the final change is T, and the final change divided by the step size is g_p. Three numbers — that's the whole identification.
Figure 3. Reading the FOPDT model off a single open-loop step test: the delay before anything happens is t_d, the time to reach 63% of the final change is T, and the final change divided by the step size is g_p. Three numbers — that's the whole identification.

Pick a desired closed-loop time constant λ — slower λ buys robustness, faster λ buys speed. A common conservative choice is λ = 3T; never choose λ smaller than the dead time. Then for a PI controller:

Kp=Tgp(λ+td),Ti=TK_p = \frac{T}{g_p\,(\lambda + t_d)}, \qquad T_i = T
Equation 4 — lambda (IMC) tuning for a self-regulating process, PI form

This is the method behind calm, non-oscillatory process control — and because λ is explicit, "make this loop twice as gentle" becomes a one-line change instead of a re-tuning session. It's the family of rules we used to hold a 12-blower industrial oven at ±2°C — four coupled loops, where Ziegler–Nichols-style aggression would have had them fighting each other.

5 · The implementation details that make or break it

Here is the uncomfortable truth: most "tuning problems" are implementation problems. The four that matter, in one annotated loop:

// dt fixed, called at a constant rate
float pid_step(float setpoint, float y) {
    float e = setpoint - y;

    // (1) Integrate with clamping anti-windup:
    //     stop integrating in the direction that's already saturated
    integ += Ki * e * dt;
    integ = clamp(integ, u_min, u_max);

    // (2) Derivative on MEASUREMENT, not on error:
    //     a setpoint step then causes no output spike ("derivative kick")
    // (3) ...and low-pass filter it: raw derivative amplifies ADC noise
    float dy   = (y - y_prev) / dt;
    d_filt    += (dy - d_filt) * (dt / (dt + Tf));   // Tf ≈ Td/8 … Td/10
    y_prev     = y;

    float u = Kp * e + integ - Kd * d_filt;

    // (4) Respect the actuator's limits explicitly
    return clamp(u, u_min, u_max);
}
  • Anti-windup (1). When the actuator saturates — heater at 100%, drive at current limit — a naive integral keeps accumulating, and you pay for it later as a huge overshoot. Clamp the integrator (or use back-calculation). This is the #1 real-world PID bug.
  • Derivative kick (2). Differentiating the error turns every setpoint change into an output spike. Differentiate the measurement instead — same damping, no kick.
  • Derivative filtering (3). An unfiltered D-term is a noise amplifier. Filter it; an unfiltered derivative is the buzzing sound your servo makes.
  • Saturation honesty (4). The controller should always know what the actuator actually did. If you ever switch modes (manual → auto), initialize the integrator so the output doesn't jump — bumpless transfer.

6 · The symptom table

Tape this to the cabinet:

SymptomLikely causeFirst move
Steady offset, never closesNo / too little integralDecrease Ti (more integral)
Slow, large-period cyclingToo much integralIncrease Ti; check valve stiction
Fast oscillation around setpointToo much proportionalCut Kp by half, retune
Actuator buzzes, runs hotUnfiltered / excessive derivativeFilter D; reduce Td; check sensor noise
Huge overshoot after saturationIntegrator windupAdd clamping / back-calculation anti-windup
Overshoot only on setpoint changesDerivative (or P) acting on errorDerivative on measurement; setpoint ramping
Great on the bench, drifts on the lineProcess changed (load, temperature, wear)Re-identify; consider gain scheduling

7 · When PID isn't the answer

PID with these practices covers an enormous share of industrial control — but not everything. Strongly coupled multi-axis dynamics, pose-dependent inertia, contact tasks: there the right move is model-based control with PID-class loops inside it — the architecture we walked through in What It Really Takes to Make a Robot Move Precisely. And in motor control, the current loops living deepest inside Field-Oriented Control are themselves PI controllers, tuned analytically from the motor's R and L — that one deserves its own hands-on article (coming next).

Need a loop tuned — or forty?

Tuning one PID is a craft; commissioning dozens of interacting loops on real machinery — ovens, rigging, motor drives — is our day job at Segev Technologies. If your process cycles, your axis rings, or your controller "worked in simulation" — let's talk.


Grounded in: J. G. Ziegler & N. B. Nichols, "Optimum Settings for Automatic Controllers," Trans. ASME, 1942; K. J. Åström & R. M. Murray, Feedback Systems (free online edition), ch. 11; lambda/IMC tuning rules as summarized by OptiControls; implementation practices popularized by B. Beauregard's "Improving the Beginner's PID" series.

Share
05 — Contact

Have a hard engineering problem?

Email
rotem@segevtech.com
Tel
+972-52-6444408
Studio
Tel Aviv, Israel