Best birthday card ever!

Description:

For this lab, I decided to make the best birthday card ever. For those who just can’t get enough of having people sing them Happy Birthday (or those who like to celebrate for an entire month—long after their friends have grown tired of singing Happy Birthday to them), this birthday card is for them. Every time the special birthday lady or gentleman opens the card, it plays them Happy Birthday. It uses a photocell to determine when the card is opened, and I used a modified notebook to stand in for the card because I don’t actually have any birthday cards lying around, sadly. Thankfully for those in the same room, the card will stop playing the melody, but will start again from the beginning once opened again.

Components:

  • Arduino Uno
  • Breadboard
  • 1 10kΩ resistor
  • 1 photocell
  • 1 piezo speaker
  • jumper cables
  • birthday card

img_1228

img_1229

Code:

// TUI Lab 05 - Molly
// Happy birthday melody sourced from http://forum.arduino.cc/index.php?topic=178460.0

int speakerPin = 9;
int photoPin = A1;
int length = 28; // the number of notes
char notes[] = "GGAGcB GGAGdc GGxecBA yyecdc";
int beats[] = { 2, 2, 8, 8, 8, 16, 1, 2, 2, 8, 8,8, 16, 1, 2,2,8,8,8,8,16, 1,2,2,8,8,8,16 };
int tempo = 150;
int val = 0;

void playTone(int tone, int duration) {
for (long i = 0; i < duration * 1000L; i += tone * 2) {
digitalWrite(speakerPin, HIGH);
delayMicroseconds(tone);
digitalWrite(speakerPin, LOW);
delayMicroseconds(tone);
}
}

void playNote(char note, int duration) {
char names[] = {'C', 'D', 'E', 'F', 'G', 'A', 'B',
'c', 'd', 'e', 'f', 'g', 'a', 'b',
'x', 'y' };

int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014,
956, 834, 765, 593, 468, 346, 224,
655 , 715 };
int SPEE = 5;

// play the tone corresponding to the note name
for (int i = 0; i < 17; i++) {
if (names[i] == note) {
int newduration = duration/SPEE;
playTone(tones[i], newduration);
}
}
}

void setup() {
pinMode(speakerPin, OUTPUT);
Serial.begin(9600);
}

void loop() {
Serial.print("Value:");
Serial.print(analogRead(photoPin));
while (analogRead(photoPin) > 200) {
for (int i = 0; i < length; i++) {
if (notes[i] == ' ' and analogRead(photoPin) < 200) {
delay(beats[i] * tempo); // rest
}
else if (analogRead(photoPin) < 200) {
playNote(notes[i], beats[i] * tempo);
}
else break;
// pause between notes
delay(tempo);
}
}
}

Leave a Reply