Monday 5 December 2011

Arduino Alarm Clock with Wake-up Light

Prefix
This post will be a continuous babble  about my progress in building an alarm clock based on the well known Arduino Uno. The content and structure of this post will change as I go on. So this will very much be a Work in progress post.
I will not go in to deep details about solutions to general or known problems in this post. In stead I will link to the solution and thereby giving the proper site/author the credits and also avoid introducing errors.

This is my first bigger usable project using Arduino.



Introduction
For quite some time now I have wanted to have one of those wake-up lights. There are a few on the market, but I find them either too expensive and not very nice.
After having played around with the Arduino for some time now I decided to go ahead and build one my self. With the Arduino and a few extras this should be easy to do - I thought. But here and there I have been running in to problems.

Because this build have to be used on a daily basis, and it must be very stable - and not to forget - It will be one of the first things I will see in the morning, so I want it to be easy to use and nice to look at.

The wake-up light will be a quite prominent feature of the alarm clock, which gives me a few difficulties in deciding on a design. But I will get there - eventually. My Danish roots often lead me to what I call B&O design. Not that my design will get even close to their design (I wish), but I will try to at least keep the design and usage as simple and functional as possible.

Other problems have mainly been down to my lack of knowledge about C++ programming. I come from the C# world and I am used to work with all the tools and helpers build into Visual Studio’s programming environment. But with thanks to this instruction I am now able to do the programming in Visual Studio, which does make things go a little more smoothly.

So after many ‘happy hours’ of programming I finally have something that works, at least in my bread board version. There are still a few issues and elements that have to be build and programmed, but the main functionality is more or less there.

At the end of this post I will keep a to do list.

Hardware
Arduino Uno
DS1307 Real Time Clock
LCD Display
LED wake-up light and driver
6 button analogue keypad
AM/FM Radio module
Audio amplifier
12V Power supply


Basic Functions 
Display Time with large digits
Wake-up light
Alarm or radio
Sleep function
Set-up menu
Quick Settings menu
Manual control of light and radio
Info display

Arduino Uno
It should be no surprise that the Arduino Uno board will be the heart of the alarm clock.

Real Time Clock with battery back-up
The alarm clock is equipped with a DS1307 real time clock module. The real time clock has a back-up battery, so the time is not lost if the power should fail.

The real time clock is not the most precise I have ever seen, so I might have to get the 'big brother' at a later stage. But because I can easily update the time, either via USB or just adjust the time manually on the clock now and then, I will keep this version for now.
I have thought of adding an auto adjust function to automatically update the clock once or twice a month, to compensate for the inaccuracy of the RTC. I will need to see how great the inaccuracy is - at the moment it seems to be loosing a couple of minutes in month - which is quite a lot if you compare it to the accuracy cheap clock modules you buy for next to nothing.

The real time clock is connected on the I2C bus. Getting it to work didn't cause any problems. And there are plenty of information to find on the web if one should get stuck.

As mentioned the real time clock keeps its time even if the power is turned off. Other settings that should be kept when power is off or by power failure are; Alarm time, snooze time, wake-up light fade in time, radio frequency etc. All these settings are stored in the EEprom on the Arduino. This means that the alarm clock will continue waking me up in the morning even after a temporary power failure.

LCD Display - Displaying large digits
The display used is a standard HP compatible 2 x 16 characters LCD display. I have made a small circuit board that fits at the back of the LCD display. This circuit drives the display as a three wire interface using a shift register. See  this blog for details.

To be able to show large digits a set of special characters have been created.

On this picture you can just get a glimpse of my add on print.
Update:
After playing around with the I2C bus, and realizing how easy it was, I decided to buy a new LCD display that like the real time clock also is controlled over the I2C bus. This LCD display is blue with white letters and is back-light. The blue display does look much nicer I think.

