This is an Arduino powered alarm clock that after hitting snooze twice the alarm will not cancel until the user has cleared 4 lines in the game Tetris. You physically turn the clock sideways, so the screen is vertical, to play Tetris. It’s never fun to wake up in the morning but playing a little Tetris is at least somewhat enjoyable and quite effective.
Feel free to vote for me in the microcontriller contest if you like my project. It would appear that contest might be specific to making things move. So what does this move? It moves the student who stayed up too late doing homework, it moves the parent with a new born child, it moves the Instructables author who was compelled to finish their project against all common sense. It moves what can often be the most immoveable of objects… you.
Direct link to this video http://www.youtube.com/watch?v=szoPO75u46s
Steps 9 and 10 have additional videos.
Some key features:
-Any button press will silence the alarm for 30 seconds so you’re not listening to the buzzing while playing Tetris.
-User can select how long the snooze interval is (with second granularity), how many times you’re allowed to hit snooze (0-255), and whether the snooze interval is from the time the alarm went off or the time the snooze button (any button) is pressed.
-Two separate alarms: One is a traditional alarm that will go off when that time is reached and then disabled for the following days. The other is what I call a “persistent” alarm that goes off at the same time Monday through Friday so isn’t disabled for the following days.
-It uses large numbers for which I was inspired by this Instructable and he got the idea from here .
-It gets power from a base that it sits on but has a rechargeable battery backup so you can tilt the clock without being encumbered by wires. The switching to and recharging of the NiMH battery happens automatically.
-It has a physical key to silence the alarm which is given to your spouse/roommate/parents so the alarm can be silenced with having to play Tetris
-The backlight brightness is user controllable through software and the backlight is turned off when not on the base to conserve power and indicate that external power is absent.
-You can cancel the alarm at any time, even before the snooze intervals have passed, by playing Tetris.
-Four different styles of Tetris, details Step 8.
-When setting the time and alarms instead of the typical adjusting of hours and minutes the user can adjust tens of hours, hours, tens of minutes, minutes, tens of seconds, seconds, tenths of seconds, hundredths of seconds (yes, really) and day of the week. This allows for quick time setting and ability to synchronize easily with another time source. See Step 9 for details.
Other points of possible interest:
-Use of interrupts, Step 4.
-The best (in my opinion) way to debounce switches, Step 5.
-Use of PROGMEM to store strings to save on memory, Step 7.
-Precise and simple instructions for using the Sparkfun FTDI Basic Breakout board and making a barebones Arduino board, Step 13.
-Keeping time with an Arduino without a separate real time clock, Step 2.
-How to deal with the fact that the Arduino function millis() wraps back to 0 every 50 days or so, Step 2.
This is my very first Arduino project and I have to say it’s a pretty slick environment.
Step 1: Parts
-An Arduino or an ATMega328 with the Arduino bootloader. Sparkfun sells them ready to go or save a buck and buy it from Digikey part number ATMEGA328-PU-ND . If you buy one without the bootloader you’ll have to program it yourself. I used a UsbTiny from Adafruit and the process was super easy thanks to the Arduino IDE. ($5.50)
-A way of programming the Arduino. I used Sparkfun’s FTDI Basic Breakout item number DEV-09873 . I had a surprisingly hard time figuring out how to hook up the programmer so I have instructions for that in Step 13. ($22.00)
-A crystal and accompanying capacitors. This and the above two items are all that’s required for a bare bones Arduino. A ceramic resonator won’t work in this application because we’re keeping track of time. I got mine from Digikey part number 300-8437-ND . ($0.63)
-A backlit standard (HD44780) 16×2 LCD display. I got mine from Sure Electronics part number DE-LM12111 . ($5.99)
-Four buttons. I used tactile ones from Digikey part number SW404-ND . ($0.35)
-A buzzer. I used one from Digikey that I got a long time ago for another project so I forget the part number.
-A rechargeable 9v NiMH battery. I got mine from harbor freight part number 97865 . ($9.99 although they have a cheaper, lesser capacity one that was out of stock the day I went)
-A 9v battery clip-style holder, I got mine from Digikey part number 71K-ND . ($0.44)
-A 9v battery contact, I had a couple on hand but I’m pretty sure I originally got them from Digikey.
-A ICL7673 backup battery IC, a wonderful device that automatically switches between two power supplies without an interruption in power to the device and even indicates which power source is currently being used. I got mine from Digikey part number ICL7673CPAZ-ND . ($2.08)
-A 5v voltage regulator, I used a Low Drop Out variety from Digikey part number MC7805CT-BPMS-ND . ($0.56)
-A couple diodes, one for recharging the batter and one to insure against reversing supply power. I used one from Digikey part number 1N4148FS-ND and one from my parts box. Two of the ones from Digikey should work just fine. ($0.14)
-A slew (6 or so) of 0.1uF ceramic disk capacitors. I got mine from Digikey part number 478-5741-ND . ($0.13)
-Various resistors, I got mine from Digikey and from my parts box which was originally stocked from a very worthwhile Radio Shack purchase part number 271-312 . ($9.99)
-A project enclosure from Radio Shack (6x3x2″) part number 270-1805 . ($3.99)
-Veroboard (stripboard ), I got mine off Ebay, you can used your favorite board making material from etching copper clad to perfboard . Consider getting some stripboard and the tool for cutting the traces together off of eBay if you’re going that route.
-I also used a breadboard for initial testing and cardboard to mock up the enclosure.
-Soldering iron, solder, wire strippers, a rotary tool to make the enclosure, typical stuff.
Step 2: Code – general
All code, with the minor exception of the small availableMemory() routine, was written completely from scratch by me.
I originally thought the Tetris part of the code would be more complicated than the time keeping part. I could not have been more wrong. Writing Tetris for Arduino was a cake walk compared to an alarm clock with all the features I wanted. Descriptions of some of the programming issues are in the next few steps.
Many parameters are adjustable in the code. They are all at the top of the main file and include:
-All the wire/pin assignments
-Default time, and both alarms
-Constants the define buzzer frequency (default 4 kHz)
-Time the alarm is muted each time a button is pressed (default 30 s)
-Default backlight brightness 0-128 (default 128)
Many parameters are adjustable through the clock itself:
-Whether thicker or smaller pieces are used
-If 2 custom characters are used for the pieces and 6 for the rubble below or 4 and 4 are used.
-Length of the snooze in minutes (default 7 min)
-Length of the snooze in seconds (default 30 sec for a total of 7 min 30 sec)
-Number of times snooze can be hit before you must wake up (default 2)
-Whether hitting the snooze is absolute or relative, if the snooze time is added to the original alarm time or the time the button is hit
-How many lines of Tetris must be cleared to be declared awake (default 4)
-Restore the clock to it’s default settings
-Turn extras like am/pm, day of the week, and which alarm is set on and off
-Display current software version
-Save and restore EEPROM
Many parameters are saved in EEPROM to survive if power is ever lost completely. This is saved every day at midnight if any of the parameters have changed. They include:
-Current time (including day of the week), and both alarms
-Tetris mode of operation (see Step 3 for description)
-Whether the extras are on or off
-How many lines it takes to clear in Tetris to declare yourself awake
Time keeping is made easy thanks to the good folks at Arduino’s excellent implementation of the millis() function. That function runs in an interrupt and is made so as not to miss a tick. All I have to do is periodically add the time elapsed since the last call of millis() to the current time. Easy as pie.
I pull an interesting maneuver to take care of the millis() roll-over problem. The millis() function uses an unsigned long variable and the 32 bits means it can go up to 4294967295. But since it’s keeping track of milliseconds that means it will roll over every 50 days or so. This is usually not a problem but since this project runs continuously and relies on that millis() function we need to account for that overflow. What I do is monitor the millis() function and when it passes the halfway point take some action. When it’s convenient in the code (nothing time critical is happening) I subtract half the total value of the millis() function both from the function itself and from my own time keeping variables. That way it can roll right past this halfway point and when it’s safe subtract half-full time from everything and roll on. It’s a bit hard to explain, examining the code might help, but it works like a charm.
Step 3: Modes of operation
There are no less than 9 separate modes of operation. This makes things complicated and requires quite a number of switch/case statements.
0 – RUN_MODE – The standard running mode, large digit display of time along with smaller indicators: am/pm, whether we’re currently snoozed, which alarms are set, day of the week, and if the processor has been reset.
1 – TIME_SET_MODE – Mode to set the current time and day of the week.
2 – ONETIME_ALARM_SET_MODE – Mode to set the onetime alarm that gets cancelled after you’re awake.
3 – PERSISTENT_ALARM_SET_MODE – Mode to set the persistent alarm which goes off Monday through Friday.
4 – ALARM_SNOOZED – Snooze button has been hit, buzzer isn’t going off, we’re waiting for the snooze-number of snooze-intervals to elapse. Can enter alarm_snooze_turnoff mode to play Tetris to cancel the alarm.
5 – ALARM_TURNOFF_BUZZING – Buzzer is currently sounding, when a button is pressed enter alarm_turnoff mode.
6 – ALARM_SNOOZE_BUZZING – Buzzer is currently sounding, when a button is pressed consider it a snooze and enter alarm_snoozed mode
7 – ALARM_SNOOZE_TURNOFF – Hitting a button while snoozed enters this mode so you can play Tetris to cancel the alarm. If you stop playing for 30 seconds it returns to alarm_snoozed mode so you can sleep a bit more.
8 – ALARM_TURNOFF – The snooze-numbers have passes so you have to play Tetris and wake up. Pressing a button silences the alarm for 30 seconds but after that buzzing starts again. You have no choice but to wake up and cancel the alarm by playing Tetris.