Project 4.05 Piezo Metronome
A metronome is a device that generates a regular beat to help musicians maintain a tempo. The Arno can generate a beep, and it keeps track of time, so we can program it to act like a metronome! In this project, the user inputs the tempo in beats per minute through the serial monitor and the Arno keeps time.
Upload this sketch to your Arno and open the serial monitor. Type the beats per minute into the serial monitor’s text box and hit Enter or click “Send”.
Concepts: atoi, functions, serial monitor
Circuits:
The variables and setup() block should look familiar to you at this point. As we enter the loop() block, we wait for input from the user through the serial monitor.
while(Serial.available()==0){
}
Once input is detected, we wait a little longer for all of the characters to enter the buffer:
delay(50);
Now we read the input into a char array:
if(Serial.available()>0){
nchar = Serial.available();
char readIn[nchar +1];
for(int k = 0; k < nchar; k++){
readIn[k] = Serial.read();
}
At this point we have a problem. We have user input in a char array but we need an int value. This might not seem like a big problem at first, but char variables are fundamentally different than int variables in the way they store information. Thankfully, the C programming language has a special function just for this problem. The function atoi (array to int) takes care of it for us:
periods = atoi(readIn);
}
Next, we make sure the user entered a reasonable value:
if(periods > 1200 || periods < 1){
Serial.println("Period outside range, period set to 1200");
periods = 1200;
}
We also keep the user informed about what the Arno plans to do:
Serial.print("Beats per Minute = ");
Serial.println(periods);
Finally we enter a loop where the Arno will keep the beat until new user input is detected. The Arno generates a tone and flashed the redLED:
while(Serial.available()==0){
//create tone
digitalWrite(redLED,HIGH);
piezoTone(2500,50);
digitalWrite(redLED,LOW);
A little math is needed to calculate the delay in milliseconds since the user input is in beats per second:
wait = 60000/periods;
And we have to account for the 50 millisecond duration of the piezoTone:
wait = wait-50;
delay(wait);
} //end if serial not available
while(Serial.available()==0){
}
Once input is detected, we wait a little longer for all of the characters to enter the buffer:
delay(50);
Now we read the input into a char array:
if(Serial.available()>0){
nchar = Serial.available();
char readIn[nchar +1];
for(int k = 0; k < nchar; k++){
readIn[k] = Serial.read();
}
At this point we have a problem. We have user input in a char array but we need an int value. This might not seem like a big problem at first, but char variables are fundamentally different than int variables in the way they store information. Thankfully, the C programming language has a special function just for this problem. The function atoi (array to int) takes care of it for us:
periods = atoi(readIn);
}
Next, we make sure the user entered a reasonable value:
if(periods > 1200 || periods < 1){
Serial.println("Period outside range, period set to 1200");
periods = 1200;
}
We also keep the user informed about what the Arno plans to do:
Serial.print("Beats per Minute = ");
Serial.println(periods);
Finally we enter a loop where the Arno will keep the beat until new user input is detected. The Arno generates a tone and flashed the redLED:
while(Serial.available()==0){
//create tone
digitalWrite(redLED,HIGH);
piezoTone(2500,50);
digitalWrite(redLED,LOW);
A little math is needed to calculate the delay in milliseconds since the user input is in beats per second:
wait = 60000/periods;
And we have to account for the 50 millisecond duration of the piezoTone:
wait = wait-50;
delay(wait);
} //end if serial not available