Arduino Ocarina

Arduino has some pretty cool features. It's easy to use and you can make a lot of very nerdy projects. For me, this means making an ocarina like One seen in The Legend of Zelda: Ocarina of Time.

If you haven't worked with Arduino before I would recommend going and finding some basic tutorials. You should be familiar with loops, arrays, if statements, and switch statements. However, the hardware is relatively simple and should be pretty easy to work with.

Due to some problems with the 3D printer I was using, I ended up making a case out of polymer clay. I would recommend finding or making an ocarina case you can 3D print as a sculpted one can be hard if you don't know what you're doing (like me). Thingiverse has some great models you can download for free.

For this project you're going to need a few basic components. All of the supplies on this list can easily be found on Amazon.

Supplies:

Step 1: Getting to Know the Parts

The parts for this project are pretty simple. You have your Arduino, a joystick, a speaker, and a bunch of buttons. I'm using two pronged buttons, but the four pronged ones are fine.

Buttons:

Buttons are some of the simplest components that can be used with an Arduino. They open and close a circuit. When they are closed current can pass through and the circuit is clodsed, when they are open the circuit is open. Most buttons work with 10 k-Ohm resistors.

Joystick

Joysticks are essentially two potentiometers stuck together. A potentiometer is a simple component that changes its resistance depending on the position of a knob or other mechanical component. For our joystick, there is one potentiometer to control the resistance on the x-axis and another one for the y-axis. The x and y axes both function as analog components that are read by the Arduino with values between 0 and 1023. At rest, the joystick has a value of 512, 512. The lowest value (0,0) is at the bottom left corner. The highest value is (1023,1023) at the upper right hand corner.

Speakers

The speakers for this project are simple piezoelectric speakers. They produce noise through high-speed mechanical motion. This is done by by applying a voltage across the speaker at various frequenies to produce sound.

Step 2: Setting Up Pitches.h

If you aren't familiar with the Arduino IDE already, you may want to go check out some other tutorials for it.

The first thing we're going to do is to open a new sketch on the Arduino IDE. We'll have to define frequencies of the notes we're going to use. The easiest way to do this is to actually create a header file in the same sketch. Fortunately, some of examples that come with the Arduino IDE come with this so we don't have to define 88 different notes ourselves. To do this, we're first going to go to the top right hand corner of the screen and click the arrow. A menu opens up. You're going to want to click "New Tab".

At the bottom of the screen a yellow bar will appear asking you to name a new file. I named mine pitches.h, you can name it anything as long it has the .h at the end. That's what makes it a header file.

Next go to File and go down to Examples, Digital, and click on any of the examples that start with tone.

Click on the 2nd tab of any of the tone examples. Copy all of the code. Each #define command sets a note to a frequency. Go back to the pitches.h tab you created in your sketch and paste the code you copied. You should also define the lengths you use with notes. You'll have to do this yourself, but it uses the same format as all of the other definitions. I used WHOLE for a whole note and set its duration for 1 second. I set HALF to 0.5 seconds and so on. Remember, the Arduino measures time in milliseconds.

Save your sketch.

Step 3: Pins and Variables

The next thing you want to do is to start defining your pins and initializing your variables. You have seven buttons connected to notes, so your going to want to create an order for the pins and eventually the buttons you'll be connecting them to. You'll also be defining your pins for the speaker, the switch button, and the joystick. The joystick will be connected to two analog pins.

#include "pitches.h"
#define BUZZ_PIN 13 //speaker is connected to pin 13
#define SWITCH_PIN 2 //switch pin is connected to pin 2

#define E_NOTE 3 //Button on pin 3 plays E note
#define F_NOTE 4 //Button on pin 4 plays F note
#define G_NOTE 5 //Button on pin 5 plays G note
#define A_NOTE 6 //Button on pin 6 plays A note
#define B_NOTE 7 //Button on pin 7 plays B note
#define C_NOTE 8 //Button on pin 8 plays C note
#define D_NOTE 9 //Button on pin 9 plays D note

#define JoyStick 10 //the switch pin for the joystick is conneted to pin 10
#define JoyXpin A0 //the x-axis of the joystick is connected to analog pin 0
#define JoyYpin A1 //the y-axis of the joystick is connected to analog pin 1

int joyx = 0; //initilize the value of the x-axis on the joystick to 0
int joyy = 0; //initilize the value of the y-axis on the joystick to 0

int songCase = 0; //controls the mode of the ocarina and which song it's playing
boolean change = false; //connected to the SWITCH_PIN to tell the ocarina whether to
                        //change modes or keep going

songCase is eventually going to control if the ocarina is in playable mode or if it playing a pre-programmed song. change tells the ocarina if it needs to change the song case based on if the switch button is pushed. For our program, we will have four cases. The first will allow us to play notes individually. That will be case 0. The next three cases will all be pre-programmed songs.

Step 4: Functions: FreePlay

