# How can I improve DC Motors rise time?

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?

• Don't saturate the PID input (the error). Rather, you ought to apply saturation to the PID output (feedback duty) and let the integral know what's going on by implementing the anti-windup. Also, the way the derivative is coded is kind of naive. Jan 16, 2021 at 11:57
• I don't think I am saturating the input and there is an anti wind up control in the code too. there is also saturation control at the output of pid. What is the correct way to code derivative term? Kp is Zero by the way Jan 16, 2021 at 12:16
• You're right! Sorry, I got confused between error and total_error. Concerning your question, do you have a model of your physical system? Having used a global optimization tool (GA), your intuition on the best estimates of gains is likely true. Nonetheless, you might exploit the physical properties of the system and run some sort of traditional control techniques around the model. Jan 16, 2021 at 12:27