Project 4.09 Piezo Playback
In the previous project, we measured the average time between four strikes on the piezo and played back the tempo. In this project, we record eight taps and playback the rhythm. In other words, we play back the same patterns of taps instead of just the average rate. Upload this sketch and tap on the peizo eight times to get it going. Press SW1 to reset the sketch and prepare it to record another set of taps.
Concepts: analogRead, arrays, boolean variable type, functions, switching pinMode
Circuits:
Concepts: analogRead, arrays, boolean variable type, functions, switching pinMode
Circuits:
Much of this sketch is the same as the previous one. On difference is that we need to record the time between strikes on the piezo. We store the values in the array periods:
long periods[7];
Look back at the previous project to see how we record the timing of each strike. We’re going to skip forward to the point where we test to see if eight strikes have been recorded:
if(count==8){
First, we switch piezo to an output to prepare it to playback the rhythm. We also reset the variable count that was used to determine when eight strikes had been recorded:
pinMode(piezo,OUTPUT);
count = 0; //reset for next time
//calculate period
Next, we calculate the time between strikes and load the results in the array periods. We also make sure that each period is at least 50 milliseconds:
for(int j = 0; j<7; j++){
periods[j] = times[j+1] - times[j];
//make delays at least 50 milliseconds
if(periods[j] < 51) periods[j] = 51;
}
Now we prepare to playback the rhythm until SW1 is pressed and goes to LOW:
//now play back until SW1 pressed
playback = 0;
while(digitalRead(SW1)==HIGH){
We begin by playing a tone and flashing redLED:
//create tone
digitalWrite(redLED,HIGH);
piezoTone(2500,50);
digitalWrite(redLED,LOW);
We have 7 periods between tones. They start at 0 (the first element of all arrays) and go up to 6. We use the variable playback to keep track of which element of periods to use:
if(playback<7){
delay(periods[playback] - 50);
}
What do we do after the last tone is played? If we start over again right away, it would just merge with the previous tone. So when we get to the seventh period (the sixth element of the array) we replay it. In other words, we repeat the last period between tones before we start the sequence over again:
else{
delay(periods[6]);
}
Now we increment playback and reset it once it reaches 8. Then we go back to the top of the while loop:
playback ++;
if(playback==8) playback=0;
} //end while for SW1
If we break out of the while loop by pressing SW1, we reset piezo to an input to prepare it for the next set of strikes:
pinMode(piezo,INPUT);
} //end if for count = 7
}
long periods[7];
Look back at the previous project to see how we record the timing of each strike. We’re going to skip forward to the point where we test to see if eight strikes have been recorded:
if(count==8){
First, we switch piezo to an output to prepare it to playback the rhythm. We also reset the variable count that was used to determine when eight strikes had been recorded:
pinMode(piezo,OUTPUT);
count = 0; //reset for next time
//calculate period
Next, we calculate the time between strikes and load the results in the array periods. We also make sure that each period is at least 50 milliseconds:
for(int j = 0; j<7; j++){
periods[j] = times[j+1] - times[j];
//make delays at least 50 milliseconds
if(periods[j] < 51) periods[j] = 51;
}
Now we prepare to playback the rhythm until SW1 is pressed and goes to LOW:
//now play back until SW1 pressed
playback = 0;
while(digitalRead(SW1)==HIGH){
We begin by playing a tone and flashing redLED:
//create tone
digitalWrite(redLED,HIGH);
piezoTone(2500,50);
digitalWrite(redLED,LOW);
We have 7 periods between tones. They start at 0 (the first element of all arrays) and go up to 6. We use the variable playback to keep track of which element of periods to use:
if(playback<7){
delay(periods[playback] - 50);
}
What do we do after the last tone is played? If we start over again right away, it would just merge with the previous tone. So when we get to the seventh period (the sixth element of the array) we replay it. In other words, we repeat the last period between tones before we start the sequence over again:
else{
delay(periods[6]);
}
Now we increment playback and reset it once it reaches 8. Then we go back to the top of the while loop:
playback ++;
if(playback==8) playback=0;
} //end while for SW1
If we break out of the while loop by pressing SW1, we reset piezo to an input to prepare it for the next set of strikes:
pinMode(piezo,INPUT);
} //end if for count = 7
}