Arduino Binary Alarm Clock

Arduino Binary Alarm Clock
This Instructable will show you how to build an binary alarm clock, with a touch sensor snooze button. This is my first instructable and my first real arduino project, I hope you like it!

I bought an arduino a while back and I think it's really nice, but I haven't really done anything useful with it yet, so now I thought it was time to make a bigger project. I decided to do an alarm clock since my old one is broken.

Here's a video of it in action:



There seems to be some problems with the video embedding,  If you can't see the video above, here's a link to it: binary alarm clock
 
Remove these adsRemove these ads by Signing Up
 

Step 1What should be done?

To help me organize my thoughts about how I should build the clock I wrote down what I think an alarm clock should be able to do. I then tried to build the clock to meet the requirements.



An alarm clock should be able to:                 What I used:
- keep time                                                          - code
- display time                                                      - LEDs 5 for hours, 6 for minutes
- keep an alarm time                                         - code
- let the user set the time                                  - buttons
- let the user set the alarm                               - buttons
- make noise when the alarm goes off.         - speaker
- let the user snooze                                          - touch sensor "button"                     
- let the user turn on and off the alarm.          - touch sensor "button"

It would be nice if it also:
- looks reasonably good                                  - a nice box as case
- is cool and geeky                                           -  true binary display
« Previous StepDownload PDFView All StepsNext Step »
21 comments
Nov 5, 2011. 10:46 AMlinux-dude says:
Really great project! Thanks a lot, this one inspired me to do my pocket binary alarm clock !
2011-10-30-002449.jpg
Jan 17, 2011. 6:58 AManalog.motion says:
Where are the wires from the buttons going? Great project!
Sep 20, 2010. 5:29 PMMad Engineer says:
how can I not use the touch sensitive on/off/snooze feature? I am pretty new to electronics, so any help would be great.

Thank!, and great instructable
Jul 10, 2010. 12:20 PMjolijar says:
Where did you get that box from?
Jan 10, 2010. 6:50 PMLaserman595 says:
When ever you do find out please post it so it would be possible to  compensate for it every 6 or so months.  =-)
Dec 25, 2009. 10:12 PMWicken says:
I just want to say how lovely this is, both the clock (which is aesthetically pleasing and clever), and the instructable. I'm a writer for my day job and I do textile crafting for my hobbies (sewing, knitting, spinning, etc.) but I actually understood what you were doing here, which means you did a great job.  I used to know a little C++ and this and that, when I was way, way younger, and I followed along the code bits you show surprisingly well, too, because you were so clear what it was all about.

I've always wanted to learn this kind of thing but don't know a single soul who knows much beyond not using the wrong adaptor for the printer (and some don't know that much!).  The more instructables I read, though, the more convinced I am that I'll have to make one, some day.  It's getting harder to resist.  :) 

Nov 26, 2009. 10:49 PMdaltore says:
Have you thought about using ternary operators?  They're basically if() statements, but use a slightly lower-level structure.  I'm not sure if they run faster under the Arduino, they may actually end up compiled the same since it's an embedded environment, but basically, it goes like this:

condition ? run if true : otherwise run this;

So you could do that first if() statement like this:

current_millis_value < previous_millis_value ? m += MAX_MILLIS_VALUE - previous_millis_value + current_millis_value : m += current_millis_value - previous_millis_value;

It's not as pretty, but as always, C ignores whitespace, so you can write it like this if you want to organize it a little:

current_millis_value < previous_millis_value ?
m += MAX_MILLIS_VALUE - previous_millis_value + current_millis_value :
m += current_millis_value - previous_millis_value;

It might run faster and eliminate some of the timing error.

Also, you might be able to spread out the time correction a little more evenly than 2 seconds every 5 hours.  Since it's .4 seconds, that's 400 milliseconds every 60 minutes.  That goes down to 20 milliseconds every 3 minutes.  Since you're counting milliseconds directly, and the overall count of seconds is a multiple of 3, it might be overall a little more accurate to the user to do the correction more often.

Great tutorial though, I might have to try this!
Nov 27, 2009. 5:13 PMdaltore says:
Leave it unsigned.  You could just as easily have it count up to 1001 instead of 999.  This would save issues of the clock wondering what time it really is.

Yeah, I'll have to see how ternary operators and if() statements compare when I finally get an Arduino (Christmas is coming, as my plan currently stands).  For a lot of embedded environments, all those conditional structures get compiled down the same way anyway.  I think I recall that the C18 compiler (for PIC microcontrollers, like the one in my VEX robot) compiles if() and switch() statements to the same thing.  I wouldn't be surprised if it takes while() loops down to if()-goto structures.  Or I guess I could just look at the avr-gcc manual, but that would be too easy :D

I think I might eventually try this project, I've wanted a binary clock for a while, and I love the AVR line.  One thing that I found last night is that the Arduino bootloader still allows you to use the lower-level avr-gcc commands.  It turns out that digitalWrite() takes about 10 times longer to run than accessing the PORT register directly, because with each call of digitalWrite(), it turns off all of the PWM timers (and in the comments in the code, the guy is asking why that couldn't be moved up to pinMode(), which is interesting).  Basically, digitalWrite() is just some safety mechanisms and a parser for the PORT register.  It sets the PORT of your choice (lets say pin 13, which is under PORT B, pin 5) to an entire byte all at once (you can toggle 8 pins just about simultaneously).  This would work like this, IIRC:

PORT_B = 0b00010000;

Or, to only affect that pin, you can use the | operator:

PORT_B |= 0b00010000;

You don't have to make these modifications, I realize it would take a long time to recalibrate, just thought you might be interested.  I still love the tutorial.  I think it might also be interesting to make a multiplexed or charlieplexed version, just for funsies.
Nov 29, 2009. 4:11 PMdaltore says:
Oh, yeah, with the "1001 instead of 999" thing, I was thinking 2 milliseconds instead of 20.  And actually, you could tack on 7 milliseconds every minute, and then 6 every 3 minutes, like so:

if(seconds==59 && m > (!minutes%3 ? 999+6 : 999+7)) {  //If divisible by 3, add
    seconds++;                                                                              //18 ms, otherwise 19
    m = 0;
}
else if(m>999) {  //Normally, a second is just 1000ms
    seconds++;
    m = 0;
}

I think how you do it with the 2 seconds every 5 hours is fine by the way, this is more just a point of discussion.
Nov 15, 2009. 4:12 PMsimonrichards150 says:
Just wondering, why didn't you use a RTC for timekeeping? Nice guide btw.

-Simon
Nov 17, 2009. 5:57 PMcyrozap says:
Yeah, it'll start drifting by a lot after a while. You should use this. I read that it is very good. You can even get one that is the electrical equivalent, but the headers are soldered on the wrong way, for half of the price.
Nov 15, 2009. 11:15 PMhollenback.c says:
 This is so cool! Thanks for posting this, this is amazing. I definitely like this binary clock system rather than Binary Coded Decimals.

Pro

Get More Out of Instructables

Already have an Account?

close

All Steps Viewing
View all steps of an Instructable on the same page when you're a Pro Member.

Upgrade to Pro today!
2
Followers
1
Author:njakol