Before we begin our setup and loop functions, let's set about making some songs to play. For my ocarina I chose a free play mode and three songs from the Legend of Zelda: Ocarina of Time: Zelda's Lullaby, Saria's Song, and Song of Storms. With some time and sheet music it is totally possible to make more songs. Now to the code.

Let's start with free play mode. For this functions you're going to be connecting to seven out of your eight buttons and your joystick.

First, your going to declare the function FreePlay (or whatever else you decide to name it). It will be a void function, so it won't return any values, and it will have no inputs. You declare your function above your setup and loop functions, but define them below them. It isn't require, just good practice. The code will look something like this:

void FreePlay();

Within your function definition, under you setup and loop functions, the first thing you're going to do is take those joyx and joyy variables that you initialized earlier and set the to analogRead(JoyXpin) and analogRead(JoyYpin) respectively. Next your going to start making code for each note. We want each of our notes to be able to be played normally, one octave higher, one octave lower, sharp, flat, octave high flat, octave low flat, octave high sharp, and octave low sharp. Including our normal note, that's 9 nine different notes for one button. That's where the joystick comes in.

For the joystick, you'll be having values on the x-axis and y-axis control the variation of the note you play. Up is octave high, down is octave low, left is flat, and right is sharp. The corners between them are variations thereof. The movement of the joystick makes all of these moves easier than, say, a panel of eight buttons. The code for my first button, my E note, looks like this:

if (digitalRead(E_NOTE) == 1) { // if the button for E_Note is pressed<br>    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_F4); //plays F4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_DS4); //plays D-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_F2);//plays F2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_DS2); //plays D-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_F3); //plays F3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_E4); //plays E4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_DS3);//plays D-sharp 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_E2);//plays E2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_E3); //plays E3
    }
  }

You might notice that I'm using a lot of if statements instead of a switch statement. This was done so that there wouldn't be any problems if two things happened at the same time. This is less important for the joystick if statements, since all of the options are continuous, but is much more important for the full FreePlay code with all of its buttons. The speaker can only play one note at a time, so pushing two buttons in a switch statement could have unexpected consequences.

The tone functions ( tone(BUZZ_PIN, NOTE#);) have two arguments: output pin you are using, and the frequency (note) you want to output. There is a third optional argument of the duration of the note in milliseconds. We'll see more of that in the pre-programmed song functions.

The numbers for each of the comparisons come from the range of the analog pins, which are from 0 to 1023. Those comparisons just measure the position of the joystick. I leave a little bit of leeway in position.

In the initial comparison in the if statement, you can see I used (digitalRead(E_NOTE) == 1). All this is doing is checking if the button has been pushed. If it hasn't it moves on. The "== 1" isn't actually necessary. It's more of a personal preference.

This is the full code for FreePlay:

void FreePlay() {<br>  joyx = analogRead(JoyXpin); //reads joystick x-axis
  joyy = analogRead(JoyYpin); //reads joystick y-axis
  /* E and F are half steps of each other so E# is actually F and Fb is actually E
     The same is true of B and C. For all other notes, the sharp of the lower note
     is the same as the flat of the higher one. In pitches.h I only defined sharp
     notes, so in the case of flats for my if statements, I am using the sharp of
     the note one lower than the actually note I'm using as a flat. The number
     following each note is the octave the note is in, with 1 being the lowest and
     8 being the highest. All octaves start with C. My buttons start with E because
     it is the is the lowest barred note on the treble clef staff.
  */
  if (digitalRead(E_NOTE) == 1) { // if the button for E_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_F4); //plays F4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_DS4); //plays D-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_F2);//plays F2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_DS2); //plays D-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_F3); //plays F3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_E4); //plays E4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_DS3);//plays D-sharp 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_E2);//plays E2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_E3); //plays E3
    }
  } else if (digitalRead(F_NOTE) == 1) { // if the button for F_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_FS4); //plays F-sharp 4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_E4); //plays E 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_FS2); //plays F-sharp 2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_E2); //plays E 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_FS3); //plays F-sharp 3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_F4); //plays F 4
    } else if (joyx < 200) {
      tone(BUZZ_PIN, NOTE_E3); //plays E 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_F2); //plays
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_F3);
    }
  } else if (digitalRead(G_NOTE) == 1) { // if the button for G_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_GS4); //plays G-sharp 4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_FS4); //plays F-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_GS2); //plays G-sharp 2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_FS2); //plays F-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_GS3); //plays G-sharp 3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_G4); //plays G 4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_FS3); //plays F-sharp 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_G2); //plays G 2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_G3); //plays G 3
    }
  } else if (digitalRead(A_NOTE) == 1) {// if the button for A_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_AS4); //plays A-sharp 4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_GS4); //plays G-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_AS2); //plays A-sharp 2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_GS2); //plays F-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_AS3); //plays G-sharp 3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_A4); //plays A 4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_GS3); //plays G -sharp 3
    } else if (joyy < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_A2); //plays A 2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_A3); //plays A 3
    }
  } else if (digitalRead(B_NOTE) == 1) {// if the button for B_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_C5); //plays C 5
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_AS4); //plays A-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_C3); //plays C 3
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_AS2); //plays A-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_C4); //plays C 4
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_B4); //plays B 4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_AS3); //plays A-sharp 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_B2); //plays B 2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_B3); //plays B 3
    }
  } else if (digitalRead(C_NOTE) == 1) { // if the button for C_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_CS5); //plays C-sharp 5
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_B4); //plays B 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_CS3); //plays C-sharp 3
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_B2); //plays B 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_CS4); //plays C-sharp 4
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_C5); //plays C 5
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_B3); //plays B 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_C3); //plays C 3
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_C4); //plays C4
    }
  } else if (digitalRead(D_NOTE) == 1) { // if the button for D_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_DS5); //plays D-sharp 5
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_CS5); //plays C-sharp 5
    } else if (joyx > 800 && joyx < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_DS3); //plays D-sharp 3
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_CS3); //plays C-sharp 3
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_DS4); //plays D-sharp 4
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_D5); //plays D 5
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_CS4); //plays C-sharp 4
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_D3);// D 3
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_D4);
    }
  } else { //if no buttons are pressed play nothing
    noTone(BUZZ_PIN);
  }
  if (digitalRead(SWITCH_PIN) == 1) { //if the swtich button is pressed move to case 1
    songCase = 1;
  }
}

