How to generate sound using a microcontroller

Post Reply
User avatar
Shane
Captain
Captain
Posts: 226
Joined: Sun Jul 19, 2009 9:59 pm
Location: Jönköping, Sweden

How to generate sound using a microcontroller

Post by Shane » Fri Jun 24, 2011 6:53 am

Here we demonstrate the use of an Arduino PWM output pin to generate sound. The output pin can be toggled very quickly from LOW to HIGH generating a square wave. If the frequency of this square wave is within the range of 20-20,00Hz and sent directly into a Piezo Speaker, an audible tone will be produced (in reality, the range of output is limited by the specs of the speaker and does not cover the entire audible frequency range.) This tutorial covers three sound output schemes: first is the method with the Piezo Speaker connected directly to the Arduino output pin. The second uses a low pass filter to transform the square wave to a line level signal that can be used with standard audio equipment. The third output scheme uses a TDA7052 amplifier (8-DIP) chip with volume control and sends the audio signal into a small 8 OHM speaker.
1.jpg
1.jpg (137.18 KiB) Viewed 3249 times
2.jpg
2.jpg (143.12 KiB) Viewed 3249 times

Code: Select all

int PiezoPin = 9; // piezo output pin

//delay values in microseconds to produce standard octave of tones (C2 to B2)

int C = 7644;
 int CS = 7216;
 int D = 6811;
 int DS = 6428;
 int E = 6067;
 int F = 5727;
 int FS = 5406;
 int G = 5102;
 int GS = 4816;
 int A = 4545;
 int AS = 4290;
 int B = 4050;
 int rest = 0;
 int period = 0;

//array holding one octave of notes + rest
 int noteArray[13] = {C, CS, D, DS, E, F, FS, G, GS, A, AS, B, rest};

int noteValue = 50; //length of note to be played (100ms)

float note = 0; //value to hold note value

//these 2 variables are used to select the octave of the note to be played
 int octave = 0;
 int multiplier = 0;

//time counting variables (for note length)
 long time = 0;
 long newtime = 0;

void setup() {
 pinMode(PiezoPin, OUTPUT); //piezo speaker connected to this pin

}

////////////////////////////////////////////////////////////////////////////
 //function to measure time - compare current time with previous time value
 int CompareTime()
 {
 newtime = millis();
 newtime = newtime - time;
 }

////////////////////////////////////////////////////////////////////////////
 //function to play note selected (or rest) for a determined length of time
 int PlayNote(float delaytime, float notelength)
 {
 time = millis(); //read current time and store for reference
 newtime = millis(); //read new current time - for comparison
 if (delaytime < 1) //this is true only if a rest value has been selected
 {
 do
 {
 CompareTime();
 //wait, generate no sound until the duration of rest has been met
 } while (newtime < notelength);
 }
 else
 {
 do
 // This will toggle the output pin HIGH and LOW at a frequency to produce 
 // the selected note for the note duration.
 // Turning on for a portion of the period(duty cycle) and then off for the
 // remainder of the period produces pulse width modulation. 
 {
 digitalWrite (PiezoPin, HIGH);
 delayMicroseconds (delaytime);
 digitalWrite (PiezoPin, LOW);
 delayMicroseconds (period-delaytime);
 CompareTime();
 } while (newtime < notelength); //do this until reaching note duration
 }
 }

////////////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////////////
 void loop()
 {
 //following determines the octave of the note to be played
 //using random function
 octave = 1;
 multiplier = (random(1,8));
 for (int i=0; i<multiplier; i++){
 octave = octave * 2;
 }
 //random choice of note value
 note = (noteArray[(random(0,12))]/octave); 
 //max delay: 7644/2 = 3822 microseconds so we will say the period is 4000ms
 period = 4000;
 PlayNote (note, noteValue); //play note (50ms long)
 PlayNote (rest, noteValue); //rest for same time
 }
3.jpg
3.jpg (187.49 KiB) Viewed 3249 times
4.jpg
4.jpg (222.41 KiB) Viewed 3249 times
5.jpg
5.jpg (201.8 KiB) Viewed 3249 times
Courtecy of UMASS AMHERST
Post Reply

Return to “Arduino”