//notes used in the Zelda's Lulliby melody #define NOTE_B4 494 #define NOTE_D5 587 #define NOTE_A4 440 #define NOTE_G4 392 #define NOTE_A5 880 #define NOTE_G5 784 #define NOTE_C5 523 boolean AlarmOn; //true if alarm is on, else false boolean LightOn; //true if light switch has been flipped on, else false int AlarmTimer; //keeps track of amount of seconds elapsed since the alarm went off int AlarmThreshold; //amount of time in minutes to wait between when the alarm goes off and when the speaker should be kicked on const int SPEAKERPIN = 9; //pin connected to the speaker const int ALARMPIN = 0; //pin connected to the line on the +v speaker line of the alarm to detect if it's going off or not. const int LIGHTPIN =10; //pin conected to relay that controls the lamp // notes in the Zelda's Lulliby melody: int melody[] = { NOTE_B4, NOTE_D5, NOTE_A4, NOTE_G4, NOTE_A4, NOTE_B4, NOTE_D5, NOTE_A4, NOTE_B4, NOTE_D5, NOTE_A5, NOTE_G5, NOTE_D5, NOTE_C5, NOTE_B4, NOTE_A4,}; // note durations for the tune: 4 = quarter note, 8 = eighth note, etc.: int noteDurations[] = { 2, 4, 2, 8,8,2,4,2,2,4,2,4,2,8,8,2 }; void setup() { AlarmTimer = 0; AlarmOn = true; AlarmThreshold = 15; //setting the threshold at 15 minutes to turn the speaker on if the light didn't wake you up by this point LightOn = false; pinMode(SPEAKERPIN, OUTPUT); pinMode(ALARMPIN, INPUT); pinMode(LIGHTPIN, OUTPUT); } void loop() { AlarmOn = GetAlarmState(ALARMPIN); if(AlarmOn) ProcessAlarmOn(); else ProcessAlarmOff(); delay(1000); } //returns true if the alarm is on or false if not //_alarmpin is the pin on the microcontroller that the alarm speaker wire is hooked to boolean GetAlarmState(int _alarmpin) { int _alarmState = analogRead(_alarmpin); //stores the raw voltage value read from the speaker pin on the alarm if(_alarmState > 0) //if it's reading a voltage on the line return true; else { //because the alarm beeps intermittently, look for a voltage on the line for about 2 seconds for(int i = 0; i < 20; i++) { delay(100); _alarmState = analogRead(_alarmpin); if(_alarmState > 0)//if a voltage is detected return true; } } return false; //no voltage found, alarm is off } //turns the light on and keeps track of how long the alarm has been on for and whether it needs to turn on the speaker as well or not, depending on how long the alarm has been on for. void ProcessAlarmOn() { TurnLightOn(); AlarmTimer++; if(AlarmTimer > (AlarmThreshold * 60)) TurnSpeakerOn(); else TurnSpeakerOff(); } //turns the light and the speaker off and resets the timer that keeps track of how long the alarm was on for. void ProcessAlarmOff() { TurnLightOff(); TurnSpeakerOff(); AlarmTimer = 0; } void TurnLightOn() { digitalWrite(LIGHTPIN, HIGH); } void TurnLightOff() { digitalWrite(LIGHTPIN, LOW); } //function plays a melody on the alarm speaker, in this case, Zelda's Lulliby void TurnSpeakerOn() { for (int thisNote = 0; thisNote < 16; thisNote++) { // to calculate the note duration, take one second // divided by the note type. //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc. int noteDuration = 1000/noteDurations[thisNote]; tone(SPEAKERPIN, melody[thisNote],noteDuration); // to distinguish the notes, set a minimum time between them. // the note's duration + 30% seems to work well: int pauseBetweenNotes = noteDuration * 1.30; delay(pauseBetweenNotes); // stop the tone playing: noTone(SPEAKERPIN); } } void TurnSpeakerOff() { digitalWrite(SPEAKERPIN, LOW); }