At the bottom you can the noTone function, which simply tells the speaker or buzzer not to produce any sound. The next if statement isn't connected to the others and will take the case from 0 to 1 if the switch button is pushed.

Step 5: Functions: Pre-Programmed Songs

I chose to only make three songs fro my ocarina, but you can make as many as your Arduino's memory will hold if you're willing to push the button that many times. Each of your song functions is going to be type void with no arguments. Let's start by writing the Song of Storms:

The first thing you're going to need is two arrays. One will contain the notes of the song and the other will contain the lengths of those notes. They'll look something like this:

/*All of the notes in Song of Storms. Each line is a measure*/<br>  int songOfStormsNotes[] = {NOTE_D3, NOTE_A3, NOTE_D4,
                             NOTE_D3, NOTE_A3, NOTE_D4,
                             NOTE_E4, NOTE_F4, NOTE_E4, NOTE_F4,
                             NOTE_E4, NOTE_C4, NOTE_A3,
                             NOTE_A3, NOTE_D3, NOTE_F3, NOTE_G3,
                             NOTE_A3,
                             NOTE_A3, NOTE_D3, NOTE_F3, NOTE_G3,
                             NOTE_E3
                            };
  /*The length of all the notes in Song of Storms. Each line is a measure*/
  int songOfStormsNlength[] = {EIGHTH, EIGHTH, HALF,
                               EIGHTH, EIGHTH, HALF,
                               QUARTER_DOT, EIGHTH, EIGHTH, EIGHTH,
                               EIGHTH, EIGHTH, HALF,
                               QUARTER, QUARTER, EIGHTH, EIGHTH,
                               HALF_DOT,
                               QUARTER, QUARTER, EIGHTH, EIGHTH,
                               HALF_DOT
                              };

Next we'll define a pause length. This will define the time in between notes. It makes the notes sound separate. The smaller the pause length the more the notes flow together. For the Song of Storms we want them relatively close so we'll define pause_note as 1.2, which means the program pauses for 1.2 times the length of the note.

float pause_note = 1.2;

The for loop is what actually plays the song. It looks something like this:

for (int i = 0; i < 23; i++) {    //plays note i of Song of Storms for length i
    tone(BUZZ_PIN, songOfStormsNotes[i], songOfStormsNlength[i]);
    delay(pause_note * songOfStormsNlength[i]); //pauses for length i *pause_note
    change = digitalRead(SWITCH_PIN); //checks if swtich button has been pushed
    if (change == true) { //if the switch button was pushed
      songCase = 0; //go back to case 0
      delay(500);
      break; //breaks out of for loop
    }
  }

The "i" defined in the for loop is the note in the song. There are 23 notes in Song of Storms (or at least the version I transcribed) so the for loop plays 23 times. It continues to play and repeat until the switch button is pushed. Notice that this is checked within the for loop. If you tried to check it outside of the for loop you couldn't change the case while the song is playing. You can also declare the arrays outside the function. This is entirely personal preference.


The three songs I made look like this:


