AUTOMATIC SPEED CONTROL OF A DC MOTOR
This project is from a class EE2799 at Worcester Polytechnic Institute. The project is implemented using a Microchip PIC16F877 microprocessor. The control system is a PI controller. The display uses a 4-bit parallel LCD from Lumex. The code is written in Wiz-C a C compiler by FED. Details are provided concerning the Proportional-Integral control system as well as modeling our DC motor in Matlab and modeling the PI controller in Simulink. Next, implementing these controls into a discrete algorithm is explained.
Matlab Code for Continuous Model – Matlab simulation in continuous time for open loop motor response as well as closed loop PI controller response. Three graphs, (1) Open Loop of Motor (2) Closed Loop Proportional Controller (3) Closed Loop Proportional Integral Controller
Simulink Model for Discrete Controllers – Simulink model of closed loop PI controller in discrete time. User can change Kp, Ki, and sampling frequency.
Here is the schematic of entire system.

PIC16F877 C File – This file is the C file written in FED Wiz-C. Many comments are written within the code explaining its function.
The rest of the information is my chopped up final report. Some parts may be completely irrelevant and it’s kind of lengthy.
DESIGN OVERVIEW
The project is implemented using a Microchip PIC16F877 microprocessor. The control system is a PI controller. An analog signal will be sampled into the processor from a frequency to voltage converter from a tachometer provided on board the motor. The processor will then provide a PWM output that goes to a driving stage, which will drive the motor. Various support modules, including debugging components and user interface components are included. The display uses a 4-bit parallel LCD from Lumex. The code is written in Wiz-C a 3rd party compiler by FED. Details are provided concerning the Proportional-Integral control system as well as modeling our DC motor in Matlab and modeling the discrete PI controller in Simulink. Next, implementing these controls into a discrete algorithm is explained.
MICROPROCESSOR
The program will be written for use on a Microchip PIC 16F877. This processor runs at 20Mhz. The crystal oscillator loaded with two 20pF capacitors provides this clock signal. The processor has on board flash, which provides 8K of data memory, 368 bytes of RAM and 256 bytes of EEPROM data memory. We will not be using any of the EEPROM data memory, and most likely will not even use half of the available data memory however we picked this particular processor for other reasons outlined in homework 3. The processor requires a VDD of +5V and a VSS connected to GND. The PIC 16F877 provides three timers. Timer 2 will be used for the PWM module. Timer 0 will be used for sampling times. The processor has 8 channels of on board 10-bit A/D converters as well as one channel of 10-bit PWM output.
PINS OF 16F877
|
1 |
+5V |
40 |
LCD
D7 |
|
2 |
|
39 |
LCD
D6 |
|
3 |
A/D
Channel 1 |
38 |
LCD
D5 |
|
4 |
|
37 |
LCD
D4 |
|
5 |
|
36 |
LCD
E |
|
6 |
RA4
– Up Button |
35 |
LCD
R/W |
|
7 |
RA5
– Down Button |
34 |
LCD
RS |
|
8 |
RA6
– Reset |
33 |
|
|
9 |
RA7
– RPS |
32 |
VDD |
|
10 |
|
31 |
VSS |
|
11 |
VDD |
30 |
|
|
12 |
VSS |
29 |
|
|
13 |
Osc1 |
28 |
|
|
14 |
Osc2 |
27 |
|
|
15 |
|
26 |
|
|
16 |
|
25 |
RC6
– RS232 PIC Tx |
|
17 |
CCP1
– PWM Out |
24 |
|
|
18 |
|
23 |
|
|
19 |
|
22 |
|
|
20 |
|
21 |
|
A/D INPUT
The A/D on board the Microchip PIC16F877 microprocessor samples at 10-bits. The next section will describe the sampling frequency of the A/D conversion. There are seven analog channels multiplexed to one common A/D conversion chip. This could present noticeable cross-noise across separate channels, however since we will only be using one channel this problem is not a factor to us. We also do not need to switch between channels, which will simplify our task as well. Through the use of register ADCON1 we can select which pins are analog or digital pins. We can also select our VREF+ and VREF- values. For our purpose these values will be VCC=+5v and Gnd=0v respectively. Therefore we need to set bits PCFG3:PCFG0 to 1110. Therefore we are limited to an analog input to within +5V. This means the max 10-bit value, 3FFF (hex) will correspond to +5.0V. In the electrical characteristics of the data sheet, it states the voltage on any one of these pins should not exceed 5.3 volts and not go below –0.3 volts. This is very important because this is stated as an absolute maximum rating. Therefore our Frequency to Voltage converter in the previous stage must not go beyond these limits. It is required for the previous stage to give a full range of voltages from 0v-5v to give us full 10-bit accuracy. 0v corresponds to a sampled value of 0 (hex). 5v corresponds to a sampled value of 3FFF (hex).
We experienced a few problems using the A/D converter at first. As shown by our Gantt charts we wrote a simple A/D converter test program and built a test circuit to test its operation while we were still designing other aspects of the circuit. We were able to get a hold of a PIC processor before ours was shipped to us. This significantly put us ahead of other competition in the class, as we had a certain section of software known to be working. In fact, we probably would not have completed the project if we were to wait until the parts arrived, because of many unexpected problems with the ADC. The solution we found in the end came with many headaches. We are using a 20Mhz oscillator frequency and within the application notes of the Microchip website we found information about the minimum acquisition time we must wait for the conversion to be successful. At first, we were not allowing the A/D conversion enough time to accurately hold the value of the sample. This is due to an internal capacitor in the A/D module, which has to charge up before the sample is read. If you do not allow enough acquisition time, the capacitor will not fully charge and therefore give very erratic values. The result of a sine wave input would be a very choppy sine wave that only had a few common values it could sample at. After allowing the correct acquisition time, which is selected in software using the ADCS1:ADCS0 bits of the ADCON0 register.
Later, in our first full prototype of the system we found some unexpected noise. We tied the input of the A/D directly to ground. We used a single ground for the entire system. Each power supply was grounded to each other at only one point to eliminate any ground loops. The noise is shown below.
The noise peaks up
to almost 50 mV. The oscilloscope shows very quick high frequency peaks. During
the middle of the above graph we disconnected the motor from the circuit. The
noise did not improve, ruling out that. Further analysis we could do is to
remove the PWM from our program because that is our next suspicion. Working
with the noise the way it is, we added a RC circuit that filters out
frequencies above 10Hz. A resistor value of 10kW and a capacitor of 1mF
does this. The transfer function is shown below during a simulation of the
filter.

