DC Motor Speed Control Part I: Open-Loop Command
DC Motor Speed Control Part I: Open-Loop Command
DC Motor Speed Control Part I: Open-Loop Command
One way to construct a cheap experimental setup for motion control is to find a used
DC servomotor with encoder equipped. Quality control of second-hand stores is a
major problem; not everyone would be lucky to find a set in good-condition. There
is no simple way to verify that the encoder is working okay. Fortunately, brand new
DC motor with encoder unit can now be bought online within budget. An example is
DC motor product line from www.pololu.com . Here we select their 19:1 Metal
Gearmotor 37Dx52L mm with 64 CPR Encoder product as shown in Figure 1.
This motor is equipped with a bare incremental encoder at the bottom as in Figure 2.
A 12V power source is needed to drive the motor, and 5V for the encoder circuit.
For other specs, please refer to the data on Pololu website.
scilab.ninja
DC Motor Speed Control Part I: Open-Loop Command
H-bridge Driver
There are many H-bridge motor driver products from various vendors including
Pololu. It happens that I have an old board moel HMD-10A from Anycontrol Ltd,
Thailand handy. It works fine in the desired setup. What makes this driver different
from other products is the inverse polarity of PWM signal; i.e., the motor speed is
proportional to the duty cycle of logic 0. So to make the controller algorithm less
confusing, I use 1/6 of 74LS04 hex inverter at the drive input to make motor speed
proportional to duty cycle of logic 1. The inverter also functions as a 3.3 to 5 volt
level shifter and an buffer to the PWM output.
Since our simple experimental setup does not need any load at the motor output, it is
convenient to mount DC motor, H-bridge drive and interface protoboard on a piece
of wood as shown in Figure 3. The board on the left (not screwed on wood) is our
PIC32EP256MC202 module. The prototype is soldered and wired as in Figure 4.
Such board could be assembled easily with budget around USD 20. Actually, not all
components shown in Figure 4 are needed for the experiment in this article.
2
DC Motor Control Series
Open-Loop Experiment
To perform an initial test for our DC motor setup, we attempt to drive the motor in
an open-loop fashion. This involves sending a pair of signals: PWM for motor
speed, and DIR for direction (0 = clockwise and 1 = counter-clockwise). The PWM
module is setup for 16-bit resolution as explained in “A Note on Output Compare
(PWM) Module of PIC24E” article, with one exception. In that article the PWM
module obtains the clock source from the peripheral clock, whose frequency is too
high for our DC motor driver. This makes it difficult to command low-speed turning
of the motor. So we instead assign a timer output as clock source to the PWM. For
example, to use timer 2, setup OCTSEL bits in the OC1CON1 register as follows
OC1CON1bits.OCTSEL = 0b000; // select Timer 2 as clock
Then initialize timer 2 to the desired frequency. Say, to set timer 2 interrupt at 8.7
KHz rate,
void initT2() // Initialize Timer 2 to use as PWM clock
{
_T2IE = 0; // disable first
T2CON = 0x8010 ; // Internal Clock (FOSC/2)=70MHZ,
PR2 = 1000; //ts/(tcy*64) where tcy = 1/70M
TMR2 = 0x0000 ;
_T2IF = 0;
_T2IE = 1;
}
Do not forget that, even though timer 2 has no particular task in its service routine,
we need to reset _T2IF so that the next timer interrupt could occur
3
DC Motor Speed Control Part I: Open-Loop Command
The open-loop test needs no feedback. Even though the actual RPM is read from the
QEI module of PIC24EP, the data is used for plotting a comparison only.
Construct a speed command variable scmd, in the range of +/- 500 RPM. Whenever
this variable is updated by the user in real-time, the DIR value is determined by the
sense, and PWM value is computed accordingly and written to the OC1R register.
The C-code for such task can be written as follows
if (scmd < 0) { // negative sense
PWMVal = (unsigned int)-scmd*PWMMAX/MAXRPM;
if (PWMVal>PWMMAX) PWMVal = PWMMAX;
DIR = 1; // CCW direction
}
else { // positive sense
PWMVal = (unsigned int)scmd*PWMMAX/MAXRPM;
if (PWMVal>PWMMAX) PWMVal = PWMMAX;
DIR = 0; // CW direction
} // if (scmd < 0)
OC1R = PWMVal;
Now, to obtain the actual motor speed, we simply read from the VEL1CNT register
of QEI1 module, and convert to RPM
QEIvVal = VEL1CNT; // read velocity each vsamp
srpm = 60*QEIvVal/(Ts*4*ENCPPM); // actual motor speed in RPM
where Ts is the sampling period, and ENCPPR is defined as total number of encoder
pulses per round, 1200 for this motor. Note that the QEI module is set up to detect
4
DC Motor Control Series
each rising and falling edges of quadrature signals A and B. This increases the
resolution 4 times.
Set the speed command variable scmd to 10 RPM. The plot in Figure 5 compares the
actual motor speed to the command. Well, from this comparison, the open-loop
speed control performs poorly. The speed error is more than 150 %. This might
come from certain factors. Our linear estimation of the PWM versus motor speed
relationship could be inaccurate, or data from the manufacture is obtained from a
different setup. etc.
In any case, without feedback one could not hope for a reliable speed regulation. In
the next article, we will exploit PID feedback to cope with this speed error and
combat disturbances such as when load changes.