/*Plays Zelda's Lullaby for the Legend of Zelda: Ocarina of Time*/<br>void ZeldasLullaby() {
  /*All of the notes in Zelda's Lullaby. Each line is a measure*/
  int zeldasLullabyNotes[] = { NOTE_B3, NOTE_D4,
                               NOTE_A3, NOTE_G3, NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A4, NOTE_G4,
                               NOTE_D4, NOTE_C4, NOTE_B3,
                               NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A3, NOTE_G3, NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A4, NOTE_G4,
                               NOTE_D5
                             };

 /*The length of all the notes in Zelda's Lullaby. Each line is a measure.*/
  int zeldasLullabyNlength[] = {HALF, QUARTER,
                                HALF, EIGHTH, EIGHTH,
                                HALF, QUARTER,
                                HALF_DOT,
                                HALF, QUARTER,
                                HALF, QUARTER,
                                HALF, EIGHTH, EIGHTH,
                                HALF_DOT,
                                HALF, QUARTER,
                                HALF, EIGHTH, EIGHTH,
                                HALF, QUARTER,
                                HALF_DOT,
                                HALF, QUARTER,
                                HALF, QUARTER,
                                HALF_DOT
                               };
  float pause_note = 1.3;
  for (int i = 0; i < 29; i++) {
    //plays the note i in the array for length i
    tone(BUZZ_PIN, zeldasLullabyNotes[i], zeldasLullabyNlength[i]);
    delay(pause_note * zeldasLullabyNlength[i]); //pasues for length i*pause_note
    change = digitalRead(SWITCH_PIN); //checks if the swtich button hass been pushed
    if (change == true) { //if the swtich button has been pushed
      songCase = 2; //change song case to 2
      delay(500);
      break; //break out of loop
    }
  }
}
/*Plays Saria's Song from the Legend of Zelda: Ocarina of Time.*/
void SariasSong() {
  /*All of the notes in Saria's Song. Each line is a measure*/
  int sariasSongNotes[] = {NOTE_F3, NOTE_A3, NOTE_B3,
                           NOTE_F3, NOTE_A3, NOTE_B3,
                           NOTE_F3, NOTE_A3, NOTE_B3, NOTE_E4,
                           NOTE_D4, NOTE_B3, NOTE_C4,
                           NOTE_B3, NOTE_G3, NOTE_E3, NOTE_D3,
                           NOTE_E3, NOTE_G3, NOTE_E3,
                           NOTE_F3, NOTE_A3, NOTE_B3,
                           NOTE_F3, NOTE_A3, NOTE_B3,
                           NOTE_F3, NOTE_A3, NOTE_B3, NOTE_E4,
                           NOTE_D4, NOTE_B3, NOTE_C4,
                           NOTE_E4, NOTE_B3, NOTE_G3, NOTE_B3,
                           NOTE_G3, NOTE_D3, NOTE_E3,
                           NOTE_D3, NOTE_E3, NOTE_F3,
                           NOTE_G3, NOTE_A3, NOTE_B3,
                           NOTE_C4, NOTE_B3, NOTE_E3,
                           NOTE_D3, NOTE_E3, NOTE_F3,
                           NOTE_G3, NOTE_A3, NOTE_B3,
                           NOTE_C4, NOTE_D4, NOTE_E4,
                           NOTE_D3, NOTE_E3, NOTE_F3,
                           NOTE_G3, NOTE_A3, NOTE_B3,
                           NOTE_C4, NOTE_B3, NOTE_E3,
                           NOTE_F3, NOTE_E3, NOTE_G3, NOTE_F3, NOTE_A3, NOTE_G3, NOTE_B3, NOTE_A3,
                           NOTE_C4, NOTE_B3, NOTE_D4, NOTE_C4, NOTE_E4, NOTE_D4,
                           NOTE_B3, NOTE_C4, NOTE_A3,
                           NOTE_B3
                          };

/*The length of all the notes in Saria's Song. Each line is a measure*/
  int sariasSongNlength[] = {EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, EIGHTH, EIGHTH,
                             QUARTER, EIGHTH, EIGHTH,
                             EIGHTH, EIGHTH, QUARTER + QUARTER_DOT, EIGHTH,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, EIGHTH, EIGHTH,
                             QUARTER, EIGHTH, EIGHTH,
                             EIGHTH, EIGHTH, QUARTER + QUARTER_DOT, EIGHTH,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH,
                             EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH,
                             (EIGHTH * (2 / 3)), (EIGHTH * (2 / 3)), (EIGHTH * (2 / 3)),
                             WHOLE
                            };
  float pause_note = 1.5;
  for (int i = 0; i < 85; i++) {
    tone(BUZZ_PIN, sariasSongNotes[i], sariasSongNlength[i]);//plays note i at length i fr Saria's Song
    delay(pause_note * sariasSongNlength[i]);  //pauses for length i *pause_note
    change = digitalRead(SWITCH_PIN); //check the switch button
    if (change == true) {
      songCase = 3; //if button is pressed change to case 3
      delay(500);
      break;
    }
  }
}
/*Plays the Song of Storms from Legend of Zelda: Ocarian of Time*/
void SongOfStorms() {
  /*All of the notes in Song of Storms. Each line is a measure*/
  int songOfStormsNotes[] = {NOTE_D3, NOTE_A3, NOTE_D4,
                             NOTE_D3, NOTE_A3, NOTE_D4,
                             NOTE_E4, NOTE_F4, NOTE_E4, NOTE_F4,
                             NOTE_E4, NOTE_C4, NOTE_A3,
                             NOTE_A3, NOTE_D3, NOTE_F3, NOTE_G3,
                             NOTE_A3,
                             NOTE_A3, NOTE_D3, NOTE_F3, NOTE_G3,
                             NOTE_E3
                            };
  /*The length of all the notes in Song of Storms. Each line is a measure*/
  int songOfStormsNlength[] = {EIGHTH, EIGHTH, HALF,
                               EIGHTH, EIGHTH, HALF,
                               QUARTER_DOT, EIGHTH, EIGHTH, EIGHTH,
                               EIGHTH, EIGHTH, HALF,
                               QUARTER, QUARTER, EIGHTH, EIGHTH,
                               HALF_DOT,
                               QUARTER, QUARTER, EIGHTH, EIGHTH,
                               HALF_DOT
                              };
  float pause_note = 1.2;
  for (int i = 0; i < 23; i++) {
    //plays note i of Song of Storms for length i
    tone(BUZZ_PIN, songOfStormsNotes[i], songOfStormsNlength[i]);
    delay(pause_note * songOfStormsNlength[i]); //pauses for length i *pause_note
    change = digitalRead(SWITCH_PIN); //checks if swtich button has been pushed
    if (change == true) { //if the switch button was pushed
      songCase = 0; //go back to case 0
      delay(500);
      break; //breaks out of for loop
    }
  }
}

