Driving a piezo speaker with a PIC
Original Assignment
In this project you will use a PWM output of the PIC microcontroller to play tones on a piezo speaker. Document frequencies that play the basic notes in the musical scale and demonstrate a simple song.
Overview
Piezoelectric speakers operate by the converse piezoelectric effect: when a voltage is applied across the terminals, the piezoelectric material in the speaker to deflect in one direction. Applying an alternating voltage will cause the material to vibrate, and create a sound.
In this lab, PWM was used provide the alternating voltage to drive the speaker (Parallax 900-00001). The period of the PWM determines the tone that will be played; the duty cycle changes the volume. The frequency range of the speaker was limited by the timer used by the PIC to control PWM, which is timer 2. First, we determined the PWM frequencies that we could use, which was 2kHz to 10kHz. Then, we found a set of timer scaling values that correspond to frequencies that would play the basic notes of an octave. The period of the PWM is defined in the following equation:
Period = 4 * (1/clock speed) * 16 * (scaling value + 1) This is for a T2_DIV_BY_16.
Note | Timer Scaling Value | Frequency (Hz) align="center" |
---|---|---|
C | 255 | 2441 |
D | 231 | 2693 |
E | 205 | 3033 |
F | 192 | 3238 |
G | 175 | 3551 |
A | 150 | 4139 |
B | 123 | 5040 |
C2 | 100 | 6188 |
Circuit
To the right is a simple circuit diagram showing the PIC connected to a Piezo Speaker.
We added a 1Kohm resistor between the PIC and the speaker because the piezo speaker has very low impedance and connecting the speaker directly to the PIC effectively created a short circuit pulling the PWM output down to zero.
Code
#include <18f4520.h> #fuses HS,NOLVP,NOWDT,NOPROTECT #use delay(clock=40000000) //define timer scaling value for each note #define C 255 #define D 231 #define E 205 #define F 192 #define G 175 #define A 150 #define B 123 #define C2 100 // #define x 14 //total number of notes in song to be played - modify for specific song //the song to be played is "Twinkle Twinkle Little Star" in this demonstration int i; int song [x]={C, C, G, G, A, A, G, F, F, E, E, D, D, C}; //insert notes of song in array int length[x]={1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 2}; //relative length of each note void main() { setup_ccp1(CCP_PWM); // PWM output on pin 17, RC2/CCP1 set_pwm1_duty(30); // changes the volume of the piezo speaker, demonstrate the use of both PWMs independently for (i=0; i<x; i++) { //play x notes inside song array setup_timer_2(T2_DIV_BY_16, song[i], 16); //set PWM frequency according to entries in song array delay_ms(400*length[i]); //each note is played for 400ms*relative length setup_timer_2(T2_DIV_BY_16, 1, 16); //short break between notes //the PWM frequency set beyond audible range in order to create silence delay_ms(50); //to distinguish between consecutive notes } }