This improved the noise quite a bit, however we are still searching for the cause of such noise. This 50mV of noise represents about 50RPM of signal (approx).
The A/D conversion is triggered by an overflow on Timer 0. Timer 0 is a 8 bit counter and the clock cycle after 0xFF the overflow bit, T0IF will be set high. For T0IF to be set the T0IE flag must be high during initialization of the program. The main loop checks for this overflow bit to be set and if it is it triggers the conversion. Timer 0 increments every instruction cycle, which is the crystal oscillator frequency, divided by four. The prescaler further divides the signal down by a selectable divisor. To gain full accuracy we have to initialize the actual TMR0 register to some value. This register holds the count of the timer. The table below shows the bit value of OPTION_REG <2:0> and the appropriate prescaler it sets, as well as the frequency the timer will overflow.
|
Bit Value |
TMR0 Rate |
Timer Frequency |
|
000 |
1:2 |
9.8 kHz |
|
001 |
1:4 |
4.88 kHz |
|
010 |
1:8 |
2.44 kHz |
|
011 |
1:16 |
1.22 kHz |
|
100 |
1:32 |
610 Hz |
|
101 |
1:64 |
305.2 Hz |
|
110 |
1:128 |
152.6 Hz |
|
111 |
1:256 |
76.3 Hz |
Figure
1: Timer Frequencies
We are using the slowest frequency the Timer can provide at a clock frequency of 20Mhz. This provides us with 76 samples per second or one sample per 13.1mS.
PWM Output
Chapter 8.0 of the PIC16F877 goes into detail about using the PWM output. It shows the PWM module makes use of Timer 2. The PWM module is a 10-bit module and can accept values for 00h to 3FFF (hex). This is convenient since it is the same bit-rate as the A/D input. This allows us to keep full accuracy from the input to the output.
We wanted a PWM output of roughly 5kHz. We did not want to go to fast as our output driver circuitry would not be able to switch on and off fast enough and we did not want a frequency to slow. The datasheet describes the formula to set the frequency as:
(Fosc/4) / Prescaler / PR2 Register = PWM Frequency
Using a 20Mhz crystal oscillator as described in previous documents, a prescaler of 4 and a PR2 value of FF (hex) we obtain a PWM frequency of 4.88kHz. The duty cycle of the PWM is set by writing to the registers CCPR1L and CCP1CON<5:4>. CCPR1L is the 8 most significant bits while CCP1CON is the two least significant bits. A value of 00 (hex) will give an output of 0volts on the output of the PWM module pin, which is pin 17 of the 16F877.
This output is driven by two internal MOSFETs. The output block diagram of this pin is shown below. This is taken from page 33 of the 16F877 datasheet. The output is driven by two MOSFETS. While one turns on, the other turns off, effectively tying the output directly to either Vcc or Gnd (Vss). The electrical characteristics of this output states it can sink or source up to 25mA. This stage will be driving a driver, which will drive the motor. This is very important the input of the driver does NOT pull more than 25mA from this output. If it does we risk burning out this output.
Figure 2 Output Diagram of PWM pin

7. MOTOR DRIVER
The motor will be driven by an N-Channel enhancement mode MOSFET. The PWM signal will operate at a frequency of 4.88kHz. The driver cannot pull more than 25mA from the output of the processor. This is the maximum source or sink current from the processor. A simple model of the two FETs in the processor along with our MOSFET driving the motor is shown below in Figure 3.
Figure 3 PWM Output Diagram

