Play musical notes PIC
We have discussed in the past experiments how to use a PIC microcontroller to do a variety of things from flashing an LED to driving a motor, etc. Today, we will see how to play notes of a song with a PIC microcontroller. Musical notes are simply sound waves of particular frequencies. If the frequency of a note is known correctly, a microcontroller can be programmed to play the note by generating a square wave (of the same frequency) signal at one of its I/O pins. The signal must be fed to a speaker to listen to the sound. Here, we will discuss playing notes of the popular "Happy birthday to you" tune using a PIC16F628A microcontroller and a buzzer.
Theory
In order to play the tune of a song, you need to know its musical notes. Each note is played for a certain duration and there is a certain time gap between two successive notes. The table below provides frequencies of musical notes starting from middle C. The middle C is designated as C4 because it is the fourth C key on a standard 88-key piano keyboard.
The notes of the other octaves can be obtained by multiplying or dividing these frequencies by 2. For example, the next C note above the middle C would have a frequency of 524 Hz. You can find the frequencies of rest of the notes at the following link: http://cs.nyu.edu/courses/fall03/V22.0201-003/notes.htm
Musical notes can be generated using square waves of the note frequencies. So, in order to play the tune of a song with a microcontroller, all you need to know are the musical notes and their timing information; rest is all programming. A square wave can be generated at an I/O pin of PIC microcontroller by bit-banging the pin high and low. An alternative way of achieving this is using a hardware PWM module. Here, we will be using the former one.
Circuit diagram
The circuit diagram for this experiment is pretty simple. The RB0 pin of the PIC16F628A microcontroller is bit-banged to generate a square wave tone of desired frequency. An I/O pin of PIC16F628A can source current up to 25 mA, which may not be sufficient to drive an electric buzzer directly. Therefore, a BC547 NPN transistor is used as a current amplifier for the buzzer. An RC filtering may be used to improve the quality of audio (square waves are not pure waves and so they don't sound as good as sine waves), but for simplicity, it is not implemented here.
You can see I am using my PIC16F628A breadboard module in this experiment.
Software
Generating audio tones is very easy in mikroC Pro for PIC compiler. It has a built-in Sound Library for serving this purpose. The library has following two functions:
Sound_Init(char *snd_port, char snd_pin): Configures the appropriate MCU pin for sound generation. For example, Sound_Init(&PORTB,0) will configure RB0 pin for the sound output.
Sound_Play(unsigned freq_in_hz, unsigned duration_ms): Generates a square wave signal on the appropriate pin.
The note frequencies of a song can be either defined as a variable array or saved as a constant array in ROM (if RAM size is not sufficient) of the microcontroller. The notes of the song "Happy birthday to you" are not too big and therefore, can be defined in an integer-type array in mikroC, as:
/* Hap py Birth Day to you, Hap py birth day to
C4 C4 D4 C4 F4 E4 C4 C4 D4 C4 G4 */
unsigned int notes[] = { 262, 262, 294, 262, 349, 330, 262, 262, 294, 262, 392,
/* you, Hap py Birth Day dear xxxx Hap py birth
F4 C4 C4 C5 A4 F4 E4 D4 B4b B4b A4 */
349, 262, 262, 523, 440, 349, 330, 294, 466, 466, 440,
/* day to you
F4 G4 F4 */
349, 392, 349
};
Similarly, the duration of each note frequency can also be defined in another integer-type array of the same size. The complete program (source + HEX files) can be downloaded from the following link.
Download mikroC source and HEX files
/*
Experiment No. 19: Playing music notes with a PIC micro
MCU: PIC16F628A at 4.0 MHz, MCLR Enabled
Description: Plays the Happy birthday tune
Compile with MikroC Pro for PIC
*/
void pause(unsigned short i){
unsigned short j;
for (j = 0; j < i; j++){
Delay_ms(10);
}
}
// Happy birthday notes
/* Hap py Birth Day to you, Hap py birth day to
C4 C4 D4 C4 F4 E4 C4 C4 D4 C4 G4 */
unsigned int notes[] = {262, 262, 294, 262, 349, 330, 262, 262, 294, 262, 392,
/* you, Hap py Birth Day dear xxxx Hap py birth
F4 C4 C4 C5 A4 F4 E4 D4 B4b B4b A4 */
349, 262, 262, 523, 440, 349, 330, 294, 466, 466, 440,
/* day to you
F4 G4 F4 */
349, 392, 349
};
unsigned short interval[] = {4, 4, 8, 8, 8, 10, 4, 4, 8, 8, 8, 10, 4, 4, 8, 8, 8,
8, 8, 4, 4, 8, 8, 8, 12};
unsigned short k;
void main() {
CMCON = 0x07;
TRISB = 0b00001000; // GP5, 5 I/P's, Rest O/P's
Sound_Init(&PORTB,0); // Initialize sound o/p pin
do {
for(k = 0; k<25; k++){
Sound_Play(notes[k], 100*interval[k]);
pause(6);
}
pause(100);
}while(1);
}
Here's a video showing the "Happy birthday to you" tune being played by the PIC16F628A microcontroller. You can tweak the time durations of notes little bit to sound it better.
Although bit-banging an I/O pin seems to be a very easy way of generating sound, the microcontroller might be substantially occupied while the tone is active. Read this article to find out alternative ways of producing sound with a microcontroller.
--
With Regards,
s.m.sethupathy,
sms communication,
Tanjore -1.
mobile :9944 186 173
www.questionpaperlink.co.cc
www.sethu-panguvarthagam.blogspot.com
Currently have 0 comments: