int16_t CalculatePID(MotorHandleTypeDef *motor)
{
float error = motor->TargetSpeed-motor->Speed;
/// calculate total error
motor->PID.TotalError+=error;
/// Check if the calculated total error value is in boundries
if(motor->PID.TotalError>motor->PID.MaxTotalError)
motor->PID.TotalError=motor->PID.MaxTotalError;
else if(motor->PID.TotalError<-motor->PID.MaxTotalError)
motor->PID.TotalError=-motor->PID.MaxTotalError;
/// Calculate the result of PID
float duty=(motor->PID.P*error) + (motor->PID.I*motor->PID.TotalError)+(motor->PID.D*(error-motor->PID.PreviousError));
motor->PID.PreviousError=error;
if(duty>1)
duty+=motor->PWM_Offset;
else if(duty<-1)
duty-=motor->PWM_Offset;
duty+=motor->PID.FeedForward*motor->TargetSpeed;
/// Check if the Calculated Duty values are in boundries
if(duty>motor->MaxDuty)
duty=motor->MaxDuty;
else if(duty<-motor->MaxDuty)
duty=-motor->MaxDuty;
/// Return calculated value
motor->Duty=duty;
return (int16_t)duty;
}
Hi everyone.
I am trying to make an efficient dc motor speed controller and this is my PID update function. I am running my update loop in 1 kHz. The DC Motor I am using is 24 VDC 100 Watt with 6000 CPR quadrature encoder. I am using Single Dimensional Kalman Filter to calculate motor speed that is running in 2 kHz. With this method there is almost no delay and ripple in speed calculation yet I am keeping my pid frequency lower than encoder update frequency to avoid errors that can be caused by the lag. I have tuned the PID parameters using Genetic Algorithm by using 400 individuals so I am thinking that the parameters are almost at their best. I am also applying speed feed forward control that's coefficient is 0.95.
Open loop step response of the motor has a rise time of 150 ms and the best rise time that I get with PID is 55 ms. I have posted one the output samples for lower 10 and 20 RPMs. (Dont worry about the overshoot. There is a motion planner on higher control level so it will be tolarated)
I would like to know if there is a way to lower this rise time to around 30ms or is this the best I can get from a brushed DC motor?