R1 and Q3 are components that we will add. Q1 and Q2 are internal to the PIC processor. We have selected Q3 to be a RFP2N10L N-Channel MOSFET. It has an RGS of 1.050W. A VDS of 100V and can handle up to 2 Amps from the drain to source. It also states it is optimized for 5V TTL gates. The switching times and propagation delays are also very low. From Figure 3 above we can see the need for R1. As the PWM signal goes high (Q1 closed, Q2 open) Q3’s gate will charge the internal capacitor on the gate to 5V turning the MOSFET on, driving the motor for the length of the duty cycle of the PWM signal. As the PWM switches to low (Q1 closed, Q2 open) the capacitor is still charged to the previous value of +5V. The capacitor will try to drain through Q2 which will surely be over it’s current rating of 25mA. In order to slow this current rush down we simply put a resistor in series with the gate. We calculated the resistance to 220W by allowing the maximum allowable current to flow Q2 of 25mA. However we didn’t want to drive the FET to it’s peak value so we instead picked 20mA.
R = V / I R = 5 / 20mA R = 250W
It is also important to use a diode to stop the back EMF current from rushing through the MOSFET, however most MOSFETs include one inside the package.
POWER SUPPLY
We will be using a 12V power supply that will be capable of delivering 2 Amps. Our MOSFET is rated for 2 Amps so therefore that is the maximum current we can supply to the motor. The rest of the circuitry requires insignificant current compared to the motor and should not be factored in. Our PIC processor requires a 5-volt DC supply to its VSS pins. Therefore we will be using a LM7805 voltage regulator to supply the 5 volts. The power supply circuit is shown below in Figure 6.
Figure 8 Power Supply Schematic

The voltage regulator is rated for 1 Amp and we should not come near this maximum specification. The main power draw will be from the PIC processor. The maximum power the PIC can draw (with all output pins loaded to the max) is 250mA. In our case the processor’s main load will only be a MOSFET, which will be drawing slightly over 20mA. The calculation for this was shown before in the PWM output stage design section. Therefore we should not need any kind of heat sink on this.
The 1000uF capacitor is there to smooth out any AC ripple the power supply may have. We are not sure of the quality of the power supply we will be using so we added it in there for safety. The two capacitors after the regulator are there to go across the two ICs that will be used on the board. These are called decoupling capacitors and help reduce digital noise on the power lines. The physical placement of these capacitors is important, as they should be as close to the actual IC as possible.
USER SPEED SELECTION
It has been decided previously that the user will be controlling the set speed of the motor through the use of two momentary push buttons. One will be designated for speed up and the other designated for slow down. The set speed will be displayed on the LCD display for a short time before switching back to the current speed of the motor. The speed will be incremented in steps of 10. Once again the program will check for a speed change every eight times it samples.
The input will be set high through the use of pull up resistor. The switch will be connected from the resistor to ground as shown below.
Figure 9 Pull Up Resistor on Switch

When the switch is open the output terminal will be tied high. As the switch closes the output terminal will be tied directly to ground. Our PIC processor will be tied to this output. The up button will be used on PORTA bit 6. The down button will be used on PORTA bit 7. On the 16F877 these pins dual as PORTE as well. For our purposes we will refer to them as PORTA. We initially thought we would need a debouncing circuit on each switch in which we were going to use a hardware approach. However, later in the design stage we changed this to a hardware approach, as this would simplify our software code. We also did not want the added time in software, which would slow down our sampling frequency. Finally we actually tested the switches when they were shipped to us, and found that they switched in under 100uS which was plenty fine for our application. We could not false trigger with this switch, as we would be checking them about every 600 mS.
LCD INTERFACING
The LCD chosen was a Lumex 16x1 Dot Matrix LCD screen with an onboard S6A0069 40 Segment Controller. This uses an eight bit parallel interface. Along with the eight data lines, three extra lines RS, R/W and E lines are needed.
The display does not come with a backlight. The display’s contrast can be adjusted by controlling the voltage level from 0V to 5V on the Vo line. The display requires a +5V on the VDD line and Gnd on the VSS line. The LM7805 used for the PIC processor will also supply the need +5V.
The LCD can be selected to operate in 8-bit bus mode or 4-bit bus mode. We will use the 4-bit mode to cut down on the amount of wires. When the 4-bit bus mode is selected it will require 4-bit data to be sent two times. This does take the LCD twice as long to receive the information, and slows down our processing speed, which we want as fast as possible in order of using the highest possible sampling rate. However most of the delay in writing to an LCD screen is the time it takes for the LCD to actually process the data, not sending the data. The R/W line is low for when the MPU is to be reading the data bus and high when writing to the data bus. The E (enable) line pulses high while data is being written to the data bus. The 7th bit of the data line also serves as the Busy Flag of the LCD. When the MPU reads the data bus it will check to make sure the LCD has processed the data and the busy line clears before writing new information. We could simply tie the write line and not care to check, however this approach is more reliable. This way we do not have to deal with individual timing delays of each command, instead the LCD controller will simply tell the MPU when it is ready for the next command. One small problem worth noting is the program may hang if the LCD is not connected to the processor.
Next we must initialize the display. In initializing the display we must tell the controller how large the display is. 16 character displays are often set up in two sets of 8 characters segments. Therefore you must initialize the segment to two lines and to write to the later half of the characters, you must write to the second line. We could not find this information on the supplied data sheets. The Lumex data sheets were not very helpful in the information it provided. In fact we had to contact the company simply to find out what kind of controller they were using on board. Despite of this, we simply tested the display and found out we had to initialize it as a two-line display. To initialize it we have to send a “Function Set” command. Looking up the individual bit modes on the Samsung data sheet we can see we have to send it a 00001011. This sets the display for two lines, 4-bit, and 5x8 dots. The RS line sets whether the data on the data lines are to be read as an instruction or actual data to be displayed. We do not plan to update the LCD at an extremely fast rate to save execution time. We are pushing for the fastest sample time as possible; therefore it is extremely important to minimize the execution time of all other functions of the processor.
We are using pre-built drivers specifically designed for the PIC processors to interface to our LCD screen. The Samsung controller is compatible with the very standard Hitachi chipset and we are not the first people to be interfacing to this kind of LCD. In fact, it is so common people have written pre-compiled drivers for doing exactly what we are doing. Luckily it is built-in to the compiler we have chosen for the project.
We are interested in displaying two four-digit numbers on the LCD screen. One being the user-selected set speed and two, being the current RPM of the motor. We are not interested in displaying the current speed of the motor extremely quickly as the user simply wants to see an average of the current speed. The user will not be actively monitoring the screen; instead they will reference the screen once in a while. Because of this we do not see any reason to update the LCD screen more than once every ½ second. The first half of the LCD (characters 1-8) will be designated for the set-speed and the second half (characters 9-16) will be designated for the current speed of the motor.
RS-232
The RS-232 serial port is simply for debugging purposes only, and should only be included on demo prototype boards. In software we are outputting the values of the feedback input from the motor and the values of the output of the PWM. This is useful for demonstration, as well as tuning. Once the program is running on the microprocessor it is hard to see the actual values of what the system is doing. The speeds will be displayed on the LCD however with the serial port connected we can log it on a PC and graph it. The RS-232 interface uses a +/-15V signal instead of a +5V TTL signal. To convert the two we use a MAX232 IC. Therefore the output pin of the PIC (RC6) goes to one of the input drivers of the MAX232. This is defined as the RX line. The PC computer is considered the host while the processor is considered the host. From the output of the MAX232 we send the data straight out to a DB-9 female connector ready to interface to any standard serial port on a PC. You can view the values in Hyper-terminal (standard with any windows computer). With this program you can also log this to a file and open it up on Excel and graph it. Therefore it is possible to see the actual system performance graphed out. All graphs included in this documents of our results were done in this fashion. In the schematic we also include the TX line. This is the transmit line from the computer and receiving on the processor. While we currently do not have any use for this, it is simple enough to include in the need of such a situation.
MOTOR
MODEL
To accurately design the control system we need an accurate model that we can simulate on the computer and implement the proposed control system design. The design is not completely calculated using formulas as many designs are. Instead in this application, we have to tune the system by simple trial and errors. By doing this in a model on the computer we can know what kind of variables we will be dealing with. It is a much different situation to program a multiplication of 2 as opposed to multiplying by 0.042. Therefore, we wanted to see what kind of values we would expect to be using. Of course, trial and error optimizations were expected for best results.
We will introduce a step function to the reference set point, r(t). In other words we will set the reference at 0 RPM. Suddenly we will turn this on input on. If the motor was ideal it was follow the input exactly. However the motor is not ideal and has its own transfer function.

