How to Tune a PID Loop: A 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:
Each term has a personality, and you can diagnose most loops just by knowing them:
| Term | What it does | Too much of it |
|---|---|---|
| P — proportional | Reacts to the error you have right now | Oscillation; never quite reaches the target alone |
| I — integral | Accumulates leftover error until it's gone; kills steady-state offset | Slow cycling, overshoot, windup after saturation |
| D — derivative | Reacts to the rate of change; brakes before the target | Amplifies 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:
Mixing up the two forms is the single most common reason "textbook gains" fail in a real device.
1 · Before you touch a gain
Twenty minutes of preparation saves a day of frustration. In order:
- 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.
- 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?
- 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.
- 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:
- Set K_i = 0, K_d = 0. Start K_p low.
- 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.
- 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.
- 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).
- 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.
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:
| Controller | Kp | Ti | Td |
|---|---|---|---|
| P only | 0.50 · Ku | — | — |
| PI | 0.45 · Ku | Tu / 1.2 | — |
| PID | 0.60 · Ku | Tu / 2 | Tu / 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:
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:
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:
| Symptom | Likely cause | First move |
|---|---|---|
| Steady offset, never closes | No / too little integral | Decrease Ti (more integral) |
| Slow, large-period cycling | Too much integral | Increase Ti; check valve stiction |
| Fast oscillation around setpoint | Too much proportional | Cut Kp by half, retune |
| Actuator buzzes, runs hot | Unfiltered / excessive derivative | Filter D; reduce Td; check sensor noise |
| Huge overshoot after saturation | Integrator windup | Add clamping / back-calculation anti-windup |
| Overshoot only on setpoint changes | Derivative (or P) acting on error | Derivative on measurement; setpoint ramping |
| Great on the bench, drifts on the line | Process 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.