Bench note

PID tuning without the spreadsheet theater

Start with a known step

Every PID tuning guide begins with Ziegler-Nichols or a table of "typical" gains for motors you don't own. Skip that. Record a step response: command your actuator from zero to a fixed setpoint, log the output at a consistent interval, and save the CSV. You need position or velocity over time, sampled fast enough to see overshoot. If your logger drops samples or your setpoint drifts, the math that follows is decorative.

A real step response shows you three things: settling time, overshoot, and whether your system oscillates or crawls. Those observations map directly to P, I, and D. No coefficient will fix a mechanical problem—if your linkage binds or your sensor lags by 100 ms, tuning is theater.

Tune P until it rings

Set I and D to zero. Increase your proportional gain until the system oscillates sustainably around the setpoint. Write down that gain (K_u) and the period of oscillation (T_u). If it never oscillates, your actuation is too weak or your feedback loop is open somewhere. Check your wiring before you invent a new control law.

Once you have K_u and T_u, calculate starting gains:

  • K_p = 0.6 × K_u
  • K_i = 1.2 × K_u / T_u
  • K_d = 0.075 × K_u × T_u

These are Ziegler-Nichols classic coefficients. They will overshoot. That's expected. You're buying margin to tune down, not up.

Add I only if you have steady-state error

Integral gain eliminates offset, but it also adds lag and invites windup. If your step response settles within 2% of the setpoint using only P, leave K_i at zero. If you see consistent undershoot—position drifts back after settling—raise K_i in small increments until the error disappears. Then halve it. Integral windup during saturation will wreck your transient response if you're greedy here.

When you do enable integral action, clamp the accumulated error. If your actuator hits a limit (max duty cycle, end stop, thermal cutoff), freeze or decay the integrator. Otherwise the next move will be violent. This is not optional.

Use D to damp overshoot, not to fix P

Derivative gain predicts where the error is going and brakes early. It turns one-ring oscillation into a clean approach. But D amplifies noise—if your sensor jitters, derivative kick will scatter your control signal. Low-pass your velocity estimate or accept that D will stay near zero.

If you need more damping than D can provide without noise problems, your proportional gain is too high. Go back and reduce K_p before you add filtering stages that delay your response by a full sample.

Log everything or guess forever

You cannot tune a controller you cannot see. Your firmware should write setpoint, measured output, error, and control signal to a buffer every loop iteration. Flush that buffer to a file or serial port after each test. Plot it. If your first attempt undershoots, increase K_p by 20% and run again. If it rings, cut K_p and add a bit of D. Compare before-and-after plots side by side.

This is why closed-loop work requires instrumentation you trust. A PID controller with no telemetry is a parameter guessing game, and you will lose.

When to stop

You're done when your system reaches 95% of the setpoint in an acceptable time with less than 10% overshoot, and disturbances settle within two oscillations. Write those final gains in a header comment with the test date and hardware revision. You'll need them again when you clone this board or someone asks why the robot moves the way it does.

PID tuning is not an art. It's a measurement discipline. Measure, adjust, measure again. The spreadsheet comes after, when you're documenting what worked.

Also on this bench