Step 6: Void Setup and Void Loop

The nice thing about the setup and the loop function in this code is that they are extremely simple. The Setup function doesn't actually need anything at all inside of it. It looks like this:

void setup(){
}

The loop function is almost as simple. It only has one switch statement in it which is dependent on the variable songCase. songCase is changed within each of the other non-setup functions when the switch button is pushed. However, we initialized it to 0 when we were declaring variables, so our code starts in the FreePlay function.

The entire loop function looks like this:

void loop() { /*Switches between songs and free play mode based on the song case*/
  switch (songCase) {
    case 0: FreePlay(); //free play mode at case 0
      break;
    case 1: ZeldasLullaby(); //case 1 plays Zelda's Lullaby
      break;
    case 2: SariasSong(); //case 2 plays Saria's Song
      break;
    case 3: SongOfStorms(); //case 2 plays Song of Storms
      break;
    default: FreePlay(); //defaults to free play mode
      break;
  }
}

The entirety of the code for the ocarina ooks something like this:

#include "pitches.h"<br>#define BUZZ_PIN 13 //speaker is connected to pin 13
#define SWITCH_PIN 9 //switch pin is connected to pin 2

#define E_NOTE 8 //Button on pin 3 plays E note
#define F_NOTE 7 //Button on pin 4 plays F note
#define G_NOTE 6 //Button on pin 5 plays G note
#define A_NOTE 5 //Button on pin 6 plays A note
#define B_NOTE 4 //Button on pin 7 plays B note
#define C_NOTE 3 //Button on pin 8 plays C note
#define D_NOTE 2 //Button on pin 9 plays D note

#define JoyStick 10 //the switch pin for the joystick is conneted to pin 10
#define JoyXpin A1 //the x-axis of the joystick is connected to analog pin 0
#define JoyYpin A0 //the y-axis of the joystick is connected to analog pin 1

int joyx = 0; //initilize the value of the x-axis on the joystick to 0
int joyy = 0; //initilize the value of the y-axis on the joystick to 0

int songCase = 0; //controls the mode of the ocarina and which song it's playing
boolean change = false; //connected to the SWITCH_PIN to tell the ocarina whether to
//change modes or keep going

void FreePlay();
void SongOfStorms();
void SariasSong();
void ZeldasLullaby();

void setup() {
}

