Learn Arduino with Olympia Circuits
Learn Arduino
  • Home
    • Get Started
    • How to Use This Site
  • Electronics
    • The Basics
    • Electricity Flows like Water
    • Electronic Components
    • The Arno Board
  • Programming
    • The Basics
    • setup and loop Blocks
    • Variables and Arrays
    • Connecting with the Pins
    • Flow Control >
      • if Statement
      • Loops
      • Delays
    • Functions
    • Serial Communication
    • USB
    • Some Thoughts
  • Projects
    • Projects 1 >
      • 1.01: Blink
      • 1.02 Blink x2
      • 1.03 Blink Faster
      • 1.04 LED Chase!
      • 1.05 Wait To Blink
      • 1.06 Blink a Little Faster Now
      • 1.07 LED Fade
      • 1.08 RGB Blink
      • 1.09 Change RGB Color with SW1
      • 1.10 Fade RGB Colors
      • 1.11 Reaction Time Game
    • Projects 2 >
      • 2.01 Hello World
      • 2.02 Talk Back
      • 2.03 ASCII Values
      • 2.04 Ski Game
      • 2.05 Demonstration of the String Object
    • Projects 3 >
      • 3.01 Read the Potentiometer
      • 3.02 ASCIIbet Soup
      • 3.03 Potentiometer sets LED Brightness
      • 3.04 Potentiometer Sets Blink Rate
      • 3.05 LED Chase, Part II
    • Projects 4 >
      • 4.01 Bringing the Piezo to Life
      • 4.02 Controlling the Piezo with a Function
      • 4.03 Piezo C Major
      • 4.04 Piezo Greensleaves
      • 4.05 Piezo Metronome
      • 4.06 Piezo as an Input
      • 4.07 Piezo as an Input 2
      • 4.08 Metronome II
      • 4.09 Piezo Playback
      • 4.10 Piezo Fireworks
      • 4.11 Piezo Mosquito
    • Projects 5 >
      • 5.01 The Phototransistor
      • 5.02 Light and Sound
      • 5.03 Light and Sound II
    • Projects 6 >
      • 6.01 EEPROM
      • 6.02 I2C Address Scan
      • 6.03 Read the I2C Temperature Sensor
      • 6.04 High Temperature Alarm
    • Projects 7 >
      • 7.01 Arno Phone Home
      • 7.02 Keyboard Alphabet
      • 7.03 Move Mouse
      • 7.04 Draw Squares
    • Special Projects >
      • Bike Light Demo
  • References
    • Arno Pin Key
    • Arno Schematic
    • Project Index

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: 
  • Circuit 3
  • Circuit 4


  • Select Sketch

    ///////////////////////////////////////////////////
    //Project 4.05 Piezo Metronome I
    int piezo = 12;
    int knock = 0;
    int redLED = 9;
    int periods = 0;
    int wait = 0;
    int nchar = 0;
    void setup(){
    Serial.begin(9600);
    pinMode(piezo,OUTPUT);
    pinMode(redLED,OUTPUT);
    }
    void loop(){
    //wait for serial input
    while(Serial.available()==0){
    }
    delay(50);
    if(Serial.available()>0){
    nchar = Serial.available();
    char readIn[nchar +1];
    for(int k = 0; k < nchar; k++){
    readIn[k] = Serial.read();
    }
    periods = atoi(readIn);
    }
    if(periods > 1200 || periods < 1){
    Serial.println(Period outside range, period set to 1200);
    periods = 1200;
    }
    Serial.print(Beats per Minute = );
    Serial.println(periods);
    while(Serial.available()==0){
    //create tone
    digitalWrite(redLED,HIGH);
    piezoTone(2500,50);
    digitalWrite(redLED,LOW);
    wait = 60000/periods;
    wait = wait-50;
    delay(wait);
    } //end if serial not available
    }
    void piezoTone(long freq, long duration){
    long aSecond = 1000000;
    long period = aSecond/freq;
    duration = duration*1000;
    duration = duration/period;
    for(long k = 0; k < duration; k++){
    digitalWrite(piezo,HIGH);
    delayMicroseconds(period/2);
    digitalWrite(piezo,LOW);
    delayMicroseconds(period/2);
    }
    }
    ///////////////////////////////////////////////////

    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

    Back to Projects 4

    Copyright Olympia Circuits LLC 2014. All Rights Reserved.