Ingredients:
Speaker (this one was taken from an old alarm clock)
LEDs
optional- distance or motion sensor
There are two sets of LEDs that alternate every time a note is played. They are on pwm pins so they fade up and down with each note.
I cut out a wooden Christmas tree using a jigsaw and drilled a hole on the side for the speaker to fit into. I then drilled holes for the LEDs.
There is a playlist of 7 Christmas songs, it will start on a random one at startup, then continue with the playlist.
Before I give it away as a present I think I will attach a distance sensor so that it will be motion activated. To code for that I would put each song inside an 'if statement' and check the distance sensor.
//Modified RTTTL Example for Christmas
// Speaker on pin 11
//one set of LEDs on 10
//another set of LEDs on 9
// To mix the output of the signals to output to a small speaker (i.e. 8 Ohms or higher),
// simply use 1K Ohm resistors from each output pin and tie them together at the speaker.
// Don't forget to connect the other side of the speaker to ground!
// You can get more RTTTL (RingTone Text Transfer Language) songs from
// http://code.google.com/p/rogue-code/wiki/ToneLibraryDocumentation
#include <Tone.h>
Tone tone1;
#define OCTAVE_OFFSET 0
float value;
long var;
int notes[] = { 0,
NOTE_C4, NOTE_CS4, NOTE_D4, NOTE_DS4, NOTE_E4, NOTE_F4, NOTE_FS4, NOTE_G4, NOTE_GS4, NOTE_A4, NOTE_AS4, NOTE_B4,
NOTE_C5, NOTE_CS5, NOTE_D5, NOTE_DS5, NOTE_E5, NOTE_F5, NOTE_FS5, NOTE_G5, NOTE_GS5, NOTE_A5, NOTE_AS5, NOTE_B5,
NOTE_C6, NOTE_CS6, NOTE_D6, NOTE_DS6, NOTE_E6, NOTE_F6, NOTE_FS6, NOTE_G6, NOTE_GS6, NOTE_A6, NOTE_AS6, NOTE_B6,
NOTE_C7, NOTE_CS7, NOTE_D7, NOTE_DS7, NOTE_E7, NOTE_F7, NOTE_FS7, NOTE_G7, NOTE_GS7, NOTE_A7, NOTE_AS7, NOTE_B7
};
int pin=9;
int pin2=10;
int playpin;
void setup(void)
{
Serial.begin(9600);
tone1.begin(11);
pinMode(pin,OUTPUT);
pinMode(pin2,OUTPUT);
//var=1;
randomSeed(analogRead(0));
var=random(2,8);
}
#define isdigit(n) (n >= '0' && n <= '9')
void play_rtttl(char *p) //$$$$$$$$$$
{
// Absolutely no error checking in here
byte default_dur = 4;
byte default_oct = 6;
int bpm = 63;
int num;
long wholenote;
long duration;
byte note;
byte scale;
// format: d=N,o=N,b=NNN:
// find the start (skip name, etc)
while(*p != ':') p++; // ignore name
p++; // skip ':'
// get default duration
if(*p == 'd')
{
p++; p++; // skip "d="
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
if(num > 0) default_dur = num;
p++; // skip comma
}
Serial.print("ddur: "); Serial.println(default_dur, 10);
// get default octave
if(*p == 'o')
{
p++; p++; // skip "o="
num = *p++ - '0';
if(num >= 3 && num <=7) default_oct = num;
p++; // skip comma
}
Serial.print("doct: "); Serial.println(default_oct, 10);
// get BPM
if(*p == 'b')
{
p++; p++; // skip "b="
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
bpm = num;
p++; // skip colon
}
Serial.print("bpm: "); Serial.println(bpm, 10);
// BPM usually expresses the number of quarter notes per minute
wholenote = (60 * 1000L / bpm) * 4; // this is the time for whole note (in milliseconds)
Serial.print("wn: "); Serial.println(wholenote, 10);
// now begin note loop
while(*p)
{
// first, get note duration, if available
num = 0;
while(isdigit(*p))
{
num = (num * 10) + (*p++ - '0');
}
if(num) duration = wholenote / num;
else duration = wholenote / default_dur; // we will need to check if we are a dotted note after
// now get the note
note = 0;
switch(*p)
{
case 'c':
note = 1;
break;
case 'd':
note = 3;
break;
case 'e':
note = 5;
break;
case 'f':
note = 6;
break;
case 'g':
note = 8;
break;
case 'a':
note = 10;
break;
case 'b':
note = 12;
break;
case 'p':
default:
note = 0;
}
p++;
// now, get optional '#' sharp
if(*p == '#')
{
note++;
p++;
}
// now, get optional '.' dotted note
if(*p == '.')
{
duration += duration/2;
p++;
}
// now, get scale
if(isdigit(*p))
{
scale = *p - '0';
p++;
}
else
{
scale = default_oct;
}
scale += OCTAVE_OFFSET;
if(*p == ',')
p++; // skip comma for next note (or we may be at the end)
// now play the note $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$
if(note)
{
Serial.print("Playing: ");
Serial.print(scale, 10); Serial.print(' ');
Serial.print(note, 10); Serial.print(" (");
Serial.print(notes[(scale - 4) * 12 + note], 10);
Serial.print(") ");
Serial.println(duration, 10);
tone1.play(notes[(scale - 4) * 12 + note]);
// delay(duration);
//THIS TURNS THE LED ON---------------
value=duration;
if(playpin==9){ //THIS SWITCHES BETWEEN PINS 9 AND 10
playpin=10;
} else{
playpin=9;
}
Serial.print("the value is");
Serial.println(value);
for(int i=25;i<255;i+=10){
analogWrite(playpin,i);
delay(value/60);
}
for(int i=255;i>0;i-=10){
analogWrite(playpin,i);
delay(value/60);
digitalWrite(playpin,LOW);
}
//END THE FADING ---------------------------------------
tone1.stop();
}
else
{
Serial.print("Pausing: ");
Serial.println(duration, 10);
delay(duration);
}
}
}
void loop(void)
{
if(var!=1){
var=random(1,8);
}
if(var==1){
char *song1 = "WeWishYou:d=4,o=5,b=200:d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,2g,d,g,8g,8a,8g,8f#,e,e,e,a,8a,8b,8a,8g,f#,d,d,b,8b,8c6,8b,8a,g,e,d,e,a,f#,1g,d,g,g,g,2f#,f#,g,f#,e,2d,a,b,8a,8a,8g,8g,d6,d,d,e,a,f#,2g";
play_rtttl(song1);
delay(1000);
var++;
}
if (var==2){
char *song2 = "CarolBells:d=8,o=5,b=180:4a,g#,a,4f#,4a,g#,a,4f#,4f#6,f#6,f#6,e6,d6,4c#6,c#6,c#6,b,a,4b,b,b,c#6,b,4f#,f#,f#,4f#,c#,d#,e,f#,g#,a,b,c#6,4b,4a,c#,d#,e,f#,g#,a,b,c#6,4b,4a,4a,g#,a,4f#,4a,g#,a,4f#";
play_rtttl(song2);
delay(1000);
var++;
}
if(var==3){
char *song3 = "Greensleeves:d=4,o=5,b=140:32p,g,2a#,c6,d.6,8d#6,d6,2c6,a,f.,8g,a,2a#,g,g.,8f,g,2a,f,2d,g,2a#,c6,d.6,8e6,d6,2c6,a,f.,8g,a,a#.,8a,g,f#.,8e,f#,2g";
play_rtttl(song3);
var++;
delay(1000);
}
if(var==4){
char *song4 = "JoyWorld:d=4,o=5,b=112:d6,8c#.6,16b,a.,8g,f#,e,d,8p,8a,b,8p,8b,c#6,8p,8c#6,2d.6,8p,8d6,8d6,8c#6,8b,8a,8a.,16g,8f#,8d6,8d6,8c#6,8b,8a,8a.,16g,8f#,8f#,8f#,8f#,8f#,16f#,16g,a.,16g,16f#,8e,8e,8e,16e,16f#,g,8p,16f#,16e,8d,8d6,8p,8b,8a.,16g,8f#,8g,f#,e,2d";
play_rtttl(song4);
var++;
delay(1000);
}
if(var==5){
char *song5 = "Rudolph:d=16,o=6,b=100:32p,g#5,8a#5,g#5,8f5,8c#,8a#5,4g#.5,g#5,a#5,g#5,a#5,8g#5,8c#,2c,f#5,8g#5,f#5,8d#5,8c,8a#5,4g#.5,g#5,a#5,g#5,a#5,8g#5,8a#5,2f5,g#5,8a#5,a#5,8f5,8c#,8a#5,4g#.5,g#5,a#5,g#5,a#5,8g#5,8c#,2c,f#5,8g#5,f#5,8d#5,8c,8a#5,4g#.5,g#5,a#5,g#5,a#5,8g#5,8d#,2c#";
play_rtttl(song5);
var++;
delay(1000);
}
if(var==6){
char *song6 = "feliz:d=8,o=5,b=140:a,4d6,c#6,d6,2b.,4p,b,4e6,d6,b,2a.,4p,a,4d6,c#6,d6,4b.,g,4b,4b,a,a,b,a,4g,g,1f#";
play_rtttl(song6);
var++;
delay(1000);
}
if(var==7){
char *song7 = "LetItSnow:d=8,o=5,b=125:c,c,c6,c6,4a#,4a,4g,4f,2c,c,c,4g.,f,4g.,f,4e,2c,4d,d6,d6,4c6,4a#,4a,2g.,e.6,16d6,4c6,c.6,16a#,4a,a#.,16a,2f.";
play_rtttl(song7);
delay(1000);
var=1;
}
}