Figure 4: Motor Model
Laplace Transform of DC Motor Equations
Three general Equation for DC motors are shown below. These are standard and can be found in any motor book.
(Eq.
1)
(Eq. 2)
(Eq. 3)
Setting Equation 2 and Equation 3 equal to each other.
(Eq. 4)
Taking the Laplace transform of Equation 1 and Equation 4 we obtain the two equations in terms of s.
(Eq.
5)
(Eq.
6)
Solving for I in each equation and setting them equal to each other gives us
![]()
![]()
Solving for q(s) / V and then multiplying the (s) out to cancel out terms in the numerator we get
![]()
Where
w(s) – angular rotation (rad/sec)
Vg(s) – input voltage
Kt – motor torque constant (Nm/A)
Ke
– back emf constant (V/(rad/sec))
L –
inductance
R –
resistance
b – viscous friction constant
Next we started to determine the values for each constant. Much work went into this during the period we were waiting for the parts. This was after the majority of the design work was completed, and before and actual testing would occur as we couldn’t do much without parts. This was almost two weeks for us because the wrong parts were shipped to us. Therefore modeling our system seemed to fit in well at this point.
The easiest variable to obtain was the coil’s resistance. The resistance of the armature’s coils is about 16W. This was measured with multiple ohmmeters on board multimeters. The test was done with the motor cold, as well as running the motor at full speed for a couple of minutes. Each coil is slightly different so spinning the armature to a different position allows us to measure different coils. The resistance takes a while to steady out due to the inductance of the motor. The inductance of the motor is 4.5mH measured on an inductance meter. Running the motor for a long period of time, did not affect this reading. Kt, the motor torque constant was calculated by our known measurements. We knew if we put 12 volts into the motor we should expect 4500 RPM. By this, we calculated the value of Kt to be 0.025. J, the moment of inertia was also calculated with our known measurements. We knew it took 300mS to speed up to 4500 volts after applying a step function of 12 volts. Therefore we were able to obtain a moment of inertia based upon this. Our final values were:
K=0.025 Calculated Electromotive Force Constant (Nm per amp)
R=16 Measured Electric Resistance
L=0.0045 Measured Electric Inductance
J=0.000002 Calculated Moment of Inertia
b=0 Assumed Damping Ratio of the Mechanical System
PROPORTIONAL
INTEGRAL (PI) CONTROLLER MODEL
In order to compensate for the motor we will add our controller Gc(s) in. The general form of our control system looks likes:

Figure
5: Control System Overview
For our control system we will be implementing at first what is known as a P controller. This takes the error between the set point and the feedback and amplifies or attenuates it according to the gain value. This is called a proportional controller because the constant KP scales the error making proportionality between the set point and the error obtained from the feedback path. A higher KP value will make the system weigh the error more which most likely speeds up the response time, however will most likely overshoot the set point. A very low KP value will make the error insignificant and the output will remain at a constant speed independent of what value the feedback yields. This controller will be implemented in our microprocessor therefore must be shown in discrete time. Therefore we need to convert the continuous equation to the discrete version. In continuous time this can be described by the equation
![]()
which is implemented in a general block diagram within our system below

Figure
6: PI Controller
A common problem with P controllers and DC motors is they will steady out to a value however never actually reach the set point. If the set point was selected to be 500 RPM and the actual motor speed was 550 RPM the error would be 50 RPM. The output of the controller would then be 450 RPM however the motor may not respond to this slight adjustment and stay at the wrong speed even though the controller is outputting the correct speed. In order to break from this “sticky state” the motor must be disturbed in order for it to reach a new steady state, which hopefully will be closer to the set point than last time but nothing guarantees this. This is known as steady state error in control systems. In order to compensate for this steady state error we can add an integrator in the system diagram. This steady state error will accumulate over time in the integrator and eventually add up enough to break from this sticky state.
Below is a simulation of this condition in discrete time with a sampling frequency of 40 Hz. Continuous time signal analysis was done in Matlab and discrete time signal analysis was done in Simulink. The importance of the sampling frequency will be explained later in this document in the section title Sampling Frequency. The voltage put into this motor under simulation was 6 volts, which should produce an RPM of 2500 RPM. Note how the motor will never achieve an RPM higher than about 1650 RPM. This is what is known as steady state error.
Steady
State Error of P Controller Closed Loop in Discrete Time (Fs=40Hz)
Kp=4
Ki=0

The initial spike is also important to note. This is the gain of the controller. A high gain will make this rise time very quick, however often with a large overshoot. A low gain will lengthen the rise time however minimize overshoot. An extremely large gain will also throw the system into an unstable oscillation state.
We can further expand upon the theory of the proportional control by adding another term in which the error is passed through an integrator.

Taking the Laplace transform of the PI we obtain
![]()
The Proportional Integral controller is shown in block
diagrams below.
Figure 7: PI
Controller Block Diagram

The proportional part acts as a simple gain of error. The larger the gain the
more weight the error affects the output c(t). The less gain Kp has
the smaller it will affect the output c(t). The higher the gain of the
proportional controller, the higher the steady state error will be. To reduce
this we add in the Integral control. The integral charges up to reduce steady
state error.

Below is a simulation of the model with some integral action added to the same
proportional gain as shown above. You can see the integral charging up to
eventually bring the system up to its desired set speed of 2500 RPM.
Proportional-Integral Controller
Closed Loop in Discrete Time (Fs=40Hz)
Kp=4 Ki=1
To high of a Ki value will also cause the integral to windup to quickly which is defined in the next section. The result of to high of a Ki value is also oscillations. In most applications we want Kp and Ki to be as high as possible however as far away from an unstable oscillatory system. This is what would be called as a balanced system. An unbalanced system is shown below where Kp is too high.
Unstable Proportional-Integral
Controller in Discrete Time (Fs=40Hz)
Kp=4.8 Ki=4

Next we show an optimally tuned system for our motor. The parameters can be calculated through complex mathematical formulas however this requires a perfect model of the system and is often obtained through putting the system through spectrum analyzers to graph an FFT of the system as well as the phase. For our system we will simply use trial and error techniques to find the best-tuned system for the particular motor as described in the model. The parameters that we found are Kp=4 and Ki=6. The step function of the closed loop is shown below. Once again all these simulations are done in discrete time.
Best
Tuned Proportional-Integral Controller in Discrete Time (Fs=40Hz)
Kp=4
Ki=6

