Bacon Alarm Clock

If you know me at all, you know that I have trouble waking up in the morning. There is an episode of The Office where Michael burns his foot on a George Foreman grill because he makes bacon next to his bed in the morning so that he can wake up to the smell of bacon.

I always thought that this was an awesome idea and wanted to make my own version of it. So I did, and I’ll show you what I did.

The Idea

Create a Bacon Alarm Clock. One that would allow me to set it up before I go to bed and then at a specified time in the morning, make bacon for me.

The Hardware

I went to Wal-Mart to look for a suitable grill for this and came across this George Foreman grill. http://www.georgeforemancooking.com/products/classic-plate-grills/gr0038w-champ-grill-white-grill-small-grill-grilling-healthy.aspx This is a 120 V, 760 Watt grill and will fit 4 half strips of bacon. Since W = V * A, the grill uses 6.33 amps of current.

I needed a microcontroller to act as the brains to turn the grill on and off. Since I had recently purchased my first Arduino (an Arduino Uno), I decided to make this my first Arduino project. http://arduino.cc/en/Main/ArduinoBoardUno

Since the Arduino cannot supply nearly enough power to control the grill, it is necessary to have the Arduino control a relay that can handle the current for the grill. I was able to get my hands on two “Opto 22” 240 V, 5 amp solid state relays with 3-32 VDC control. Since the grill I am using draws 6.33 amps, I wired the relays in parallel to allow me to control up to 10 amps of power. However, now that I think about it, since I am in the USA, our power outlets run at 120 VAC, not 240 VAC. I wonder if running these relays at a lower voltage would give them a higher amperage rating…probably not, but just a thought.

I didn’t want to manually set the time on the Arduino each time that I turned it on. Fort this, I decided to also use a Real Time Clock(RTC) Module in the design. This module is able to keep track of time even if the power to the Arduino is cut because it has it’s own button cell battery power source. The Arduino can automatically get the time from the RTC. https://www.sparkfun.com/products/99

Improvements

The code right now does not automatically detect daylight savings time. That shouldn’t really be too hard to implement. (I was just too lazy to figure out the algorithm)

Right now, in order to change the time and duration of the alarm, you have to go in and change the source code, recompile, and reload the Arduino. It would be nice to have a small LCD screen with some buttons that could display the current time and be able to set the alarm clock.

Block Diagram

Bacon Alarm Block Diagram

Source Code

Here is the code for the Arduino. I’ll leave it to you to look up the libraries that I used.

/*
 * BaconAlarm.ino
 * Author: Jeremy Butler
 *
 * This code allows allows you to set a time to turn on one of the I/O pins
 * of the Arduino. You can also control the duration that pins should stay on.
 */

#include <Time.h>
#include <TimeAlarms.h>
#include <Wire.h>
#include <DS1307RTC.h>  // a basic DS1307 library that returns time as a time_t

#define ALARM_HOUR 7      //Hour of the alarm
#define ALARM_MINUTE 55   //Minute of the alarm
#define COOK_TIME 300     //How long to cook the bacon in seconds
#define ALARM_PIN 13      //The pin that will control the grill relay.

const static time_t DST = -21600; //-7(-6 in summer)*60*60

time_t sync(){
  return RTC.get() + DST;
}

void setup()  {
  Serial.begin(9600);
  setSyncProvider(sync);   // the function to get the time from the RTC
  if(timeStatus()!= timeSet)
     Serial.println("Unable to sync with the RTC");
  else
     Serial.println("RTC has set the system time");

  Alarm.alarmRepeat(ALARM_HOUR,ALARM_MINUTE,0,makeBacon); //Adjust this line to the time that you want to make your bacon
  Serial.println("Alarm Set");
  pinMode(13, OUTPUT);
}

void loop()
{
  if(Serial.available())
  {
     time_t t = processSyncMessage();
     if(t >0)
     {
        RTC.set(t);   // set the RTC and the system time to the received value
        setTime(t);
     }
  }
   digitalClockDisplay();
   Alarm.delay(1000);
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year());
  Serial.println();
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

/*  code to process time sync messages from the serial port   */
#define TIME_MSG_LEN  11   // time sync to PC is HEADER followed by unix time_t as ten ascii digits
#define TIME_HEADER  'T'   // Header tag for serial time sync message

time_t processSyncMessage() {
  // return the time if a valid sync message is received on the serial port.
  while(Serial.available() >=  TIME_MSG_LEN ){  // time message consists of a header and ten ascii digits
    char c = Serial.read() ;
    Serial.print(c);
    if( c == TIME_HEADER ) {
      time_t pctime = 0;
      for(int i=0; i < TIME_MSG_LEN -1; i++){
        c = Serial.read();
        if( c >= '0' && c <= '9'){
          pctime = (10 * pctime) + (c - '0') ; // convert digits to a number
        }
      }
      return pctime;
    }
  }
  return 0;
}

void makeBacon(){
  Serial.println("Making Bacon! Nom Nom Nom");
  digitalWrite(ALARM_PIN,HIGH);
  Alarm.timerOnce(COOK_TIME, stopMakingBacon);
}

void stopMakingBacon(){
  Serial.println("Your bacon is done! Woot!!!!");
  digitalWrite(ALARM_PIN,LOW);
}