Tuning a PID is adjusting the gains Kp, Ki, and Kd until you get a stable and useful response for your plant.
We already know what each part of the controller does. P reacts to the current error, I corrects accumulated error, and D dampens the trend. Now comes the part that usually hurts: choosing the numbers.
Because yes, in the end, someone has to put concrete values in the code:
float Kp = 2.0;
float Ki = 0.5;
float Kd = 0.1;And those values don’t come from a universal table. They depend on the plant, the sensor, the actuator, the sampling time, the load, the physical limits, and even on how badly a screw is tightened. Welcome to the real world.
Before Touching Gains
Before tuning anything, it’s good to have three things clear. Otherwise, you’ll chase ghosts for hours.
First, the sampling time must be constant. If the PID runs sometimes every 5ms and other times every 40ms, the gains don’t mean the same thing in each cycle.
Second, the controller output must be limited to the real range of the actuator. A PWM motor can go from 0 to 255, a valve from 0% to 100%, a servo from a certain minimum angle to a certain maximum angle.
Third, you need to measure the response. Even if it’s with a Serial Plotter, a CSV, or a crude graph. Tuning a PID just by looking and thinking “it seems fine” is a great recipe for fooling yourself.
Empirical Method to Start
For small real-world projects, we often use manual tuning. It’s not glamorous, but it works quite well if you have patience.
The typical sequence is this:
- Set
Ki = 0andKd = 0. - Slowly increase
Kpuntil the system responds quickly, but without becoming unstable. - If it starts oscillating, lower
Kpa bit. - Slowly add
Kito eliminate steady-state error. - If too much overshoot appears, lower
Kior add someKd. - Add
Kdonly if you need to dampen oscillations or reduce overshoot.
Adjust one gain at a time. If you change Kp, Ki, and Kd all at once, you won’t know which one fixed the system or which one broke it.
The idea isn’t to find the perfect number on the first try. It’s to approach it step by step, observing what changes in the response.
How Each Gain Manifests
Although every plant has its quirks, there are quite repeatable trends:
| Gain | If we increase it, it usually… | If we overdo it… |
|---|---|---|
Kp | Makes the system faster and reduces initial error | Oscillation, overshoot, and instability |
Ki | Eliminates steady-state error | Windup, slow overshoot, and heavy recovery |
Kd | Dampens and reduces rebounds | Noise, vibrations, and nervous output |
This table doesn’t replace real testing, but it helps to not go completely blind.
A Practical Procedure
Let’s imagine we are controlling the speed of a DC motor with an encoder.
We start with Ki = 0 and Kd = 0. We increase Kp until the motor reaches the target speed quickly. If it falls short, we keep increasing. If it starts oscillating, we lower it by 20% or 30%.
Then we add Ki little by little. We want the steady-state error to disappear, but without the integral pushing for too long. If the motor overshoots a lot and takes time to return, Ki is too high.
Finally, we test Kd. If the system bounces, a small D can help. If the sensor is noisy, be careful, because D will amplify that noise quite happily.
When the actuator is strong enough to break something, tune with conservative limits. First, test gently; there will be time to tighten later.
Ziegler-Nichols
One of the classic tuning methods is Ziegler-Nichols. It’s old, well-known, and still appears in many books because it provides a reasonable starting point.
The sustained oscillation version works like this:
- Set
Ki = 0andKd = 0. - Increase
Kpuntil the system oscillates continuously. - That value is called
Ku(ultimate gain). - Measure the oscillation period
Tu. - Calculate the initial gains using a table.
For a classic PID, the typical table is:
| Controller | Kp | Ti | Td |
|---|---|---|---|
| P | 0.5 Ku | - | - |
| PI | 0.45 Ku | Tu / 1.2 | - |
| PID | 0.6 Ku | Tu / 2 | Tu / 8 |
If your PID uses the parallel form:
Then you can convert:
Ziegler-Nichols often gives aggressive adjustments, and taking the plant to the stability limit can be dangerous. It serves as a starting point when testing is safe; it’s not suitable for every process.
Why We Sometimes Skip Classic Methods
In an industrial environment, with a large plant and decent documentation, it makes sense to apply formal methods. In maker projects, small robotics, or experimental firmware, the plant often changes too much.
The battery drains, the robot’s weight changes, the motor heats up, the sensor introduces noise, friction varies. So a perfect laboratory adjustment can stop being perfect as soon as you take the device to the workshop floor.
That’s why we often use a reasonable mix:
- We understand what each gain does.
- We adjust manually with graphs.
- We limit output and integral.
- We filter the derivative if there is noise.
- We save the values and repeat tests.
It’s not as academic, but it avoids a lot of headaches.
Save and Compare
A simple tip: save your tests, even if it’s in a table in a notebook.
| Test | Kp | Ki | Kd | Result |
|---|---|---|---|---|
| 1 | 1.0 | 0.0 | 0.0 | Slow, steady-state error |
| 2 | 2.5 | 0.0 | 0.0 | Fast, some overshoot |
| 3 | 2.0 | 0.3 | 0.0 | No steady-state error, stable |
| 4 | 2.0 | 0.3 | 0.05 | Smoother |
When you’ve been tweaking numbers for 20 minutes, all attempts start to look the same. Having a history saves you from unnecessary backtracking.
Tuning a PID is about finding a compromise. We want a fast response, little steady-state error, little overshoot, little noise, and sufficient stability. All at once. It’s not easy, of course.
The manual method consists of adjusting Kp first, then adding Ki to eliminate steady-state error, and finally using Kd only if you need damping.