To implement this controller we put the continuous time equation into discrete time and obtain the difference equation.
![]()
This is the discrete equation we will be programming into the microprocessor. c(nT) is the current sample where c(nT-x) is x samples behind the current sample.
PI CONTROL ALGORITHM
To implement the discrete time difference equation
![]()
We took the current velocity and subtracted the set speed from it. These were each 10 bits and therefore occupied a 16-bit register. This gave us our error, or e(nT) as shown above. To produce the proportional part we had to multiply by Kp. We limited this to a single digit number with a decimal point of one digit. To do the Ki part we had to create an integral in software. We could either program the above formula directly, or just store the previous value of errors. It is essentially the same thing, just shown in a different way. We created a 16 bit variable that held the Ki error part. This had to be limited to some max and min value so the register would not roll over. A common problem is integral wind up. Say for example the motor was jammed for a long period of time. The integral term would wind up and become a very large value. Therefore we had to limit this value at some value. We sacrificed the 16th bit in the variable as a overflow bit. If the register went below 0 the value would be a very large binary number. Therefore we just checked for this. For the max limit we checked for this 16th bit as well as some additional bits to be set.
The final part of the algorithm is to add the Kp and Ki errors together. These are both 16 bit values, so a 16 bit addition would have to take place. This would then be the direct value that would be outputted to the PIC. This value then had to also go through a max and min limit. It would not make sense to put a value of 2000 into a 10 bit PWM register. Therefore any thing over 1023 we treated as 1023, and anything below 0 we treated as zero. We applied the max and min limits in the same way as above with the Ki error limits. The 16th bit would be used as a flag for a min limit and the 11th bit would be used for the max limit. The value after 11,1111,1111 would then be 100,0000,0000 and by checking this 11th bit, we can tell if a max limit should be applied.
SAMPLING TIME
One aspect of design that cannot calculate during the design stage (or at least in practicality) of the project is the exact sampling frequency at which the A/D converter and discrete PI controller will operate. This is extremely important as the need for a fast sampling time is required. If we had a specific tolerance at which the speed must adhere to, including peak errors, steady state time errors, etc we could calculate at what speed the controller must sample at. However, for this particular project we picked our microprocessor on all features with the exception of this. We did not take the speed into account. Instead we simply tried to get the best speed out of it by writing efficient code and other methods in which we will outline. This is simply because the original speed requirements for the project were quite general. It simply stated the speed needed to be within 10% of the set speed. This did not include at any specific amount of time the error should be measured at, nor did it state that it must be within 10% at all times. In fact, the latter requirement would be quite a difficult task in itself.
The Nyquist rate of a digitally sampled signal states that the sampling frequency must be twice as high as the maximum sampled frequency to avoid aliasing. In general the sampling frequency of a discrete servo should be roughly ten times larger than the maximum control signal. Now this takes a little explanation to understand. Our PI controller is a discrete control servo. If we use a sample rate of 50Hz, we can control error signals that change as quick as 5Hz. The errors may not change as quickly as 5Hz continuously, however a step function has high frequencies harmonics up to infinity. We certainly may see step functions, such as the turn on speed of the motor or a sudden change in load, or set speed. This is very important because the higher we can control error signals, the more control of the system we will have in attenuating such sudden error changes.
In this project our sampling rate is not easily calculated. Instead we simply wrote the code as efficiently as possible and time the program execution time. In the very end we were running the program in about 6 mS depending on the error and what appropriate instructions it had to go through. We choose a gap of 8mS to allow each sample algorithm to run. Often, complex interrupt timing issues can be extremely difficult to find, and in our limited time to complete the project, this is the last thing we wanted to debug. 8mS gave us a sampling frequency of 78Hz.
GENERAL PROGRAM ORGANIZATION
Our program will begin by calling an initialization routine in which will set all the appropriate registers to set up Timers, PWM, A/D, etc. After this it will begin to go into the main loop. One way of organizing a time critical application such as this is to set up all the main functions in the main loop. Then while the processor is in the middle of the main loop an interrupt will occur interrupting the main loop and running the algorithm for the control system, therefore processing a sample in our application. This way, the sampling algorithm always has priority. Some common problems that occur in this setup is overflowing the stack in the event a second or third interrupt is called while processing the code in another interrupt. Because of this complex structure we wanted a more simple process. As described in the section on sampling frequency, we can see that the sampling frequency is critical for this application and should be as fast as possible. Therefore it is not wise to display to the LCD every sample. This is a waste of time as the user’s eye can not view the LCD this fast, and actually makes it hard to view changing numbers on the screen. Instead we divided the main loop into 8 sections in which one of the eight sections runs each sample. Therefore, the set speed on our LCD is updated once, and then the second time through the current RPM is updated. On another loop through the buttons will be checked for a change in speed. By cutting the workload into eight different sections, this allows us to speed up the sampling time as the full main loop is significantly reduced.
The other requirement we had was a constant sampling frequency. We could not just run this loop around in a circle and have it sample at different intervals in time. This would cause for erratic behavior in our control system. Therefore we set up the Timer 0 to trigger at 76 Hz and called the algorithm with the Timer.
Once an A/D conversation is complete an interrupt (set by the ADIF flag) will be called. We will be using a quick interrupt technique in which sets another temporary flag in which we check for in the main loop. After exiting the interrupt function the main loop will check for this temporary flag and will call the PI routine, which calculates the controlled output as described above in PI Control. The PWM routine will then be called which will output this control signal to the PWM module. This must all occur before another interrupt is called, therefore reinstating the importance of timing. The program loop will generally be set up like this:
Main()
Call Initialize Function
Loop
If Timer 0 Overflow Then
Call A/D Conversion
End if
If A/D Conversion Interrupt
Call PID Function
Call PWM Function
End if
Case x
1. Update half of LCD
2. Update half LCD
3. RS-232
4. RS-232
5. Check speed change
6. Check stall condition
End Case
End Loop
NON-LINEAR
AFFECTS
INTEGRAL WINDUP
A side effect of our integral controller is what is known as integral windup. It is a common side affect of all motors due to their physical limitations. The integral part of our controller is an unstable mode. This does not cause any difficulties when the loop is closed, however a break occurs in the feedback loop when the motor is saturated. Motor saturation is due to its physical limitations of not being able to accept voltages up to infinity. In other words, if the motor is slowed down to the point where the motor is driven to its maximum power and can not drive the motor any faster, the integral error term will start to increase very rapidly. Therefore when the motor desaturates the integral will start to wind-down. The effect of this is a motor that may be driven to its saturation value after an integral windup even though there is no load on the motor. This is a nonlinear aspect of our PI controller and is also bad for the motor. Once again, this only occurs when the motor is driven to its maximum value and does not have any more headroom to operate within.
STALL CONDITION
The stall condition will be called by checking the speed. If the speed is too low the PWM module will be forced to zero no matter what the PI control system is trying to send it. This is described in the basic flow chart as an on/off switch, however it will be in the software. The speed is checked every interrupt cycle. If the speed is under 300 RPM then the stall condition flag goes high. This then jumps to an external loop that outputs “stalled” on the LCD screen as well as a wait function that loops around simply waiting for the reset button to be depressed.
OVERLOAD CONDITION
An added feature was added to our product at a very late stage of design. An overload condition can exist when the controller’s output to the motor is saturated at the motor/driver’s maximum power and does not have any more headroom to operate within. This creates a non-linearity in the control system and makes for erratic results. We have provided a LED on the board to let the user know of such a condition. This is not a healthy condition for the motor to operate within therefore we have provided a signal to let the user know of the condition. However, this system may peak into this condition for short amount of times. We do not desire a full stall condition on this condition. If an overload condition occurs often, the user should decrease the amount of load on the bit.
FINAL RESULTS
We built a full prototype our proposed design on a breadboard. The exact schematic shown in Appendix B was built and tested. The end result was a fully functional project that acted almost identical to our simulation, models and designs. One aspect that was however different was our actual control system variables. This is most likely due to an inaccuracy in our model. More specifically it is because we omitted the mechanical dampening of the motor, which is a common practice in modeling simple motors.
By having a good understanding of the control system and how it operates we will have a better understanding of our results. The results of our system were once again plotted through an RS-232 serial interface to our device. While our model did not prove to be exactly accurate, it helped us understand the basics of the system and to get a feel of what values we would be looking at. All plots within the next few sections describing our results have been set to a RPM of 2500 RPM unless otherwise stated.
In our models we used fairly large values of gains for the integral action. From our prototype we found we needed much smaller gains, in fact they were all attenuations. The reason behind this is due to two different representations of the PI controller. The representation we have been using is