A very premature version of the current set up. The blue LCD does have a nice look to it.
Alarm On/Off indicator
For the alarm on/off indicator the colon ‘:’ between hour and minute is used.
If the alarm is off the hour/minute separator dots are blinking at the same time, once a second. If the alarm is on, the separator dots are blinking alternatively.  This gives a clear, yet discrete, indication of the alarm status. The blinking speed shown below is not accurate.

Alarm is On
Alarm is Off
Wake-up light
The alarm clock has a wake-up light function. The wake-up light gradually increases light intensity from 0 – 100% starting 30 minutes (default) before the alarm goes off.
For the wake-up light 84 bright bluish (465nm) LEDs are used. The LED panel was used for a winter mood light, published in Elector some time ago. The colour of the LEDs should be specifically good to help against winter mood. Still have to see if this is fact or fiction though.
The LED panel will be driven by one of the PWM outputs through a MOS-Fet driver. Because this neither have to be high speed nor high power I have just used a simple driver. The extra transistor is there to help turn the MOS-Fet totally on and off. The 5 volts from Arduino was not enough with the Fet I had on stock.


LED Panel



The original LED panel for the Wake-up light.

Update: 5-11-2011 - The blue LEDs does not produce enough light. As a LED panel for the winter mood light it gives sufficient light, because you are supposed to have it quite close to you when using it. But for lighting up my bedroom they are too weak. So I have ordered a bunch of bright white LEDs now and will have to see if this works better. I hope so – because there is going to be a lot of drilling and soldering.

Update: 7-11-2011 - The LEDs are now in, and I have done a quick test, with just 24 of these babies; the bedroom is just bright enough to read a book. So 80 should be enough to have the room fully lit.
Unfortunately my printer has stopped responding, it does not like the non original Epson cartridges I presume. That means I can't get to create new circuit boards until I get a new one. I probably buy a laser printer this time. I hope I will get better transfers with that. Have a look at my babble about how I create my circuit boards. 

Update: 12-05-2014 - I have replaced the LED panel with 3 power LEDs. I only run the LEDs  at 300mA, this gives a good reading light, and keeps the temperature so low that I only little cooling. The 3 LEDs are mounted side by side on a piece of aluminium.

Update: 19-11-2011 - Finally got a new printer. Went for a Samsung Colour Laser printer. The printer was quickly up and running - so I have made the first few tests today. When I saw the first transparency print, it looked very, well transparent, not the full cover I'd expected. After fiddling around for a couple of hours, with colour settings, contrast, print quality e.t.c.,  without getting a much better result, I tried to make a small test print. The result was surprisingly  good. So it seems like the toner is very efficient in blocking the UV light despite the, in my opinion, very thin layer of toner.

The first attempt using my new printer. Most tracks are 24mill.
Using a laser printer is not only faster, it also gives a much sharper result and is much less of a hassle. With the old ink jet printer I had to wait for hours for the ink to dry totally - before printing the same sheet again, to get a proper coverage. 
The above circuit board is the main board for the alarm clock and only took a couple of hours to make.

Detail of print. A few specks of dust has landed in the fix spray.


The Alarm
For the alarm sound I use a small 8Ω speaker, from an old phone if I remember right. The speaker is driven with just a normal small signal transistor, 2N2222 from the stock pile, with a current limiting resistor in series with the speaker. Using the tone library I can easily adjust the frequency or the annoyance of the alarm.

Speaker driver for buzzer.

Snooze function
The alarm clock has a Snooze function that extends the alarm time with 9 minutes (default) when pressed.

The Radio
The radio is a pre-build module from Sparkfun. It contains an AM/FM radio. In my set-up I will only be using the radio in FM mode.  At the moment I'm not sure if I want to build a small audio amplifier or just use an existing set of PC speakers with build-in amplifier. Currently I'm just using my old PC speakers.
The radio module does have a bug though, so it had to be modify. Fortunately the modification is quite easy made. A small signal diode is soldered between GPO1 and pin 12 and the track is cut. See also this link for full details.

