## PDI Feedback Controller Program

I've built a PDI feedback controller for the AVR which can seek and
hold a specific value. Load is still a capacitor+resistor hooked up
to a VCO. The controller uses 3 terms to set the output from the
input:

1. Proportional: a multiple of the error.

2. Derivative: a multiple of the first derivative of the error.

3. Integral: a multiple of the sum over time of the error.

This is a standard controller type which is easily implemented in
software. The salient code is:

for (i = 0; i < SUM_LENGTH - 1; i ++) error[i] = error[i + 1];
error[SUM_LENGTH - 1] = input - target;
...
deltaError = error[SUM_LENGTH - 1] - error[SUM_LENGTH - 2];
...
sumError = 0;
for (i = 0; i < SUM_LENGTH; i ++) sumError += error[i];
...
y = output + kP * error[SUM_LENGTH - 1] + kD * deltaError + (kI * sumError) / SUM_LENGTH;
newOutput = y + 0.5;

where the equation for y updates the output using the P, D, and I
terms. Currently I am sampling and making 1 correction per second.

The coefficients for the controller can be set graphically by
observing the step response to the system. The attached screenshots
(60 sec per plot) show:

1. A step response from 0 to 127 (half the range) using a P
coefficient of -0.5. The control signal is in blue, the hardware
response is in red, and the target value is green. The system shows a
damped oscillation about the target value.

2. Decreasing the P term to -2.25 just produces a sustained
oscillation.

3. Adding a D term of -3.25 damps the oscillation without overshoot.

4. Adding an I term of -0.125 adds just a little overshoot, slightly
decreases setting time, and increases stability.

5. System response to changing the target from 127 to 63, to 191, and
back to 127.

6. Uncontrolled response to varying the load by inserting and removing
a resistor across the capacitor.

7. Tracked response to the same varying load.

As you can see, the transient response to a large change is a little
better than to a smaller change, but there are some things I can do
about that. The next thing is to do this with a real motor!

İSky Coyote 2006