Upon more research into this error we found other books using the following representation

The only difference is the Ki term is the reciprocal of the first representation. This turns out to be a common misleading problem between control or process engineers who commonly use the first representation. Electrical engineers commonly use the second representation, as it is more direct to implement with voltage. While we do not fully understand the reasons behind this, we have found there is a reasonable explanation. Therefore this paper will maintain the same confusion that holds between control and electrical engineers. From this point forward, we will still use the first representation, as it seems to be more consistent with our models. In any case, the reciprocal can easily be found.
First we will look at a controller that has a gain of 1.5 and an integral gain of 1/14. This is shown below.

As you can see from the graph there is an oscillation that dampens out over time. This, however, takes quite a while and is to long for our application. The user does not want to wait four seconds for the drill to stable out to the desired speed. Furthermore, whenever an external load affects the system, the speed will oscillate just like shown above. From our extensive simulations and study of control systems, we learned that increasing the gain, Kp, of the system, would increase this response time.
In the next plot we increased the gain to a value of 10. The model predicted a system with this gain would be oscillating. This is exactly what happens in our system. The following plot shows this.

Without going through over 100 plots we logged we found our optimized values for the best-tuned system through trial and error. Unfortunately this process was quite time consuming, as we had to keep reprogramming the processor with each parameter change. The values we determined to be the optimized parameters are Kp=5 and Ki=1/10. The following shows a sample with this tuned system.

