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.03 Piezo C Major 

The piezoTone function allows us to do a lot with the piezo device without a lot of extra coding.  In this project, we teach the Arno to play the C-major scale and set up some of the coding needed to play a song in the next project.


Concepts:  arrays, functions

Circuits: 
  • Circuit 4


  • Select Sketch

    ///////////////////////////////////////////////////
    //Project 4.03 Piezo C-Major
    int piezo = 12;
    char notes[] = {C,d,D,e,E,F,g,G,a,A,b,B};
    int cScale[] = {1,3,5,6,8,10,12};
    float freqs[] = {16.352,17.324,18.354,19.445,20.602,
    21.827,23.125,24.500,25.957,27.500,29.135,30.868};
    int majorC[] = {0,2,4,5,7,9,11};
    int octave = 0;
    long thisNote;
    void setup(){
    pinMode(piezo,OUTPUT);
    }
    void loop(){
    for(int i=0;i<7;i++){
    int k = majorC[i];
    thisNote = (long) freqs[k]*pow(2,octave);
    piezoTone(thisNote,100);
    delay(50);
    } //end loop through notes
    octave++;
    if(octave>8) octave = 0;
    }
    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);
    }
    }
    ///////////////////////////////////////////////////

    We start by creating several arrays.  The notes array holds the names of the 12 tones in the chromatic scale.  The lower-case letters indicate flats:

    char notes[] = {'C','d','D','e','E','F','g','G','a','A','b','B'};

    The tones array holds the frequencies of each note:

    float freqs[] = {16.352,17.324,18.354,19.445,20.602,

     21.827,23.125,24.500,25.957,27.500,29.135,30.868};

    We actually don’t need the full chromatic scale for this project since we’re only going to play the C-major scale.  However, we want to create durable, reusable code.  It wasn’t much more work to include the full chromatic scale and we can use it later.  You may have also noticed that we don’t use the notes array anywhere in this sketch.  But stay tuned.  We’ll use it in a more complex sketch in the next project.

     The majorC array holds the positions of the C-major notes within the freqs and notes arrays:

    int majorC[] = {0,2,4,5,7,9,11};

    The chromatic scale repeats itself in different octaves.  We don’t need to write out the frequency of every octave since there’s a mathematical relationship between the octaves.  You can learn more about octaves here:

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

    We use the variable octave to hold the octave value. It’s initially set to zero:

    int octave = 0;

    The loop() block is fairly simple.  We start a for loop to run through the 7 notes of the C-Major scale:

      for(int i=0;i<7;i++){

    We retrieve the position of note i in the C-major scale:

        int k = majorC[i]; 

    Next we need to calculate the frequency of the note.  The piezoTone function expects a long value instead of a float.  This means we lose some precision (the decimal part of the frequency).  We control the octave using the built-in pow function.  The pow function  raises its first argument to the power of its second argument (e.g. pow(2,3) = 23 = 8).  The value is cast into a long by including (long) in the statement:

        note = (long) freqs[k]*pow(2,octave);

    Now we call the piezoTone function for the note, delay  for 50 milliseconds between notes, and then move on to the next note:  

        piezoTone(note,100);

        delay(50);

      } //end loop through notes

    After going through the seven notes, we move up an octave (remember that octave++ is the same as writing octave = octave + 1).  After playing octave 8, we go back to 0:

      octave++;

      if(octave>8) octave = 0;

    Back to Projects 4

    Copyright Olympia Circuits LLC 2014. All Rights Reserved.