January 1, 2010

Alarm Clock Overkill


I don't get up at the same time every day, so I thought it'd be nice to have an alarm clock that would drag me out of bed at different times on different days. That was the initial idea: things got out of hand, of course, and this is the result.

What it does:
1) It displays the time, day, and date. It also keeps track of the year, leap years, and adjusts automatically for daylight savings time.
2) It displays the temperature.
3) It has seven independent alarms, each of which can be set for different days of the week. For example, one alarm can go off at 5am on Tuesday, Wednesday, and Friday while another can go at 6am Monday and Thursday and a third can allow me to sleep until 7 on weekends.
4) In the event of power failure, the clock keeps time anyway. The alarms and display don't work when the power's off of course, but when power comes back on the time will be correct and it remembers the alarm settings.
5) It announces special events. Today is New Year's Day, so the bottom line of the display alternates between day/date (shown above) and the message shown below.

There are over 150 of these special events programmed into the clock, including family birthdays, oddball holidays (Squirrel Appreciation Day, anyone?) and so on. On my kids' birthdays it even tells me the age of the kid. (A useful bit of information that sometimes escapes the geek mind, as you probably have noticed —or forgotten— already.)

How it does it:

The brains of the unit are supplied by an ATMega328 Boarduino  (Arduino clone). This keeps the display up to date, turns alarms on and off, and runs the user interface. It also stores and displays the various special events for the year.

Accurate timekeeping is provided by a DS1307 real-time-clock chip. This chip also has 56 bytes of spare EEPROM which I use to store the alarm information in the event of power loss. Communication with the microcontroller is via I2C bus.

The alarm beeper itself is a simple piezo buzzer from Radio Shack, driven off the 9V supply line with a 3904 NPN transistor. The Boarduino can make the buzzer sound without the help of the transistor, but the goal is to not just sound the buzzer but get me out of bed!

Temperature sensing is via an LM35 temperature-sensitive zener diode. This is a great little component! Put in 5V, and the signal line puts out 10mV/°C. It's that easy. I use these, or the similar LM335, in my physics lab quite often.

User input is via a pushbutton/quadrature knob. The user presses the knob to select an action or set a number, and turns the knob to dial in the option of his choosing. Much better than the usual 4-button combination on the top of most alarm clocks.

Here's a cut-down version of the code. I trimmed the getMessage() function in this sample code to just show an example of how the "special events" code works — you'll have to put in the special events of your own choosing. (Or you can email me and I'll send the uncut version.)

Notes about the hardware:
1) The 2x16 character LCD uses the standard Hitachi HD44780 driver and the LiquidCrystal.h library. With some modification you could make it work with other LCDs, although this code is optimized for 16-character lines.
2) I put 0.1µF caps to ground on each of the three switch lines on the rotary switch, in addition to the usual 10k pull-up resistors. This combination nicely debounces the quadrature signal.
3) The DS1307 clock chip requires 3V on the "battery backup" line. It will not work without this.
4) I soldered the crystal directly to the DS1307 chip to minimize any clock error due to crappy breadboard connections.
5) As written, the code requires an ATMega328 or larger microcontroller. The "stock" ATMega168 does not have enough memory to run this program unless you get rid of the alarms or most of the daily specials.

Next:
It needs an appropriate case of some kind. I'm planning to etch a small batch of boards for these, driven with bare ATMega328's instead of the Boarduino I used for this prototype, and I'm thinking some sort of retro-steampunk case. I'll post pictures when it's done.

Want to build one yourself?
Download the code here. The hardware is very straightforward, here's an electrical diagram. I don't recommend this as a first Arduino project, though!



6 comments:

  1. Looks great!

    Did you just pole the timer IC from the Arduino? I hear getting a reliable human-clock from the Arduino is a bit fiddly.

    Look forward to seeing the enclosure too.
    ReplyDelete
  2. I have been looking for something like this to help my mother (who has Alzheimers) keep track of the day and what she needs to do that day.
    ReplyDelete
  3. Great project.
    To eliminate the case when the alarm is not triggered because of a power failure, you can use batteries.
    Since the consumption is not more than 100mA, you should be able to power it from batteries (4xAA rechargeables, at 2800mAh, which would provide about a month of power).

    I made a similar (based on DS1307) clock, check it out here:
    http://timewitharduino.blogspot.com/
    ReplyDelete
  4. Nice clock. It's a little more feature complete than any of the ones I've built as of late, though using the same chip.
    A few notes though: The DS1307 doesn't have any EEPROM in it. It has 56 bytes of SRAM, not EEPROM, so it still depends on the battery backup. The ATMega has plenty of EEPROM, if you want to not even depend on the batttery. The DS1307 also doesn't require 3V. I've used it with Vbat tied to ground for plenty of things. The problem is that if you leave it floating, it will drift all over the place and disable the I2C interface, since Vcc MUST be 1.25 times Vbat.
    ReplyDelete
  5. Just need to add a radio reciever to it so it syncs itself to the atomic clocks...
    ReplyDelete
  6. In the drawing you have the sda connection from the 1307 to the scl arduino, and the scl to the sda. Is this a mistake or was it done for a reason.
    ReplyDelete