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.02 Controlling the Piezo with a Function 

In project 4.01, we used the piezo to create a single tone.  To really make it useful, we need to create different tones with different durations.  In other words, we want the piezo to create music.  This is the perfect place to introduce functions, reusable pieces of codes where we change a couple of parameters, but more or less do the same thing over and over again.


Concepts:  Functions, delayMicroseconds

Circuits: 
  • Circuit 4


  • Select Sketch

    ///////////////////////////////////////////////////
    //Project 4.02 Piezo Function
    int piezo = 12;
    void setup(){
    pinMode(piezo,OUTPUT);
    }
    void loop(){
    piezoTone(262,250);
    delay(250);
    piezoTone(294,250);
    delay(250);
    piezoTone(330,250);
    delay(250);
    piezoTone(349,250);
    delay(250);
    }
    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);
    }
    }
    ///////////////////////////////////////////////////

    This code looks different than everything else we’ve done so far.  In addition to the setup()  and loop() blocks, there’s a function declaration.  Remember, the function is declared after the loop() block, but we can still call the function from either the setup() or loop() blocks.  Don’t be confused by the order of the blocks.  Functions can be called from anywhere in the code, even from other functions.

    Let’s look at the function first.  We declare the function with the term void to indicate that the function doesn’t return any information.  The Arno doesn’t need to save a place in memory to return a value from the function.  We tell the Arno to expect two parameters, freq controls the frequency of the tone and duration controls how long it lasts, in milliseconds:

    void piezoTone(long freq, long duration){

    Like in project 4.01, we still need to know how many microseconds are in a second and the period of time between vibrations.  Since we declare these variables within the function, they’re local variables and aren’t available for use elsewhere in the code.  That’s OK, we don’t need them anywhere else and it frees up memory to use them only when we need them:

      long aSecond = 1000000;

      long period = aSecond/freq;

    It’s convenient to send duration to the function in milliseconds, since it saves us from writing out a bunch of zeros, but we need better control of the timing of the vibrations so we convert the value to microseconds:

      duration = duration*1000;

    The variable period is the time between vibrations.  We need to adjust duration so that it accounts for differences in the time between vibrations.  This yields the number of vibrations needed to fill the period of time specified by duration:

      duration = duration/period;

    Now we simply vibrate the piezo element at the frequency specified by freq enough times to cover the period originally specified by duration:

    for(long k = 0; k < duration; k++){

        digitalWrite(piezo,HIGH);

        delayMicroseconds(period/2);

        digitalWrite(piezo,LOW);

        delayMicroseconds(period/2);

      }

    Using the function makes playing different notes on the piezo easy.  Four calls to the piezoTone function plays the notes of middle C, D, E, and F.  We delay for 0.250 seconds before starting over again:

    void loop(){

      piezoTone(262,250);

      delay(250);

      piezoTone(294,250);

      delay(250);

      piezoTone(330,250);

      delay(250);

      piezoTone(349,250);

      delay(250);

    }

    You can find the frequencies for the full range of notes on a piano here:

    http://en.wikipedia.org/wiki/Piano_key_frequencies

    Back to Projects 4

    Copyright Olympia Circuits LLC 2014. All Rights Reserved.