Getting ready
You need to start with the setup you had at the end of the Pulsing with the PIC lab. If you have to start all over, here at the parts you need.
- Breadboard — large or medium
- Microstick
- One LM386 DIP
- One 3904 transistor
- Two 330 Ω resistors (orange–orange–brown)
- One 10 Ω resistor (brown–black–black)
- One 220 µF capacitor
- Two 0.1 µF capacitors (labeled 104 for 10⨯104 pF)
- One LED
Other components will be needed depending on your choices.
A little talk
We need to review Rebecca Bruce’s presentation for EGM 360/CSCI 373 before going any further.
References
- LM386 low voltage audio power amplifier
- 3904 NPN transistor
- PIC24HJ32GP302/304, PIC24HJ64GPX02/X04 and PIC24HJ128GPX02/X04 datasheet
- PIC24H Family Reference Manual
Our objective
We are going to look at these topics today:
- Controlling the world with microprocessors
Getting to the starting point
There are two things you should have accomplished before going on.
First, you should have used both the the 3904 transistor and LM386 amplifier described in the Getting louder section of the Pulsing with the PIC lab.
Second you should have the new pulsing routine
genPulseWave
from the Better digital to
analog lab.
This routine receives three parameters:
pulseHi
, the length of the high pulse in microseconds;
pulseLow
, the length of low high pulse in microseconds;
and duration
, the time in which
the alternating pulses are generated in milliseconds.
It conforms to the following prototype:
void genPulseWave(uint32_t pulseHi, uint32_t pulseLo, uint32_t duration) ;
If you haven’t done both of these two, complete them now.
Experiment 1 — Servos
All those radio controlled cars use servos to turn the wheels. In servo control the width of a high pulse is varied from 1 to 2 milliseconds within a 20 millisecond period to change the rotation of a servo motor. DC motors can spin around, but servo motors just rotate to a position and stay there for a little while.
You should look at the servo section of Rebecca Bruce’s presentation for EGM 360/CSCI 373 to see how servos must be connected to your PIC before you start using them.
We suggest you write a C function
genServo
that implements receives two arguments:
plseHi
, the width of the high pulse in milliseconds,
and duration
to generate the
Servo output. Again, it’s a two to four line function.
Here is a prototype:
void genServo(uint32_t pulseHi, uint32_t duration) ;
Program a servo to move between various position. Start by making the servo move a few degrees at a time. You’ll need to stay in a position for a half second or so to give it time to settle down.
Try to make the servo rotate smoothly.
By the way, serious hobbyists building RC-controlled airplanes prefer the newer digital servos rather than the older analog servos we are using today.
Experiment 2 — Pulse Width Modulation
By keeping the period fixed, but changing the width of the high pulse you can vary the voltage, and often the power, delivered to a device. You have already seen how to do this with an LED.
In previous labs, you used a 3904 transistor to drive your speaker. You can replace the speaker with a small DC motor. If you increase the high pulse width as you decrease the low pulse width, the motor should speed up.
You might also consider replacing the 3904 transistor with a TIP120 transistor. The TIP120 can even turn computer fans on and off. The instructables tutorial on using a TIP120 with an Arduino contains a lot of good information about how to use these devices. The tutorial suggests you use a diode and ceramic capacitor to protect your more sensitive electronic devices. These are available for your use today.
Last year we tried to build some flapping birds in the lab. But the birds seem to have flown away.
We suggest you write a C function
genPWM
that implements receives two arguments:
power
, a number between 0 and 255, where 255 is all power
and 0 is no power, and duration
, the
length of the pulse in milliseconds to generate the
PWM output. It’s a two to four line function.
In our implementation it high pulse last
power*40
microseconds.
Here is a prototype:
void genPWM(uint8_t power, uint32_t duration) ;
Try to make a motor cycle between fast and low speeds with PWM.
Experiment 3 — Music and sine controlled PWM with a touch of PCM
This one is a hard one. Right now our speaker receives a high pulse for half the period and a low pulse for the rest of the period. What if we divided the duration into 16 or 64 or 256 equal sections and the duration of the high and low pulses of each of those sections varied according to the output of a sine function? Would the music sound any better?
You could call sin
from your PIC program but it would be better
generate a table of sine values from either a spreadsheet or C program.
Here is a link to a table of sixteen values generated
using C.
You can also use spreadsheet to look
at a larger range of values.
You would need to add this C array declaration to your program.
I suggest declare it of type uint8_t
.
If you were generating a tone of 131 Hz, you would first figure out
the usual period, 7633 µsec. Then divide that by 16 to get
477 µsec.
Your program will then go through a loop 16 times, for each element of the
array. On the i’th iteration, look
up the i’th element of the array.
Let’s say it is pi.
Now call genPulseWave
for a high pulse of
pi
,
a low pulse
of 16-pi
µsec,
and a duration of
477 µsec.
You can find many examples, such as this one for the Arudino, through Google of people following this technique. Evidently the results aren’t that musical.
There is a Microchip application note of using pulse code modulation to generate speech. Generaing understandable speech is much easier than generating pleasing music.
Some pictures