There is very little space to solder the diode, but with a little patience it is possible.
 In the above image I have bend to VRef pin so it doesn't connect to the Arduino Board. If connected the Analog inputs does not respond and I do need them for the analogue keypad and the I2C bus.

The diode just fits in the existing holes.


Sleep function
The sleep function can be set from 15 minutes to 90 minutes in intervals of 15 minutes.

The analogue keypad
To save pins I have chosen to go for a simple analogue keypad with 6 buttons. The buttons are menu, enter, left, right and up, down. The navigation buttons and enter button is placed in a typical 'joystick' like layout, the menu button is made somewhat larger because it is also used as the Snooze button.

Analogue Keypad



Button functions of keypad.




Simplified work flow
The work flow of the alarm clock is quite simple. The biggest challenge has been to create an easy to use set-up menu.


I will post the full code when it is bug free and cleaned up.



Here is my very simplified pseudo code.

Setup() {
  Initialize
  Read Eeprom
}

Loop() {
  GetCurrentTime()

  if (lastSecons !=  currentSecond)  {
    Get current time from RTC
    Check alarm time and wake-up light time
    Display Time
  } 

  key = CheckKeypad()

  switch (key) {
    case btnMenu: Execute Set-up menu
    case btnDown: Execute Quick Set-up
    case etc...
  }
}

Download
The  current version of the source code can be seen here. This is my working code, so neither optimized nor bug free. There are still some loose ends here and there.
 
In the setup() method, after the initialization, settings such as alarm time, snooze time and so on, are read from the Eeprom.

In the main loop() method, the time is read from the real time clock. The current time is compared with alarm time and wake-up light time and a flag is set if the comparison is true. The display is updated once every second.

When not updating the display or checking the time, the keypad is checked and depending on the key state and the state of the alarm clock, running, alarm on and so on, the appropriate function is executed.

I have split the set-up menu in sub functions for setting date, time and numeric values. While in the set-up menu the main loop is not executed.

The box
I have started to create a box for the alarm clock. I'll keep the box as simple as possible, mainly because my limited tool collection. The box will be build from 3mm MDF board. It's easy to work with, and though this MDF is very thin, it is still possible to create a quite sturdy box. I have also been using MDF for my other projects.
I have decided to use external speakers for the alarm clock. There are a couple of reasons for that. Firstly - Using internal speakers would make the clock much too big, at least if I want an acceptable sound quality. Secondly - I already had a set of old PC speakers that sounds reasonably good. The disadvantage here is the two extra wires, power and signal.

I found an old 'universal' remote in one of my drawers, that newer worked for more than 5 minutes before loosing its settings. So I decided to use the buttons for the alarm clock. The buttons is made from the usual semi soft - nice to touch rubber. Five of the buttons are placed in the typical Up, Down, Left, Right and Ok fashion. See photo below. The power button, which is used as the Menu/Snooze button, is not as large as I would have preferred, but it serves its purpose. The original text and symbols on the buttons I remove with fine sandpaper.
With a jigsaw I cut out the holes for the buttons, it was quite a fiddle to do but I think the result turned out Ok. A small circuit board, with the 6 push switches, is placed behind the rubber buttons.

Here are some photos of the box:

Box with the holes in place. The holes are cut with a jigsaw. 
Wish I had that laser cutter though.

Inside of the box, with the buttons in place. The base is clued together with wood glue. 
Only the top and back uses screws.

Circuit boards added. A little annoying that Sparkfun, the designers of the radio module,
have placed the audio plug on the wrong end of the board.

Front view. Here I still need to remove the printing on the buttons.

Top view.

Wake-up light closed.

Back view. Antenna, USB, audio out, speaker and power cord.


Links
Circuit diagrams are all created with Eagle editor.
The Arduino Uno board and LCD displays are bought by iPrototype.



To do and extras. 
Multiple alarms.
Week Schedule.
Sleep function.
Auto adjust time to compensate for RTC inaccuracy.