Electrical – Implementing a deadband on a PID controller for a dc motor

dc motormicrocontrollerpid controller

I've been building a system to control motor position using a microcontroller.
But I faced some problems during the implementation of the PID controller and I found out, thanks to this article: http://www.wescottdesign.com/articles/Friction/friction.pdf
that the problem is friction. The following image shows the response of my system using a PI controller:enter image description here

Where the orange line is the PID output variable and the blue line is the angle of the motor axis(what I want to control). If you compare this image to figure 12 on page 12 of the article posted above we can conclude that friction is the problem.
Also in the same article one of the given solutions is to apply a deadband to the controller but I'm having some difficulties understanding how to implementing it. If my PID controller code is:

angulo = (encoder*360)/(4*102.0);
erro = setpoint - angulo;

d_term = kd*((erro - erro_ant)/0.00125);
i_term = i_term + ki*(0.00125*erro);

output = kp*erro + d_term + i_term;

erro_ant = erro;

if ( output >= 0 )              
{                               
    direcao(1);
    setPWM(fabsf(output));
}
if ( output < 0 )               
{                               
    direcao(0);
    setPWM(fabsf(output));
}

The direcao() function will change the h-bridge pins to make the motor rotate in the correct direction.
And what I fought to do was:

...
erro_ant = erro;

if (error is within deadband)
{
    setPWM(0);
}
else
{
    if ( output >= 0 )              
    {                               
       direcao(1);
       setPWM(fabsf(output));
    }
    if ( output < 0 )               
    {                               
       direcao(0);
       setPWM(fabsf(output));
    }
}

or

...
erro_ant = erro;

if (error is within deadband)
{
    output = 0;
}
if ( output >= 0 )              
{                               
    direcao(1);
    setPWM(fabsf(output));
}
if ( output < 0 )               
{                               
    direcao(0);
    setPWM(fabsf(output));
}

I also fought about setting the integral term to zero, when it is within the deadband, but that will act as a anti-windup technique when the system overshoots.

Thanks in advance to anyone who answers.

Best Answer

It's a common fact that a drive system has a resonance frequency due to moment of inertia and the elasticity of the transmission. If you have a high closed loop gain, then the system is always "nervous" waiting for dynamic action. To overcome this small oscillations problem in a professional equipment you set the notch filters to eliminate this resonance frequency. This is done by injecting signals and draw Bode plot. You can add a lowpass filter, but you will loose the dynamics, or you might decrease the gain.

Introducing the dead band means introducing the nonlinearity in the system. Perhaps there are better solutions rather a dead band for the drive control.

The professional drive controllers I have used, have an adaptation of Kp and Ti with regard the input value. At low error, the Kp is low and Ti is slightly higher. This could be also a way to go.

enter image description here

For example, you do the abs() on input then you make a linear function with minimal Kp at low input error and nominal Kp at high input error.

If you want a deadband anyway, you have a formula already in the article (29) and (30) give the new transformed input as depicted in figure 16. enter image description here enter image description here enter image description here

To be continued...