Electric motor
This chapter contains projects that use an electric motor. The specific problems that you will encounter
when using electric motors, such as different supply voltage, high power requirements, and speed control,
are all discussed.
Project Description
Electric motor control Basic control of a small 9 V electric motor.
Pulse Width Modulation Control the speed of a small 9 V motor.
Constant motor speed through feedback Maintain an electric motor at a constant
speed, even when the load on the motor
varies.
Tachometer Create a tachometer using the PIC's
TIMER I interrupt.
7.1 Electric motor control
The purpose of this project is to demonstrate basic control of a small 9 V electric motor from a PIC.
Technical background
The motor used in this project is the 7142766 by the Lego Company, but in principle you could use any
small electric motor. This particular motor operates at 9 V and consumes too much power to connect it
directly to a PJCTM67 One solution is to use the TC4427A MOSFET driver IC from Microchip."
Technical data: max. 360 rpm, 3.5mA power consumption without load, 360rnA stalled power
6(,
consumption and 6Ncm stalled torque, according to measurements made by Philippe (Philo)
Hurbain: http://www.philohome.com.
67 The PTCHI can deliver 25mA per pin, with a maximum of 200mA per port .
• , Download the datasheet TC4426A-27 A-28A from http: //www.microchip.com.
120
7.1 Electric motor control
It has the following specifications:
Peak output current: 1.5 A
Voltage: 4.5 - 18 V
Delay: 30 ns
Reverse current: max. 500mA
This chip is a MOSFET driver, but the specs are more than enough for our motor so we don't even need the
MOSFETs themselves. The high allowable reverse current means we don't need diodes to protect the chip.
TC4427A
Figure 59. Pin layout of the TC4427 A.
From the pin layout you can see that pin 2 (IN A) connects to pin 7 (OUT A). Since pin 2 is connected to
the PICTM it will switch between 0 V and 5 V. The voltage at pin 7 depends on the power supply voltage
of the TC4427 (Vdd, pin 6). The maximum is 18 V, so once pin 2 has been made high pin 7 will be at 18V.
The same applies to pins 4 and 5. Pin 3 (GND) is connected to the ground (0 V) of the power supply. Note
that when you run the TC4427 on a voltage different than your microcontroller the ground leads of both
power supplies must be connected. Pins I and 8 are not in use (NC ~ not connected). So at least the
following pins need to be connected:
Pin Name Description
3 GND Connect to the ground (0 V) of the power supply.
Note that when you run the TC4427 on a different
voltage than your microcontroller the ground leads of
both power supplies must be connected to each other.
6 VDD Motor power supply (4.5 to 18 V)
121
7 Electric motor
The software
The control of a motor has basically three functions: stop, forward and reverse. We will use a variable
resistor to do the controlling:
Resistance LED 1 LED2 Action
< 50 0 0 stop
50 - 150 1 0 forward
150 – 200 0 1 reverse
> 200 1 1 stop
When both contacts of the motor driver chip carry the same signal the motor is stopped and braked. This
means rotating it manually takes effort. Coast (stopped without braking) would be a fourth motor option,
but is not possible with this setup.
After the definition of the pins and variables the program starts by measuring the resistance:
-- take a sample of pin a0 (analog 0)
resist = ADC_read_low_res(0)
Nested if ... then ... else statements determine which action is to be taken based on the resistance
measured:
if resist < SO then
LEDO= low
LEDI = low
else if
resist> 200 then
LEOO = high
LEOI = high
else if
resist < 1 SO then
LEDO = high
LED1 = low
else
LEOO= low
LEOI = high
6'1 See Chapter 5 for more information on this subject.
122
end if
end if
end if
7.1 Electric motor control
Since both LEDs are connected to the same pins as the TC4427, switching on the LEDs also switches
on the motor.
Not required, but fun anyway, is to send the data to the PC over an RS232 connection using the
programmer pass-through (see Chapter 6):
-- and send 10 PC
serial_ sw write( resist)
serial sw write(LEDO)
serial sw write(LEDl)
You can use the Visual Basic debugger software from section 6.3; just remember to add the relevant
pins.
Putting it all together yields this program:
-- JAL 2.0.4
include 16F877 bert
-- define the pins
pin_aO_direction ~ input
pin c4 direction ~ output
pin c5 _ direction ~ output
-- general variable
var byte resist
var bit LEDO is pin c4
var bit LEOl is pin_c5
forever loop
--lake a sample o/pin aO (analog 0)
resist ~ ADC_read-'ow_res(O)
if resist < 50 then
LEDO~ low
LEDI ~ low
123
7 Electric motor
else if
resist > 200 then
LEDO = high
LEDI = high
else if
resist < 150 then
LEDO = high
LEDI = low
else
LEDO = low
LEDI = high
end if
endif
end if
-- and send to PC
serial sw write(resist)
serial sw write(LEDO)
serial sw write(LED I)
-- give the computer lime to reaCl
delay I OOms(1)
end loop
The hardware
Since the TC4427A has to drive the 9 V electric motor, it has to be connected to a 9 V power supply.
We will get the 5 V power supply for PIC and the other parts of the project from the same supply,
using a UA 7805 with a 0.1uF stabilizing capacitor.
The motor can be directly connected to the MOSFET driver IC, along with a small 0.1uF noise
reduction capacitor across the motor leads.
'o 70 The Lego motor has an internal PTe to protect it against overheating. So an overheating motor
will run slower.
124
The next figure shows the circuit on the breadboard. The top power rail is 9 volts and the bottom
power rail is 5 volts. Conversion between the rails is handled by the UA7805 on the right hand side.
The long wires on the left side belong to the programmer and are used to send data to the PC.
The power supply wires are soldered to the inside of the Lego battery box to prevent accidental power
reversal when engaging battery power.
125
7 Electric motor
Upon closer inspection you may notice a diode in the ground lead between the 9V and 5V rail. This
turned out to have no useful contribution so it has been left out in later projects. In the schematic, the
diode is not shown and you do not need to use it.
7.2 Pulse Width Modulation control of an electric motor
The purpose of this project is to control the speed of a small 9V electric motor between 0 and 100%.
In order to supply the power and higher voltage a TC4427A MOSFET motor driver chip will be used.
Technical background
The simplest way to control the speed of an electric motor would be to vary the voltage between 0 and
9 volts. Unfortunately this doesn't work. First of all, the motor needs a minimum voltage to get started,
so it will immediately go from off to fast. Secondly, the torque at low speeds is extremely low. The
solution is to keep the voltage constant at 9 volts - which eliminates starting problems - and simply
switch the power on and off. If you do that quickly enough the motor will run very smoothly, even at
low revolutions.
Two different methods can be used:
1. Increase the on-off pulses to make the motor go faster. The length of the pulses remains the same,
but the frequency increases. This is technically the simplest solution, but smooth low-speed operation
is difficult to attain.
2. Keep the number of pulses constant, but vary the duration of the pulse. This is technically more
difficult, but produces much better results.
We will use method 2, which is called Pulse Width Modulation (PWM). The next figure shows how
PWM works. In the top graph the width of the pulses is 10% of the period (the time between the start
of two consecutive pulses). This is called the duty cycle, and is the part of the period where power is
actually delivered.
In the middle graph the duty cycle is 50%. The bottom graph shows 100%. The latter, of course,
means that the power is always on and the motor runs at full speed.
126
7.2 Pulse Width Modulation control of an electric motor
Figure 62. PWM duty cycles.
The PICTM 16F877 is equipped with two Pulse Width Modulation modules, which are connected to
pins c1 and c2. Note that module 1 is connected to pin c2 and module 2 is connected to pin c1. Once
connected, the only thing that needs to be done is to initialize the PWM modules and apply the proper
values to them.
For standard values the 16F877_bert library can be used, since it contains the
pwm_hardware library. However, we may need to use different settings for other projects
(PWM has many uses), so we will set the PWM module manually here as a learning experience.
Since all of the variables we are using are 8 bits (max. value 255) it would be convenient if we could
use this directly in the PWM module. That would mean we get 256 different speeds (stopped is also a
speed), which would appear to be enough.
The PWM module can handle 10·bit speed control, with the two lowest bits being in a different
register (CCP1CON). So if we want to use 8-bit speeds we need to split the speed up and spread it
over two registers with two bits in CCP I CON and the remaining 6 bits in CCPR1L. That would be
rather inconvenient, and the question is how useful would it be?
Let's assume we simply ignore the two lowest bits and just set them to 0. This would mean that any
value less than 4 couldn't be selected. A value of 4 would be a duty cycle of 1.6%. This is such a small
value that it would be no problem to "jump" right from 0% to 1.6% as the first step.
So if we ignore the lowest two bits we can use the 10-bit setting after all. The lowest two bits in
CCP1CON can be set to 0, and the highest 8 bits in CCPR1L will be used for the speed. Looking at
the datasheet, the table shows that the highest frequency at l0-bit resolution is 19.53 kHz.
127
7 Electric motor
Figure 63. PWM frequencies.
This can easily be verified. According to the datasheet the PWM period can be calculated with the
following formula:
(PR2 + 1) * 4 * Tosc * TMR2prescaler
where:
PR2 = FF = 255
Tosc = 1/20 MHz = 50 ns
TMR2prescaler = 1
So the period is 0.0000512, which is a frequency of 19.531 kHz.
This frequency is a bit high for a PWM application, but in this case it works like a charm and the
electric motor (a Lego motor type 71427 71) runs exceptionally smooth. Should your motor not run
smoothly or make a lot of noise it is best to reduce the frequency. This is not a problem, because at 10-
bit resolution 4.88 kHz and 1.22 kHz are also available.
To get our frequency of 19.53 kHz the TIMER2 prescaler must be set to 1 and PR2 must be set to
OxFFh. PR2 is the TIMER2 period register; the timer will count up to this number and then start at 0
again. It can be assigned like this:
PR2 = OxFF
The clock signal is divided by the prescaler and results in a longer period, since it will now take longer
before the preset value is reached. The prescaler is hidden in the T2CON register:
71Technical data: max. 360 rpm, 3.5 rnA power consumption without load, 360 rnA stalled power
consumption and 6 Ncm stalled torque according to measurements made by Philippe (Philo)
Hurbain: http://www.philohome.com.
128
7.2 Pulse Width Modulation control of an electric motor
T2CON: TIMER2 CONTROL REGISTER (ADDRESS 12h)
bit 7 Unimplemented: Read as '0'
bit 6-3 TOUTPS3:TOUTPSO: Timer2 Output Postscale Select bits
0000 = 1:1 Postscale
0001 = 1:2 Postscale
0010 = 1:3 Postscale
1111 = 1:16 Postscale
bit 2 TMR20N: Timer2 On bit
1 = Timer2 is on
o = Timer2 is off
bi11-0 T2CKPS1 :T2CKPSO: Timer2 Clock Prescale Select bits
00 = Prescaler is 1
01 = Prescaler is 4
Ix = Prescaler is 16
Figure 64. T2CON Register.
To set the prescaler to a value of 1 bits 0 and I of T2CON must be set to 0. This is, of course, only
useful if the timer is actually switched on, so bit 2 must be set to 1. The postscaler is not needed, so
these bits will remain 0. The result is:
T2CON = 0b000_0100
The only thing we need to do now is send the signal to pin c2 (CCP1). This pin has many functions, as
can be seen in figure 65. To put it into PWM mode bits 2 and 3 of CCP1CON must be set to 1 (the
other bits are irrelevant).
Since we opted not to use the two lowest bits of resolution we need to set them to 0. Otherwise, we
won't be able to stop the motor (bits 4 and 5 of CCP1CON).
CCP1CON = 0x0F
129
7 Electric motor
rnl 7-6
bit 5-4
bit 3-0
CCP1CON REGISTERlCCP2CON REGISTER (ADDRESS: 17h/1Dh)
u-O u-O RfW-O R/W-O RJW-O RJW-O RfW-O RfW-O
I
CCPxx CCPxY CCPxM3 CCPxM21 CCPxMl CCPxMO I I
bit 7
Unimplemented: Read as '0'
CCPxX:CCPxY: PWM Least Significant bits
Capture mode:
Unused
Compare mode:
Unused
PWM mode:
bit 0
These bits are the two LSbs of the PWM duty cycle The eight MSbs are found in CCPRxL
CCPxM3:CCPxMO: CCPx Mode Select bits
0000'" Capture/Compare/PWM disabled (resets CCPx module)
0100 = Capture mode, every falling edge
0101 = Capture mode, every rising edge
0110 = Capture mode, every 4th rising edge
0111 = Capture mode, every 16th rising edge
1000 = Compare mode. set output on match (CCPxIF bit is set)
100 1 = Compare mode. clear output on match (CCPxIF bit is set)
1010 = Compare mode. generate software interrupt on match (CCPxlF bit is set, CCPx pin is
unaffected)
1011 = Compare mode, trigger special event (CCPxIF bit is set, CCPx pin is unaffected); CCP1
resets TMR1: CCP2 resets TMR1 and starts an AID conversion (if AID module is
enabled)
llxx = PWM mode
Figure 65. CCPICON register.
Putting the settings together we have:
PR2 =0xFF
neON = 0b000_0100
eePI CON = 0x0F
And obviously the pin must be defined as an output.
Pin_c2_direction = output -- actual PWM output pin
Because we use JAL we can accomplish the same thing using simple JAL statements, even though
you do need knowledge of the datasheet in order to know what to enter.
130
7.2 Pulse Width Modulation control of an electric motor
The relevant commands are:
const pwmJrequency = number This sets the PWM frequency. You
can only chose the frequencies listed
in the datasheet and as you have seen
this has consequences for the
available resolution.
canst pwml_dutycycle = numberl
const pwm2 _ dutycycle = number2
PWM_initJrequency (boolean,
boolean)
The software
If you use frequency modulation (FM)
instead ofPWM this is where you set
the desired duty cycle. In later
sections we will see that this is a fun
way to make sounds.
Engage the PWM modules.
Set the duty cycle. When using PWM
this is the variable that controls the
power output (if an electric motor is
used this controls the speed).
We are using a variable resistor to control the speed of the motor. Since we have opted
for 8-bit resolution the duty cycle for the motor can be copied directly from the
measurement of the AID converter. Notice that variable resist needs to be defined as a
byte to hold the 8-bit value:
-- convert analog on 00 to digital
resist = ADC _read Jaw Jes(O)
-- set actual PWM duty cycle
PWM _set_ dutycycle (resist, resist)
The PIcn. cannot deliver enough power to directly drive any kind of motor. Our motor
also needs 9 volts, which the Picn. is unable to provide. For these reasons a TC4427
MOSFET motor driver chip is used, just like in the previous project.
The motor driver chip has two inputs. One will be used for the speed (this is where the
PWM signal will be fed into) and the other is for the rotation direction. Unfortunately, if
you switch direction you also switch speed. If the duty cycle is 20% with the motor
131
7 Electric motor
running forward, then changing the direction to reverse will change the duty cycle to 80%
(this is due to the inner workings of the TC4427, the 16F877 of course doesn't change).
So whenever the direction is reversed the duty cycle also needs to be "reversed". We do
this by simply "reversing" the measured resistance.
-- !f the switch is pressed reverse direction
ifpin_c7 ~~ high then
else
pin c4 ~ high
-- and reverse reading to maintain speed
resist ~ 255 - resist
pin c4 ~ low
end if
Putting this all together yields this program:
132
-- JAL 2.0.4
include 16F877 bert
-- define variables
var byte resist
-- define the pins
pin aO _ direction ~ input
pin _ c7 direction ~ input
-- variable resistor ('peed)
-- forward/reverse switch
-- enable pulse width modulation
PWM_initjrequency (true, true)
pin_c4_direction ~ output
var bit direction I is pin _ c4 ~ true
forever loop
-- convert analog on aO to digital
resist ~ ADC read low res(O) - - -
-- send resistance to PC
serial_sw write(resist)
delaY" I OOms(l)
end loop
The hardware
7.2 Pulse Width Modulation control of an electric motor
-- if the switch is pressed reverse direction
ifpin_c7 = high then
end if
pin_c4 = high
-- and reverse reoding to maintain speed
resist = 255 - resist
else
pin_c4 = low
-- set actual PWM duty cycle
PWM_set_dutycycle (resist, resist)
6
TC4427A
1-----'11---.--1 '
3 0.1 uF
'----1-'
Figure 66. PWM project schematic.
The schematic is identical to the previous project, except that a switch has been added to
reverse the direction of the motor and the B input of the 4427 is now connected to the
CCPI output of the l6F877.
The next figure shows the breadboarded circuit. The top power rail is 9 V and the bottom
power rail is 5 V. Conversion between the rails is handled by the UA 7805 on the right
side. The long wires on the left belong to the programmer and are used to send data to the
PC.
133
7 Electric motor
Even at the lowest setting Gust 1.6% duty cycle) the motor runs and needs a whopping 14
seconds to make one rotation. Impressive! The Lego motor has a built in gearbox with a
ratio of 14: I, so internally the motor makes one revolution per second.
Figure 67. Pulse Width Modu/otion.
When in-circuit programming with the Wisp628 the motor (and everything else) can
remain connected. It may make a strange sound and small movements, but these do not
affect the programming in any way.
134
7.2 Pulse Width Modulation control of an electric motor
An option
If you want you can display the PWM data on a PC. It has no impact of the functionality;
it's just for fun. If you're not interested the commands:
-- send resistance to PC
serial_sw write(resist)
delay-I OOms( 1)
can be removed from the program .
... Be fl Vdn ()<Im ((1]006 _ I ~~
pulse width modulation
16F877
eor-ct to PIC
..... ·",,1
p "'''''''''
"""onPC
r. Coml r ComJ
r Com2 r Can ..
Figure 68. VB program
After powering up the project, start communications by clicking the "start" button. The
term "motor power" really means the value being sent to the PWM module. The
"percentage power" on the dial is the duty cycle that varies between 0 and 100%.
135
7 Electric motor
7.3 Constont motor speed through feedback
The purpose of this project is to maintain an electric motor at a constant speed, even when
the load on the motor changes.
Technical background
The speed of an electric motor is measured. Based on that measurement the power to the
motor is varied using the PWM module. If the motor slows down for some reason (such
as when you pinch the axle between your fingers) the PICTM will detect this and increase
the power until the measured speed matches the desired speed again.
The motor we'll be using is the Lego 7142772
, but any small motor could be used. It may
be convenient to build the motor frame and support out of Lego as well. But first we need
to generate some sort of feedback signal so the PICTM knows the speed of the motor.
We start with a small circle of paper that is black on one half and glued to a Lego wheel.
A black marker works well, but as you can see a black pencil works just fine too.
Figure 69. Pulse wheel.
We'll use a sensor to determine the difference between the black and white halves. By
measuring how long it takes for one color to pass the sensor the speed can be calculated.
The Fairchild QRB 134 infrared photo reflector is used as the sensor. It comes equipped
with a daylight filter to eliminate the influence of stray light as much a possible. It also
has a bui lt-in infrared LED (and the price is quite agreeable). The datasheet is not quite
clear on whether current limiting resistors are built in. The answer is "no" as I found out
when I fried the first one.
72 Technical data: max. 360 rpm, 3.5 rnA power consumption without load, 360 rnA stalled power
consumption and 6 Ncm stalled torque according to measurements made by Philippe (Philo)
Hurbain: http://www.philohome.com.
136
7.3 Constant motor speed through feedback
r--r--.'V
green blue
Figure 70. Connecting the QRB J J 34.
The sensor needs to be mounted at a distance of about 2 to 4 mm (5/64 to 5/32 in.) from
the pulse wheel. Figure 71 shows how that can be done using standard Lego parts. The
sensor is about 2/3 of a Lego brick high; so two angled 113 bricks hold it in place.
Figure 71. Sensor construction.
Now we need to measure how long it takes for the sensor to "see" a color change. The
16F877 is equipped with a timer for purposes such as this: TlMER!73. This timer can be
controlled using TICON, the TIMER I control register. The only thing we need to do is
switch it on
TICON = Ob 0000 0001 - -
This way we also set bit I to zero, which ind icates that the internal clock is used.
73 You may recall that there is also a TIMER2, but it is being used for the PWM module.
137
7 Electric motor
T1CON: TIMER1 CONTROL REGISTER (ADDRESS 10h)
u-O u-O RfW-O RIW-O RJIN-O RIW-O RlW-O RJW-O
IT1CKPS1 IT1CKPSoi T10SCEN I T1SYNC I TMR1CS I TMR10N I
bit 7
bit 7-6 Unimplemented: Read as '0'
bit 5-4 T1CKPS1:T1CKPSO: Timer1 Input Clock Prescale Select bits
11 == 1:8 Prescale value
10'" 1:4 Prescale value
01 == 1:2 Prescale value
00 == 1:1 Prescale value
bit 3 T10SCEN: TImerl OsciUator Enable Control bit
1 ::: Oscillator is enabled
o '" Oscillator is shut-off (the oscillator inverter is turned off to eliminate power drain)
bit 2 T1SYNC: Timerl External Clock Input Synchronization Control bit
When TMR1CS::: 1:
bit 1
<:
bit 0
1 - Do not synchronize external clock input
o = Synchronize external clock input
When TMR1CS - 0:
This bit is ignored. Timerl uses the internal clock when TMR1CS == O.
TMR1CS: Timerl Clock Source Select bit
1 External dOCk from pin RCOIT1 QSQ/T1 CKI (on the rising edge)
o Internal clock (Fosc/4) >
TMR10N: Timer1 On bit
1 = Enables Timer1
o = Stops Timer1
Figure 72. TIMER 1 control register
bit 0
Note that the external oscillator controls this internal clock, with the frequency being that
of the external oscillator divided by four. This is overlooked quite easily, hence the red
circle_
The l6F877 is connected to an external crystal of20 MHz. The clock frequency (Fosc) is
20 MHz, so one "tick" takes 50 ns74
. Since the timer only counts one in every four ticks a
timer tick takes 200 ns. The maximum number of ticks this timer can hold is 256 for the
high byte and 256 for the low byte so in total 256 * 256 ~ 65,535 ticks. At 200 ns per tick
this takes just 0.0131 second. Not enough by a long shot. It's incredible how fast these
microcontrollers are!
Ifwe add an extra byte (the eXtra High byte) the maximum time would increase to 3.35
seconds (256 x 0,013 seconds). Just for fun we will add yet another byte, the eXtra eXtra
High byte resulting in a maximum time of 858 seconds, which is enough for even the
slowest motors'
74 m ~ 10-3
, U ~ 10-', n ~ 10-', P ~ 10-12
, SO I second is 10' ns, or 1.000.000.000 ns.
138
7.3 Constont motor speed through feedback
In JAL it looks like this:
ifTMRIH = 255 then
if counterXH == 255 then
counter XXH = counter XXH + I
end if
counterXH = counterXH + I
while TMRI H == 255 loop end loop
end if
When the high byte of the timer is 255 the pro~ram needs to take action. At the next
increment the high byte will rollover to 0 again." This is a good place to increment the
eXtra High byte (counterXH) by one.
ifTMR I H == 255 then
counterXH = counterXH + I
This will have to be done only once so we will wait until the high byte has indeed rolled
over.
while TMR I H == 255 loop end loop
In fact, the eXtra High byte counts a bit too early; specifically when the high byte of the
timer is 255 instead of when it actually rolls over. You won' t really notice this because
the loop above will correct for it. Unless of course the process is stopped (because the
sensor color changes) right at this very moment. That would cause an error of I tick of
the high byte, which is 0.051 ms. I think we can live with that.
When the eXtra High byte rolls over the eXtra eXtra High byte needs to be increased by
one:
if counterXH == 255 then
counter XXH = counter XXH + I
end if
counter XH = counter XH + I
Now all we need to do is start and stop counting at the right moment, when the sensor
detects a color change on the pulse wheel. We will stop the program until the pin that is
connected to the sensor (inpulpin) drops from high to 10w76
:
75 A byte can hold a maximum value of255. If you add I it will start at zero again, so 255+1 =0.
This is called a rollover.
76 Note that it makes no difference whether the color changed from white to black or black to
white since they both have the same length.
139
7 Electric motor
while inputpin loop end loop
When that happens TIMERI is reset by setting the high and low bytes to zero:
TMRIH = OxOO
TMRIL = OxOO
The counter loop runs as long as the color of the pulse wheel remains the same:
while I inputpin loop
Now that we know how long it took for the motor to make half of a tum we need to add a
feedback mechanism. Here's where we need a reality check. We are talking about a toy
electric motor with a hand drawn pulse wheel. It is completely useless to measure speed
to hundredths of a second. The TIMER I low byte can thus be completely ignored.
Whether the high byte is of use could be a matter of discussion, but in this project we
assume that the eXtra High byte is the lowest meaningful value.
As an example, the setpoint for the speed in this project is 10 for the eXtra High byte.
Which means one color takes (10/256)*3.35 = 0.13 seconds to pass the sensor. So one
complete revolution would take 0.26 seconds, which is equivalent to 231 revolutions per
• 77 minute.
The most essential part of the software - which uses the measured speed to adjust the
power to the motor - has now become quite simple.
If the motor runs too slowly (the counter value is too high) the PWM setting is increased
by five. [fthe motor runs too fast the PWM setting is reduced by five.
ifcounterXH < 10 then
CCPRIL = CCPRI L - 5
end if
if counter XH > 10 then
CCPRI L = CCPRIL + 5
end if
17 In this project the setpoint is a fixed value. You can make the setpoint a variable by connecting a
variable resistor to the PICTM and using the measurement to control the speed. If you divide the
measurement by 10 you will get a nice control range. Please be aware that if you stop the motor
you won'1 get it started again because the program will wait for a pulse which will never come.
The solution is to add a timeout to the waiting loop to limit the maximum waiting time.
140
7.3 Constant motor speed through feedback
The software
It is not necessary (but really quite interesting) to graph the data from the PICTM on a Pc.
Try pinching the motor axle to feel the power increase, and then see the readings on the
PC change accordingly.
The red line in the graph of Figure 73 represents the power sent to the motor. You can see
that I pinched the motor axle at two diffe rent times. The PICTM immediately increased the
power to the motor (the red line went up) until the speed was correct again. When I
released the axle the motor ran too fast so the PICTM corrected for this by reducing motor
power.
The actual motor power is shown on the dial and in numbers below. The contents of all
counters are also shown.
This Visual Basic program is part of the free download package, and includes the source
code.
.. IlcII vdn [)dm (c))OO6 _ ~ ex
16F877
~
,~
~ ,.,
""'" l ,----;<i
""'" H ,..--.,
CwUo:>Oi ~
Cco.ri«~ r--o
PM'W po<I'IIOa
pc
r--r&2
A_", [17l
!.~ ! A~e: I r.::.U .... 1...,1 ,, "'..,.
[r. ~ ~ ~
Co rn 1 { Can 3
r ecn. 2 r Corn ~
Figure 73. Pinching the motor axle.
141
7 Electric motor
In order to display these data we do need to actually send them. To keep them separate on
the PC side they are preceded by a number.
Prefix
2
3
4
5
Data content
TIMER I low byte78
TIMER I high byte
eXtra high byte
eXtra eXtra high byte
PWM module pulse length
In JAL this is handled as follows:
serial_sw write(" I ")
serial_ sw _ write( counterL)
delay_I ms( I 0)
serial_sw write("2")
serial sw write(counterH)
delay I ms( I 0)
serial_ sw write("3")
serial sw write(counterXH)
delay 1 ms( I 0)
serial_sw write("4")
serial sw write( counterXXH)
delay 1 ms( 1 0)
serial_ sw _ write(" 5")
serial_sw write(CCPR I L)
All important parts of the software are now complete and can be put together:
-- JAL 2.0.4
include 16F877 bert
-- define variables
var byte cOllnterL, counterH, cOllnterXH, counterXXH
pin d2 direction = input -- m%rfeedback pulse
711 This is, of course, TMR 1 L. But between the moment it is measured and the moment it is sent to
the PC the counter changes value, and so does TMRI L. So right after the measurement the value is
put into a separate variable (counterL) to preserve it. The same applies to TMR I H.
142
7.3 Constant motor speed through feedback
var bit direction I is pin_c4 = false
pin_c4_direction = output
var bit inputpin is pin_d2
pin_d3_direction = output
var bit yellowled is pin_d3
-- mOlor direction
-- signalfrorn the photo reflector
-- yellow led
.- enable pulse width modulation
PWM_initJrequency (true, true)
CCPRIL= 138 -- set ac/ual PWM duty cycle to 138
TI CON= Ob - 0000- 0001
forever loop
while inputpin loop end loop
TMRIH= OxOO
TMRIL=OxOO
yellowled = high
while! inputpin loop
ifTMRIH == 255 then
if counterXH == 255 then
counterXXH = counterXXH + I
end if
counterXH = counterXH + 1
while TMR I H = 255 loop end loop
end if
end loop
-- counting completed
counterH = TMRI H
counterL = TMRI L
ye llowled = low
-- TIMERI enabled
-- wait for high to low transition
-- initialize TIMERI
-- high pulse turns led on
-- wait for low to high transition
-- meanwhile COllnt overflows
-- adjust the power to the motor if needed
ifcounterXH < 10 then
CCPRIL = CCPRIL - 5
end if
ifcounterXH> 10 then
CCPRIL = CCPR I L + 5
143
7 Electric motor
end if
-- send data to the PC (for information purposes only)
serial_sw write(" 1 ")
serial_ sw write( counterL)
delay I ms( 10)
serial_sw write("2")
serial_sw write(counterH)
delay I ms(l 0)
serial_sw _ write("3")
serial_sw _ write( counter XH)
delay_lms(lO)
serial_sw write("4")
serial_ sw write( counter XXH)
delay_ lms(lO)
serial_sw _ write("5")
serial_sw write(f877 CCPR 1 L)
-- reset all counters
counterL ; 0
counterH; 0
counter XH ; 0
counter XXH ; 0
end loop
The hardware
The circuit looks a lot like the PWM project of section 7.2. The Fairchild QRBI134
infrared photo renector needs to be added of course. If you compare the schematic with
the breadboard photograph you will notice a few small differences. The setup on the
breadboard works perfectly, however in applications where power is scarce and voltage is
lower than anticipated (such as battery applications) the set up in the schematic will
function better (such as in battery powered robots).
The diode in the ground lead between the 5 V and 9 V power rails is removed, and the
resistor between the PICTM and the MOSFET driver chip is relocated to the LED (which
was what they were meant for in the first place). These changes have been incorporated
into the circuit in Figure 74.
The long wires on the left side of the breadboard are from the Wisp628 in-circuit
programmer.
144
7.3 Constant motor speed through feedback
Figure 74. Constant speed with feedback .
Figure 75. Constant speed with feedback.
145