void loop() {
  /*Switches between songs and free play mode based on the song case*/
  switch (songCase) {
    case 0: FreePlay(); //free play mode at case 0
      break;
    case 1: ZeldasLullaby(); //case 1 plays Zelda's Lullaby
      break;
    case 2: SariasSong(); //case 2 plays Saria's Song
      break;
    case 3: SongOfStorms(); //case 2 plays Song of Storms
      break;
    default: FreePlay(); //defaults to FrrePlay mode
      break;
  }
}
/* FreePlay allows the user to play the ocarina like an acutal instrument. Each of 7 buttons,
    not including the switch button reperesents a note between A and G. All of the notes can
    be played either as the default middle tone, one octave higher, one octave lower, sharp,
    flat, octave high sharp, octave high flat, octave low, sharp, or octave low flat. 
*/
void FreePlay() {
  joyx = analogRead(JoyXpin); //reads joystick x-axis
  joyy = analogRead(JoyYpin); //reads joystick y-axis
  /* E and F are half steps of each other so E# is actually F and Fb is actually E
     The same is true of B and C. For all other notes, the sharp of the lower note
     is the same as the flat of the higher one. In pitches.h I only defined sharp
     notes, so in the case of flats for my if statements, I am using the sharp of
     the note one lower than the actually note I'm using as a flat. The number
     following each note is the octave the note is in, with 1 being the lowest and
     8 being the highest. All octaves start with C. My buttons start with E because
     it is the is the lowest barred note on the treble clef staff.
  */
  if (digitalRead(E_NOTE) == 1) { // if the button for E_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_F4); //plays F4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_DS4); //plays D-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_F2);//plays F2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_DS2); //plays D-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_F3); //plays F3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_E4); //plays E4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_DS3);//plays D-sharp 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_E2);//plays E2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_E3); //plays E3
    }
  } else if (digitalRead(F_NOTE) == 1) { // if the button for F_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_FS4); //plays F-sharp 4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_E4); //plays E 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_FS2); //plays F-sharp 2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_E2); //plays E 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_FS3); //plays F-sharp 3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_F4); //plays F 4
    } else if (joyx < 200) {
      tone(BUZZ_PIN, NOTE_E3); //plays E 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_F2); //plays
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_F3);
    }
  } else if (digitalRead(G_NOTE) == 1) { // if the button for G_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_GS4); //plays G-sharp 4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_FS4); //plays F-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_GS2); //plays G-sharp 2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_FS2); //plays F-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_GS3); //plays G-sharp 3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_G4); //plays G 4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_FS3); //plays F-sharp 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_G2); //plays G 2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_G3); //plays G 3
    }
  } else if (digitalRead(A_NOTE) == 1) {// if the button for A_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_AS4); //plays A-sharp 4
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_GS4); //plays G-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_AS2); //plays A-sharp 2
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_GS2); //plays F-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_AS3); //plays G-sharp 3
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_A4); //plays A 4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_GS3); //plays G -sharp 3
    } else if (joyy < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_A2); //plays A 2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_A3); //plays A 3
    }
  } else if (digitalRead(B_NOTE) == 1) {// if the button for B_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_C5); //plays C 5
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_AS4); //plays A-sharp 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_C3); //plays C 3
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_AS2); //plays A-sharp 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_C4); //plays C 4
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_B4); //plays B 4
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_AS3); //plays A-sharp 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_B2); //plays B 2
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_B3); //plays B 3
    }
  } else if (digitalRead(C_NOTE) == 1) { // if the button for C_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_CS5); //plays C-sharp 5
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_B4); //plays B 4
    } else if (joyx > 800 && joyy < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_CS3); //plays C-sharp 3
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_B2); //plays B 2
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_CS4); //plays C-sharp 4
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_C5); //plays C 5
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_B3); //plays B 3
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_C3); //plays C 3
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_C4); //plays C4
    }
  } else if (digitalRead(D_NOTE) == 1) { // if the button for D_Note is pressed
    if (joyx > 800 && joyy > 800) { //if joystick in upper right corner
      tone(BUZZ_PIN, NOTE_DS5); //plays D-sharp 5
    } else if (joyx < 200 && joyy > 800) { //if joystick in upper left corner
      tone(BUZZ_PIN, NOTE_CS5); //plays C-sharp 5
    } else if (joyx > 800 && joyx < 200) { //if joystick in lower right corner
      tone(BUZZ_PIN, NOTE_DS3); //plays D-sharp 3
    } else if (joyx < 200 && joyy < 200) { //if joystick in lower left corner
      tone(BUZZ_PIN, NOTE_CS3); //plays C-sharp 3
    } else if (joyx > 800) { //if joystick right
      tone(BUZZ_PIN, NOTE_DS4); //plays D-sharp 4
    } else if (joyy > 800 ) { //if joystick up
      tone(BUZZ_PIN, NOTE_D5); //plays D 5
    } else if (joyx < 200) { //if joystick left
      tone(BUZZ_PIN, NOTE_CS4); //plays C-sharp 4
    } else if (joyy < 200) { //if joystick down
      tone(BUZZ_PIN, NOTE_D3);// D 3
    } else if (joyx < 800 && joyy < 800 && joyx > 200 && joyy > 200) {//center
      tone(BUZZ_PIN, NOTE_D4);
    }
  } else { //if no buttons are pressed play nothing
    noTone(BUZZ_PIN);
  }
  if (digitalRead(SWITCH_PIN) == 1) { //if the swtich button is pressed move to case 1
    songCase = 1;
  }
}

