DC Motor Speed Control Part II: PID Feedback

From our previous article DC Motor Speed Control Part I: Open-loop Command, an experimental setup for DC motor is constructed and tested. The result shows that the command and actual motor speed differ significantly. Not a surprise. An open-loop control scheme cannot regulate the speed because no feedback is applied. So in this article, a PID control is deployed.

Figure 1 shows a simplified block diagram of closed-loop DC motor speed control. This diagram is drawn as a big picture for general audience to understand. Speed feedback is actually read from the QEI module of PIC24EP, so the leftmost summing junction should be inside the microcontroller. Anyway, we draw it explicitly to show the feedback structure more clearly.

Figure 1 a closed-loop DC motor speed control scheme

The PID algorithm is a discrete-time version with derivative term replaced by filter transfer function

(1)   \begin{equation*}  C(z) = K_p + \frac{K_iT_sz}{z-1} + \frac{K_dN(z-1)}{(1+NT_s)z-1} \end{equation*}

How to convert (1) to computer software algorithm is explained in Discrete-time PID Controller Implementation. The algorithm is put into ISR of timer 1. Note that the controller coefficients are functions of PID gains (K_p, K_i, K_d), filter coefficient N, and sampling time T_s. So whenever any of these parameters changes, the controller coefficients need to be recomputed. This can be written as a function

// ------------ PID control function ----------------------
void vPIDSetup(void)
// -- this function must be invoked anytime
// -- any parameter involved is changed by user
    _T1IE = 0;  // disable timer 1
    a0v = (1+Nv*Ts);
    a1v = -(2 + Nv*Ts);
    // a2 = 1;
    b0v = Kpv*(1+Nv*Ts) + Kiv*Ts*(1+Nv*Ts) + Kdv*Nv;
    b1v = -(Kpv*(2+Nv*Ts) + Kiv*Ts + 2*Kdv*Nv);
    b2v = Kpv + Kdv*Nv;
    ku1v = a1v/a0v;
    ku2v = a2v/a0v;
    ke0v = b0v/a0v;
    ke1v = b1v/a0v;
    ke2v = b2v/a0v;
    _T1IE = 1;   // enable timer 1
    _T1IF = 0;   // reset timer 1 interrupt flag
    SysFlag.VPIDchg = FALSE;  // reset PID change flag

Note that variable names are ended with v to indicate they are used in velocity feedback loop, to distinquish from position feedback in case it is also implemented in the same system. To guard against read-modify-write problem, timer 1 is disabled during coefficient update.

For the PID algorithm, what is different from the code in our previous article is the output part. Now we have to convert a single control variable to a pair of signals PWMVal and DIR (see Part I). The conversion is straightforward. When the output is positive, it is sent out directly (limited by maximum possible value) and DIR is set to 0. On the other hand, when the output is negative, it is converted to positive value and DIR is set to 1. The code below shows how to implement the PID algorithm for our DC motor setup

        e2v=e1v;  // update variables
        e0v = scmd - srpm;  // compute new error
        u0v = -ku1v*u1v - ku2v*u2v + ke0v*e0v + ke1v*e1v + ke2v*e2v; 
        if (u0v>=0)  {  // positive sense
            if (u0v>PWMMAX) u0v = PWMMAX;  // limit to PWM range
            PWMVal = (unsigned int)u0v;
            DIR = 0;
        else   {  // negative sense
            u0vn = -u0v;
            if (u0vn>PWMMAX) u0vn = PWMMAX;
            PWMVal = (unsigned int)u0vn;
            DIR = 1;
        OC1R = PWMVal;

Closed-Loop Speed Control

A global variable is defined so that the feedback loop could be open or closed by user command. Figure 2 shows step response of closed-loop system when the motor is commanded to rotate at speed 10 RPM. The controller gains are set at K_p = 200, K_i = 100, K_d = 50. We see that at steady state, the motor speed is regulated around 10 RPM, the commanded value. The response is not very smooth due to the speed readout is rounded to integer value. Comparing this to the open-loop response in part I, we see clearly the benefit of feedback.

Figure 2 closed-loop step response of DC motor to speed command at 10 RPM

Another important property of feedback control is disturbance rejection performance. Disturbance could be the result of, say, load change. An easy way to demonstrate output disturbance for this small DC motor is by grabbing the motor shaft with your fingers ( for your own safety, never attempt this on a high power motor). With no feedback, you can momentarily slow down or stop the rotation. In contrast, a closed-loop speed control commands the motor to generate more torque to combat the speed loss. You could feel the torque increase on your fingers.

Figure 3 shows disturbance rejection property of the closed-loop motor speed control. The motor is commanded to rotate at 100 RPM. Then at t = 5 seconds, I apply more load by grabbing the motor shaft. The speed regulation is disturbed, but then compensated by the controller so that the response remains regulated at 100 RPM.

Figure 3 closed-loop response when output disturbance is applied at t = 5 seconds



Comments are closed.