ME 333 Introduction to Mechatronics
Lab 4: PIC Control of a DC Motor and Servo Motor

In this lab you will use the items in your lab kit (including the batteries or power adapters as opposed to the bench supplies) to do encoder-based control of a DC motor and control of an RC servo. Most of what you need to do this lab can be found on the mechatronics wiki, so there is little instruction here.

You have two tasks in this lab: (1) velocity control of the Faulhaber DC motor using software encoder counting; and (2) control of the position of an RC servo motor.

There is no answer sheet for this lab. Just print out your well-documented code for each of the two tasks and answer any questions either on those printouts or separate sheets.

1. Controlling a DC Motor with an Encoder

Last lab we used a potentiometer for motor feedback. This is cheap and easy, but it has a few drawbacks: a potentiometer requires an analog input, it has a limited rotation range, and the effective resolution may be low. A much more common (and only slightly more expensive) solution is to use an encoder (see the wiki page on encoders). The Faulhaber motor we have has a 141:1 gearhead and an encoder on the motor shaft that uses Hall sensors to provide one A and B pulse per revolution of the motor, so that you can count up to 141 x 4 = 564 counts per output shaft revolution in x4 decoding mode (see the wiki page on this motor-encoder-gearhead combination).

You will keep track of how far the motor has rotated by counting encoder pulses in x4 decoding mode. You will do this by using an interrupt service routine (ISR) that is called every 1 ms. The ISR counts any changes in the encoder state and implements the control law, which compares the actual velocity to a velocity commanded by a potentiometer knob and produces pulse-width modulation to try to reduce the error.

Proportional-integral (PI) control is a common scheme for velocity control. In PI control, the control signal is proportional to Kp (the proportional gain constant) times the velocity error, plus Ki (the integral gain constaint) times the time-integral of the velocity error (i.e., the position error). We don't have a direct measurement of velocity (which could be provided by a tachometer), so we would have to estimate it by subtracting a previous position from the current position and then dividing by the elapsed time. (There are lots of more fancy ways to do this; this is a topic for digital filtering.) But we won't bother with that in this lab, and instead we will construct a simple integral (I) controller, which produces a control signal proportional to the position error. Your program must keep track of where the motor should be, based on integrating the commanded velocity from the potentiometer. Your potentiometer analog input, which is between 0 and 5V, has 0 corresponding to maximum CW velocity, 2.5V corresponding to 0V, and 5V corresponding to maximum CCW velocity.

  1. Check your battery pack voltage. Is it fully charged?

    Power your motor with the battery, power the encoder with 5V (make sure you check the wiki for proper connection to the encoder and motor!), and using your oscilloscope, record how many pulses per second the A channel of the encoder makes. How many counts per second does this correspond to in x4 decoding mode? Explain whether your 1 ms software encoder counting scheme will be fast enough to be guaranteed to catch all counts. If not, what is the maximum voltage that should be applied across your motor to assure correct counting? You will use this to determine the maximum PWM rate in your controller.

  2. Write a program that, every 1 ms, reads the potentiometer input, converts to a commanded velocity, updates the commanded position, and implements the I controller. Use code on the wiki as your starting point, and the L293D H-bridge chip to power the motor (this can be powered by your battery pack). Your ISR should also set a digital output high at the beginning of the ISR, then set it low at the end of the ISR, so we can keep track of how long the ISR taks to execute.

    Draw your circuit diagram showing the connection of the L293D to the motor and the PIC. Looking at the oscilloscope trace of the digital output set high and low in the ISR, how long does it take for the ISR to execute? Is it less than 1 ms? If not, can you make it shorter by using simpler math? If you can't shorten enough, two options are (1) use a different ISR, executed less frequently, that computes the control law (leaving the 1 ms ISR for the encoder counting only), and (2) just use one ISR, but make it execute less frequently. If you need to, modify your program to make sure that the ISRs always complete in the time between ISR calls.

    Once your program is working and you can demonstrate that the PIC controls the velocity to be proportional to the potentiometer angle, print out your code and have the TA sign off on (1) a demonstration of motor control, and (2) an oscilloscope trace of the PWM signals to your L293D.

  3. We can count encoder counts at a much higher rate (e.g., for faster motors or encoders with more lines) by using hardware counting instead of software counting. Beginning from the hardware counting code on the wiki, draw a circuit diagram showing how an LS7083 can be connected to the PIC and the encoder to allow the PIC to count encoder counts in hardware without having to constantly check the encoder channels in software.

2. Controlling an RC Servo Motor

Beginning with the sample code on the wiki, write a program so that an RC servo motor spins to an angle proportional to the angle of an input potentiometer. Look at the RC servo control signal on the oscilloscope and see how it changes as you rotate the pot. Print out your well documented code and have the TA sign off after a demonstration.