/*Plays Zelda's Lullaby for the Legend of Zelda: Ocarina of Time*/
void ZeldasLullaby() {
  /*All of the notes in Zelda's Lullaby. Each line is a measure*/
  int zeldasLullabyNotes[] = { NOTE_B3, NOTE_D4,
                               NOTE_A3, NOTE_G3, NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A4, NOTE_G4,
                               NOTE_D4, NOTE_C4, NOTE_B3,
                               NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A3, NOTE_G3, NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A3,
                               NOTE_B3, NOTE_D4,
                               NOTE_A4, NOTE_G4,
                               NOTE_D5
                             };

 /*The length of all the notes in Zelda's Lullaby. Each line is a measure.*/
  int zeldasLullabyNlength[] = {HALF, QUARTER,
                                HALF, EIGHTH, EIGHTH,
                                HALF, QUARTER,
                                HALF_DOT,
                                HALF, QUARTER,
                                HALF, QUARTER,
                                HALF, EIGHTH, EIGHTH,
                                HALF_DOT,
                                HALF, QUARTER,
                                HALF, EIGHTH, EIGHTH,
                                HALF, QUARTER,
                                HALF_DOT,
                                HALF, QUARTER,
                                HALF, QUARTER,
                                HALF_DOT
                               };
  float pause_note = 1.3;
  for (int i = 0; i < 29; i++) {
    //plays the note i in the array for length i
    tone(BUZZ_PIN, zeldasLullabyNotes[i], zeldasLullabyNlength[i]);
    delay(pause_note * zeldasLullabyNlength[i]); //pasues for length i*pause_note
    change = digitalRead(SWITCH_PIN); //checks if the swtich button hass been pushed
    if (change == true) { //if the swtich button has been pushed
      songCase = 2; //change song case to 2
      delay(500);
      break; //break out of loop
    }
  }
}

/*Plays Saria's Song from the Legend of Zelda: Ocarina of Time.*/
void SariasSong() {
  /*All of the notes in Saria's Song. Each line is a measure*/
  int sariasSongNotes[] = {NOTE_F3, NOTE_A3, NOTE_B3,
                           NOTE_F3, NOTE_A3, NOTE_B3,
                           NOTE_F3, NOTE_A3, NOTE_B3, NOTE_E4,
                           NOTE_D4, NOTE_B3, NOTE_C4,
                           NOTE_B3, NOTE_G3, NOTE_E3, NOTE_D3,
                           NOTE_E3, NOTE_G3, NOTE_E3,
                           NOTE_F3, NOTE_A3, NOTE_B3,
                           NOTE_F3, NOTE_A3, NOTE_B3,
                           NOTE_F3, NOTE_A3, NOTE_B3, NOTE_E4,
                           NOTE_D4, NOTE_B3, NOTE_C4,
                           NOTE_E4, NOTE_B3, NOTE_G3, NOTE_B3,
                           NOTE_G3, NOTE_D3, NOTE_E3,
                           NOTE_D3, NOTE_E3, NOTE_F3,
                           NOTE_G3, NOTE_A3, NOTE_B3,
                           NOTE_C4, NOTE_B3, NOTE_E3,
                           NOTE_D3, NOTE_E3, NOTE_F3,
                           NOTE_G3, NOTE_A3, NOTE_B3,
                           NOTE_C4, NOTE_D4, NOTE_E4,
                           NOTE_D3, NOTE_E3, NOTE_F3,
                           NOTE_G3, NOTE_A3, NOTE_B3,
                           NOTE_C4, NOTE_B3, NOTE_E3,
                           NOTE_F3, NOTE_E3, NOTE_G3, NOTE_F3, NOTE_A3, NOTE_G3, NOTE_B3, NOTE_A3,
                           NOTE_C4, NOTE_B3, NOTE_D4, NOTE_C4, NOTE_E4, NOTE_D4,
                           NOTE_B3, NOTE_C4, NOTE_A3,
                           NOTE_B3
                          };/*The length of all the notes in Saria's Song. Each line is a measure*/
  int sariasSongNlength[] = {EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, EIGHTH, EIGHTH,
                             QUARTER, EIGHTH, EIGHTH,
                             EIGHTH, EIGHTH, QUARTER + QUARTER_DOT, EIGHTH,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, EIGHTH, EIGHTH,
                             QUARTER, EIGHTH, EIGHTH,
                             EIGHTH, EIGHTH, QUARTER + QUARTER_DOT, EIGHTH,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, QUARTER,
                             EIGHTH, EIGHTH, HALF_DOT,
                             EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH,
                             EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH, EIGHTH,
                             (EIGHTH * (2 / 3)), (EIGHTH * (2 / 3)), (EIGHTH * (2 / 3)),
                             WHOLE
                            };
  float pause_note = 1.5;
  for (int i = 0; i < 85; i++) {
    tone(BUZZ_PIN, sariasSongNotes[i], sariasSongNlength[i]);//plays note i at length i fr Saria's Song
    delay(pause_note * sariasSongNlength[i]);  //pauses for length i *pause_note
    change = digitalRead(SWITCH_PIN); //check the switch button
    if (change == true) {
      songCase = 3; //if button is pressed change to case 3
      delay(500);
      break;
    }
  }
}

