Here we have the basic formula of a Proportional Integral Derivative controller. This is the formula from the Wikipedia page on the subject
I want to implement this type of controller in my system. Currently the system (function in the software) is fed a psi value and told to set an analog output to a value so that this pressure is achieved. The function, lets call it SetPressure(int psi)
, has access to a table of psi vs analog signal output, it does quick binary search and finds the closest match and sets the analog output to that match.
This is not good enough for when the machinery/valves "wears in".
So now I have access to a pressure transducer to tell me the actual pressure in the line I am trying to control. It gives me an analog input to my function. I would like to figure out, given these values of commanded and actual values, how to create a software PID.
So, the first value is easy; P. This is found by determining the error in the value error = DesiredValue - ActualValue
and multiplying it by some proportional gain Kp
. So P = Kp*error
this is easy enough to understand. After some tuning I should find a suitable value of Kp
such that I can control the pressure a little better.
But what about if I would like to find the I and D?
The software this PID runs in is real time. It gets called every few milliseconds and reads the inputs and determines the outputs based on its state.
I guess for a start, where do I go from here to get I and D. I understand that there are gains for each of these terms but I am not sure about how I calculate the entire term.
For instance, Do I need to save each calculated error for each time t so that I might find the integral? This seems it would be a waste of memory, saving each error for each moment in time would accumulate to a huge list in a matter of seconds.
Any help is appreciated. Please ask for clarification if needed, and note this is my first time working with something like this.
.
Code Sample so far:
(anaOutput[PRESS_OUT_DAC] is already determined above in the code from the analog vs psi table)
float KpPressure = 1; // These gains are to be determined
float KiPressure = 1;
float KdPressure = 1;
float MVout = anaOutput[PRESS_OUT_DAC]; // Init to output
if(anaInput[PRESS_IN_DAC] != anaOutput[PRESS_OUT_DAC])
{
// error = SetPoint - ProcessValue
float error = (float)anaOutput[PRESS_OUT_DAC] - (float)anaInput[PRESS_IN_DAC];
// Pout = Kp * error
float Pout = KpPRessure * error;
// Iout = Ki * Int(0,t)[error(t)]
float Iout = KiPressure * 1; //// What should 1 be?
// Dout = Kd * (d/dt)[error(t)]
float Dout = KdPressure * 1; //// What should 1 be?
// Manipulated Output = Combination of PID
MVout = P + I + D;
}
if(MVout > MAX_SIGNAL)
MVout = MAX_SIGNAL;
anaOutput[PRESS_OUT_DAC] = (UWORD)MVout + ANALOG_ZERO;