Improving dcservo accuracy
Not being an expert in motor control, I created dcservo project to make a basic platform to create cheap servomotors that could replace stepper motors on certain systems, like 3D printers. I chose to implement a full PID controller but that might have been a bit overkill.
I was talking today to a more knowledgeable colleague who asked me why I needed a PID. My answer was that without the integral action I was getting a significant position error in the steady state, and the derivative action, though a really small value, was needed to keep the system from overshooting. However, he suggested me to focus only on a simpler, proportional controller with a twist: most of my position error is coming from the fact that there is a dead zone where motor does not respond to control action.
It is true, though the motor will move faster the higher the PWM value it is applied to the motor drive, it is also true that low values (between 1 and 50 in my test system) do not cause the motor to move.
I was willing to know how much a difference that could make. The change is actually just a line of code:
In the motor PWM output code. 'm' is the absolute value of the output from PID controller and what I am doing now is to scale the values from 1...255 to a new range from 50...255, so any output different than 0 is actually causing the motor to move, thus removing effectively the dead-zone.
I was talking today to a more knowledgeable colleague who asked me why I needed a PID. My answer was that without the integral action I was getting a significant position error in the steady state, and the derivative action, though a really small value, was needed to keep the system from overshooting. However, he suggested me to focus only on a simpler, proportional controller with a twist: most of my position error is coming from the fact that there is a dead zone where motor does not respond to control action.
It is true, though the motor will move faster the higher the PWM value it is applied to the motor drive, it is also true that low values (between 1 and 50 in my test system) do not cause the motor to move.
I was willing to know how much a difference that could make. The change is actually just a line of code:
if( m>0 ) m = map(m,1,255,50,255);
In the motor PWM output code. 'm' is the absolute value of the output from PID controller and what I am doing now is to scale the values from 1...255 to a new range from 50...255, so any output different than 0 is actually causing the motor to move, thus removing effectively the dead-zone.
The purple line represents the position error of a collection of consecutive movements to different random locations using just a proportional controller with a gain close to the critical gain. While the green line represents the same error when using the same proportional controller with dead-zone elimination code (proportional gain was reduced ten-fold to keep the system from oscillating).
Having only a proportional controller makes tuning much simpler and faster now, so I think it is a big improvement over the existing code.
Comments
Question:
Can DCServo be used in combination with Klipper, now that as of December Klipper has added experimental support for closed loop steppers (Mechaduino, uStepper, etc) and has a development branch dedicated to closed loops (see discussion #1038).
Would the DCServo code need to be integrated into the Klipper firmware, or can a second Arduino sit in front of the DCServo Arduino in a sort of Daisy Chain with Klipper as the master controller?