I am looking at code references for simple PID implementation in arduino.
these are the few implementations YMFC
pid_error_temp = gyro_pitch_input - pid_pitch_setpoint;
pid_i_mem_pitch += pid_i_gain_pitch * pid_error_temp;
if(pid_i_mem_pitch > pid_max_pitch)pid_i_mem_pitch = pid_max_pitch;
else if(pid_i_mem_pitch < pid_max_pitch * -1)pid_i_mem_pitch = pid_max_pitch * -1;
pid_output_pitch = pid_p_gain_pitch * pid_error_temp + pid_i_mem_pitch + pid_d_gain_pitch * (pid_error_temp - pid_last_pitch_d_error);
if(pid_output_pitch > pid_max_pitch)pid_output_pitch = pid_max_pitch;
else if(pid_output_pitch < pid_max_pitch * -1)pid_output_pitch = pid_max_pitch * -1;
pid_last_pitch_d_error = pid_error_temp;
error_sum[PITCH] += errors[PITCH];
deltaErr[PITCH] = errors[PITCH] - previous_error[PITCH];
previous_error[PITCH] = errors[PITCH];
pitch_pid = (errors[PITCH] * Kp[PITCH]) + (error_sum[PITCH] * Ki[PITCH]) + (deltaErr[PITCH] * Kd[PITCH]);
double PTerm = kp * error;
integral += error * (double) (timeChange * .000001);
ITerm = ki * integral;
// Derivative term using angle change
derivative = (input - lastInput) / (double)(timeChange * .000001);
DTerm = (-kd * derivative);
//Compute PID Output
double output = PTerm + ITerm + DTerm ;
void Compute()
{
/*How long since we last calculated*/
unsigned long now = millis();
double timeChange = (double)(now - lastTime);
/*Compute all the working error variables*/
double error = Setpoint - Input;
errSum += (error * timeChange);
double dErr = (error - lastErr) / timeChange;
/*Compute PID Output*/
Output = kp * error + ki * errSum + kd * dErr;
/*Remember some variables for next time*/
lastErr = error;
lastTime = now;
}
can any one give me explanations for following :
YMFC code the i term is
pid_i_mem_pitch += pid_i_gain_pitch * pid_error_temp;
why he multiplying with error ? labodol is just adding the previous error with present error and other two are multiplying it with time change
any other simple implementation suggestions also welcome.
The lobodol and YMFC systems work without using the time constant, because the code is written in such a manner that the Arduino would not do anything other then the control.
As such the time difference between calculations of P, I and D error would remain the same.
There is no difference in how you would tune these systems to how you would tune any other PID system.
While this system works, this also means that the final tuned PID values would only be used with these systems and not to any other.
The other systems which are using the time difference in their calculations. This means that the tuned PID values could be used(More reliably as compared to lobodol and YMFC) with other systems as well.
In the YMFC implementation
pid_i_mem_pitch += pid_i_gain_pitch * pid_error_temp;
^
Note the '+' sign before the '=' sign. This means that the error is getting added. Just that the gain multiplication is being done before addition as opposed to after addition.
Both methods yield the same (theoretically) result.
I hope this helps.