During the first ½ second you can see the motor attempt to go from off to a speed of 2500 RPM. The motor overshoots 2500 RPM by about 1000 RPM and then quickly comes down to steady out. This is our proportional gain at work. The higher we make this gain, as shown in the simulations, the faster the motor comes up to speed, however the overshoot increases. Next, you can see a few oscillations dampening out up to about one second. If you closely look at these oscillations you can see the oscillations shifting up towards 2500 RPM. This is due to the integral part of the controller.
LOADING WITHIN OPERATING RANGE
Next we analyzed the system with different loads applied to the motor’s armature. We simply used our finger to slow down the armature modeling either a steady friction or a sudden torque. In theory as well as our simulations, a steady friction should be corrected through the integral action of the controller. Sudden torques are controlled more through the gain of the controller. In this next example, we applied what we thought would model a constant friction applied to the motor much like a constant friction from a material a drill bit was drilling through. These tests were all done within the controller and motor’s operating range. In other words we made sure that for the following tests an overload condition did not occur. Overload conditions are described in detail in the section titled “Overload Condition” of this document.

Constant loads
such as friction work very well with our system, which is primarily what the
controller was designed for, as these are the most evident loads on a drill
press. From the graph above there is not much error in speed despite different
loads forced on the armature of the motor. The peak values shown in this graph
are what is used to obtain the specification “Maximum Speed Error (no overload)”.
The average value shown in this graph is what is used to obtain the
specification “Typical Speed Error (no overload)”. The specifications are shown
in the appendix A.
We also loaded the motor by grabbing the armature quickly, loosely modeling sudden torque applied to the motor. This can happen if the bit is to catch on a material for a second, but then cuts through it, and continue to drill. The speed plot below shows such a response.

The gain of the
controller is mostly what controls these sudden spikes in speed. The maximum
error is +/- 10% and the average error is +/-5. These values are listed in the
specifications in Appendix B as the typical and maximum torque loads.
EFFECTS OF OVERLOAD
The effects of an overload are shown below. When the motor is saturated to its full value an overload exists. This creates a non-linearity in the control system, thus breaking the loop. Below is a load that is too strong for the motor and therefore creates an overload, but not strong enough to trigger the stall condition. During this overload the controller can no longer give any more power to the motor and therefore cannot control the motor any more.

During this overloaded condition, integral windup occurs. This is described in detail in the section titled “Integral Windup” in this document. Once the load is removed or held back to a linear region of the controller, the integral will “wind down”. This is the error term that has been accumulated in the integral and has to empty out.
TESTING STALL CONDITION
If a heavy enough load is placed on the motor that the motor can no longer spin the armature or drill bit a stall condition takes place. This effectively turns off the motor and waits for the user to reset the system. When a stall condition is present, the program does not operate the main code any more therefore not outputting our data to the RS-232 port. In the following plot of the stall condition, our graph stops logging any further values after a stall due to the way the program is set up. More information on this is available in the section titled “Stall Condition”. Therefore, we cannot show the motor completely turned off in the graph, however by physical evaluation of the motor, we can confirm the motor has been shut off.

MAXIMUM/MINIMUM SPEEDS
Below, the maximum and minimum speeds of the controller are plotted. This graph is from the minimum value of speeds the system allows you to select to the maximum value. This shows the full range of speeds the system allows you to make.

REFERENCES
![]()
1.
Kamen, E.W. Industrial Controls and Manufacturing. Academic Press. San
Diego, CA. 1999.
2.
Levine, William S. Control System Fundamentals. CRC Press LLC. NY, NY.
2002.
3.
Dote, Yasuhiko. Servo Motor and Motion Control using Digital Signal
Processors. Texas Instruments, Prentice Hall, Inc. Englewood
Cliffs, NJ. 1990.
4.
Messner, Bill and Tilbury, Dawn. Control Tutorials for Matlab. http://www.engin.umich.edu/group/ctm/. University of Michigan,
1997.
5. Basic
DC Motor Speed Control With The Infineon C167 Family http://www.hitex.co.uk/c166/PID167.html
6. Procedure for Identifying
Permanent Magnet DC Motors http://mechatronics.me.vt.edu/book/Section3/motormodelling.html
7. PID
Controllers Tutorial.
http://www.che.utexas.edu/~control/sim/pid.htm
8. Tutorial
for PID - Controlled Systems.
http://www.shu.ac.uk/schools/eng/teaching/rw/pidtutorial.htm
9. More PID Loops Tuned http://bestune.50megs.com/more.htm
10. Professor Jonathon Hill. Introduction to Simulink. http://www.ece.wpi.edu/courses/es3011/sim/simulink.html. 2001