joannehadley4
Published © GPL3+

Musical Treasure Box

Play a custom tune when your treasure box is opened to warn you someone may be trying to thieve your stuff!

IntermediateFull instructions provided4,003
Musical Treasure Box

Things used in this project

Hardware components

Arduino UNO
Arduino UNO
×1
SparkFun Trim Potentiometer
×1
Buzzer, Piezo
Buzzer, Piezo
×1
SparkFun Mini breadboard
×1
LDR, 5 Mohm
LDR, 5 Mohm
×1
Resistor 10k ohm
Resistor 10k ohm
×1
Jumper wires (generic)
Jumper wires (generic)
Male/male wires. If your piezo speaker has no wires you'll need 10 of these.
×6
Male/Female Jumper Wires
Male/Female Jumper Wires
For the LDR.
×2
I used an old Tjena box but any box will do
×1
ESD Tape, Masking
ESD Tape, Masking
×1

Software apps and online services

Arduino IDE
Arduino IDE

Story

Read more

Schematics

Musical Treasure Box Circuit

This circuit has an LDR to sense the light level in the environment and a buzzer to play a tune. The potentiometer is included to encourage others to consider doing an extension of the project but is not used in this project. It can be left out if desired by removing the potentiometer and the three wires connected to it.

Code

LightSensingBuzzer

Arduino
Firstly, take a look at the section of code from about lines 30 through to 59. This section determines what tune will be played and at what speed (via tempo value). The current tune has a total of 19 notes and rests. This is the value of songLength (line 31). You must edit this value to match the number of notes/rests in your tune.

Edit the song length on line 29 to reflect the number of notes in your song. Include all the notes and rests in the count. Follow the commented instructions in the code when editing the notes and the beats array. You'll need some understanding of how musical compositions work to code your own tune. You can expect to spend some time getting the timing of the notes correct.

Speed up or slow down the tune by changing the Tempo value on line 29.
/******************************************************************
 * SparkFun Inventor"s Kit
 * Example sketch 11
 * 
 * BUZZER
 * with lots of help from the Arduino community,
 * and amended by J. Hadley to include an extra octave and semitones.
 * Further amended August 2020 to allow the playing of a song to be
 * interrupted by a sensor input. When the sensor value meets the
 * condition, the song will cease playing.
 * 
 * This sketch uses the buzzer to play songs.
 * The Arduino"s tone() command will play notes of a given frequency.
 * 
 * This sketch was written by SparkFun Electronics,
 * (This sketch was originally developed by D. Cuartielles for K3)
 * This code is completely free for any use.
 * Visit http://learn.sparkfun.com/products/2 for SIK information.
 * Visit http://www.arduino.cc to learn about the Arduino.
 * 
 * Version 2.0 6/2012 MDG
 * Version 2.1 9/2014 BCH
 *****************************************************************/


const int SensorPin = A4;   // switch to use a different analog sensor
int sensorThreshold = 500;  // what sensor value will stop the song
const int buzzerPin = 3;    // connect the buzzer to pin 3 (Thinkershield buzzer pin)
int tempo = 270;            // The tempo is how fast to play the song (beats per minute).
const int songLength = 19;  // sets the number of notes of the song

// Notes is an array of text characters corresponding to the notes
// in your song. A space represents a rest (no tone). Each note or rest must be separated by a comma
// with no comma after the last note.

// It"s important that you use single quotes for single letters like "b", "g" and the rest ' ', and
// that you use double quotes for notes requiring multiple letters like "g2" (which is the g in the octave above)
// and "f#" (which is the sharp - a semitone above "f") in the lower octave. Your code may compile if these are
// incorrect but those notes will not play. It is a quirky part of the Arduino coding language in this IDE.
// In Tinkercad, it works differently and all notes should be enclosed in double quotes.

char* notes[songLength] = {
  ' ', 
  "f#", "g#", 'b', 'b', ' ', 
  "d2#", "f2#", "g2#", "g2#", ' ', 
  "g2#", "f2#", "f2#", "e2", ' ', 
  "e2", "d2#", "d2#"}; 

// beats[] is an array of values for each note. A "1" represents a quarter-note, 
// "2" a half-note, and "4" a full-note.
// Don"t forget that the rests (spaces) need a length as well.

int beats[songLength] = {
  2, 
  1, 1, 2, 3, 2, 
  1, 1, 2, 3, 2, 
  1.5, 0.5, 1, 3.5, 2, 
  1.5, 1, 3.5};

void setup() 
{
  pinMode(buzzerPin, OUTPUT);  // sets the  buzzer pin as an OUTPUT
  pinMode(SensorPin, INPUT);
  //Serial.begin(9600);
}

void loop() 
{
  int i, duration; 
  bool keepPlaying = true;
  int value;
  
  i=0;
  value = analogRead(SensorPin);
  //Serial.println(value);
  keepPlaying = (value > sensorThreshold);
  
  while ((i < songLength) && keepPlaying)
  {
    //Serial.println("playing");
    duration = beats[i] * tempo;  // length of note/rest in ms

    if (notes[i] == ' '){          // is this a rest? 
      delay(duration);            // then pause for a moment
      //Serial.println("pause");
    }
    else                          // otherwise, play the note
    {
      tone(buzzerPin, frequency(notes[i]), duration);
      delay(duration);            // wait for tone to finish
      //Serial.println("note is " + String(notes[i]));
    }

    delay(tempo/20);              // brief pause between notes
    value = analogRead(SensorPin);
    keepPlaying = (value > sensorThreshold);
    //Serial.println(value);
    i = i+1;  
  }

  //while(true){
  // We only want to play the song once, so we pause forever
  //}
  
  /* If you'd like your song to play once only, uncomment the 3 lines that make up the 
     while(true)statement above. When commented out, the song will play repeatedly. */
}

//-------------------------------------------------------------------------------------------------------------------------
int frequency(char* note) 
{
  int i;
  const int numNotes = 25;  // number of notes we"re storing - includes the semitones over 2 octaves starting at middle C
  char* names[numNotes] = { 
    'c', "c#", 'd', "d#",'e', 'f', "f#", 'g', "g#", 'a', "a#", 'b', "c2", "c2#", "d2", "d2#", "e2", "f2", "f2#", "g2", "g2#", "a2", "a2#", "b2", "c3"    };
  int frequencies[numNotes] = {
    262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494, 523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988, 1047    };

  // Now we"ll search through the letters in the array, and if
  // we find it, we"ll return the frequency for that note.

  for (i = 0; i < numNotes; i++)  // Step through the notes
  {
    if (names[i] == note)         // Is this the one?
    {
      return(frequencies[i]);     // Yes! Return the frequency and exit function.
    }
  }
  return(0);  // We looked through everything and didn't find it,
  // but we still need to return a value, so return 0.
}

Credits

joannehadley4

joannehadley4

3 projects • 0 followers

Comments