/*Plays the Song of Storms from Legend of Zelda: Ocarian of Time*/
void SongOfStorms() {
  /*All of the notes in Song of Storms. Each line is a measure*/
  int songOfStormsNotes[] = {NOTE_D3, NOTE_A3, NOTE_D4,
                             NOTE_D3, NOTE_A3, NOTE_D4,
                             NOTE_E4, NOTE_F4, NOTE_E4, NOTE_F4,
                             NOTE_E4, NOTE_C4, NOTE_A3,
                             NOTE_A3, NOTE_D3, NOTE_F3, NOTE_G3,
                             NOTE_A3,
                             NOTE_A3, NOTE_D3, NOTE_F3, NOTE_G3,
                             NOTE_E3
                            };
  /*The length of all the notes in Song of Storms. Each line is a measure*/
  int songOfStormsNlength[] = {EIGHTH, EIGHTH, HALF,
                               EIGHTH, EIGHTH, HALF,
                               QUARTER_DOT, EIGHTH, EIGHTH, EIGHTH,
                               EIGHTH, EIGHTH, HALF,
                               QUARTER, QUARTER, EIGHTH, EIGHTH,
                               HALF_DOT,
                               QUARTER, QUARTER, EIGHTH, EIGHTH,
                               HALF_DOT
                              };
  float pause_note = 1.2;
  for (int i = 0; i < 23; i++) {
    //plays note i of Song of Storms for length i
    tone(BUZZ_PIN, songOfStormsNotes[i], songOfStormsNlength[i]);
    delay(pause_note * songOfStormsNlength[i]); //pauses for length i *pause_note
    change = digitalRead(SWITCH_PIN); //checks if swtich button has been pushed
    if (change == true) { //if the switch button was pushed
      songCase = 0; //go back to case 0
      delay(500);
      break; //breaks out of for loop
    }
  }
}

With that we wrap up our code. Next comes connecting our hardware and putting it in the case.

Step 7: The Circuit

Above you can see a basic reprenting the basic circuit. You have 8 buttons: one for each of the notes A-G and one for the switch button. You also have a joystick and a speaker. In an earlier step, I described what each of these components does. Now, I will describe how to connect them into a working Ocarina.

The buttons themselves are going to be connected to digital pins 2-9 on your Arduino Uno. Note that if you are using a different type of Arduino, you will most likely need to use different pins and reassign them in your code. Each button is connect to 5V and ground. The pin going to ground needs to have a 10kOhm resistor between the pin and the actual ground. You attach a wire leading to the digital pin on the Arduino to the same pin that you attached to ground.

The seven note buttons all function as simple on off switches. When the button is pushed current is allowed to flow and the note plays. The switch button has the same mechanical properties, but functions as a very simple state machine due to the code. A state machine changes conditions if a certain criteria is met, going from one state to the next depending on the input. In this case, the button is the input, and it changes the state cyclically each time it is pressed.

The speaker has an extremely simple setup. The black lead is connected to ground, while the red lead is connected to digital pin 13. You may notice that digital pin 13 is not a pulse width modulation pin. This is because the speaker does not depend on how long the voltage is high in a duty cycle, but rather the frequency at which that voltage changes and the speed of the duty cycles themselves.

The joystick is slightly more complicated than the speaker or the buttons, but still very simple. The pins labeled Vin and GND are connected to 5V and ground respectively. If your joystick is able to "click" like mine does, it will have a SW pin. This will be connected to digital pin 10 and acts very much like a button. The last two pins are usually labeled Vx and Vy or something similar. These will be on all joysticks (that I know of). You can connect them to A0 and A1 respectively if you wish for them to correspond with the code. These will read the position of your joystick on your x and y axis. You may want to create a program to test the position of the x and y axes. Some joysticks may come with their x and y pins switched like mine did, so confirming these values correspond to what they should be is a good idea.

Step 8: Putting It All Together.

The last thing we need to do is physically put together out hardware. Most ocarina cases will be small and the a large breadboard isn't a good idea. Depending on the case, getting everything to fit right will be a challenge. To help with this, we need to make sure the circuit is condensed.

One way to do this is to use a breadboard that fits on top of the Arduino. There are plenty of breadboards like this and they usually come with Arduino kits. Since our hardware has a lot of buttons (that need connections to both 5V and GND) you're going to have to connect multiple rows to 5V and ground. To get the buttons to the holes in the ocarina, I used several male to female jumper wires. How you wire things up is going to depend on you're case and breadboard. The most important thing is to make sure everything works each time you wire something. There's nothing worse that putting everything together and then have nothing work... trust me.

And that's it! I hope you enjoyed this tutorial. Make sure to ask questions and let me know if anything doesn't make sense!

Fandom Contest

Participated in the
Fandom Contest

Share

    Recommendations

    • DIY Summer Camp Contest

      DIY Summer Camp Contest
    • Classroom Science Contest

      Classroom Science Contest
    • Sensors Contest

      Sensors Contest

    Discussions

    1
    None
    seamster

    23 days ago

    Very cool. Thank you for sharing the process!