Intro: Puzzle Alarm Clock
In this instructable I am going to show how to build an alarm clock that allows you to set the wake-up time by arranging the digits.
I hardly ever get in an argument with my boyfriend, but when we do it is nearly always about setting the alarm time (so far we have been using our phones). It has happened quite a few times that we both forgot to set alarm or one of us was mad, because the other one forgot to turn their alarm off during the vacation. So we wanted to build an alarm clock that makes the time it is set to very visible. Furthermore we wanted it to be able to play music, tell us the weather forecast and to look good. Luckily I stumbled over this concept by bitplay INC and we decided to adapt it to our needs.
Step 1: Stuff You Need
You can make the box out any material you like, as long the magnets are able to activate the reed switches through it. So if you don't want to work with wood you can also 3D print the case (I uploaded the files to this step) or even make it out of cardboard.
I used African Blackwood and Spruce to get a nice contrast
- Intel Edison (e. g. on the intel site)
- 28 reed switches (e.g. on amazon.com)
- portable mini speakers with USB plug (e.g. on amazon.com)
- Arduino Uno or an ISP programmer
- USB sound card (e.g. on amazon.com)
- SMD resistors (0805): 56, 330, 10k (47x), 1M (2x)
- SMD capacitors (0805): 22 pF (2x), 100n (2x)
- electrolyte capacitors: 0.1 uF (2x), 0.33 uF
- LM7805 +5V voltage regulator (e.g. on amazon.com)
- LM7809 +9V voltage regulator
- ATMega 328P IC TQFP-32
- PCF8574T I/O expander IC (4x)
- SMD quartz crystal 16 MHz
- SMD BC849C NPN transistor (SOT-23)
- SMD USB-A female connector
- SMD micro push button (2x)
- IR LED
- pinheads (a lot)
- jumpers (9x)
For the case:
- wood (e.g. Spruce)
- front: 26.4 x 11.6 x 0.2 cm
- back: 26.4 x 11.6 x 0.6 cm
- sides: two 11 x 9 x 0.6 cm
- top: 26.4 x 9 x 0.6 cm
- bottom: 25.2 x 9 x 0.6 cm
- supports: four 1 x 1.5 x 9.5 cm and two 1 x 1.5 x 15 cm
For the digits:
- wood (e.g. African Blackwood)
- 30 x 8 x 5 mm (you will need at least 26 pieces)
- two 8 x 8 x 5
- Ø 5 x 4 mm (one per piece, I couldn't find any so I stacked two Ø 5 x 2 mm ones on top of each other)
- Ø 4 x 2 mm (54 + two per piece)
- drill or mill and 4 and 5 mm drill bits
- sanding paper (sander)
- wood glue
Step 2: Wooden Box
Start by sanding all the pieces to get rid of any splinters that might be there. Then glue the supports to the sides and the top, as shown in the first and the third picture. Afterwards you will have to glue the sides onto of the top plate. Once the glue is set, you can glue the front and back plates in place as shown in the fifth picture. Make sure to clamp the wood properly and use small wooden pieces, to prevent it from getting dented.
Once all the pieces are glued in place, you can place the bottom into the box (you can of course use the bottom as a distance holder while gluing, but make sure not to glue it in place). If it sits to tight inside of the box, use sand paper, to make it smaller. Once you are happy drill four 2 mm holes into the corners of the bottom so that you can later screw it in place.
Step 3: Digits
We decided that we didn't want any markings on the front of the alarm clock, so it was important for the pieces to snap into the right position.
Drill two 4 mm and one 5 mm holes into the pieces, as shown in the pictures. Afterwards glue the magnets in place.
You will also need two 8x8 mm pieces, which will later be used to cover up the buttons. Drill a 4 mm hole into the center of them.
Step 4: Intel Edison
All the high level code reading is run on the Intel Edison. Its main functions will later be:
- read the current alarm time from the segments via I2C
- synchronize the current time via internet
- fetch weather report data
- synthesize the greeting message via text to speech
- play the greeting message and wake-up music at the right time
- send the IR-LED commands to the ATMega IC
Fortunately, once set up and connected to the Wi-Fi, the board can easily be programmed from the distance using a SSH client. Intel published a really nice “Getting Started” guide on their homepage that explains how to set up the board, install the current firmware and how to connect the board to the internet via Wi-Fi. In step 5 they also show you how to obtain your IP address which you will need later to connect to the board. In this instructable I will use the same address as given by Intel`s tutorial: 192.168.0.105. Please note that your IP address is most likely different and you have to figure it out like it is shown in the tutorial.
Once you have a working Wi-Fi connection you can set a password to be able to use SSH and also install the missing packages. Just type the following commands in the Edison serial console (omit comments marked by #):
#set password for later SSH use configure_edison --password #update and install needed packages opkg update opkg upgrade opkg install nano opkg install python-pip opkg install mpg123 opkg install alsa-utils pip install gTTS pip install pywapi #set timezone for the local clock timedatectl list-timezones timedatectl set-timezone ####your timezone####
Before placing your Edison board in the alarm clock you should try the SSH connection once. If you have followed Intel`s "Getting Started" guide, you already got to know the little but powerful program “putty” which will act as our SSH client. Just start the program and enter the IP address assigned to the board and choose SSH as connection type (see image above). Then a windows will open prompting you for a username (root) and a password (the password you set before). If the connection works you will be able to program and test your code without having to open your clock every time.
Step 5: Power Supply and IR Controller
The 1st image in this step illustrates the general layout of our alarm clock electronics. The Intel Edison board polls the chosen number set by the magnets using the I2C and PCF8574 DIO extenders. This reduces the number of needed IO pins on the Edison board from 28 (4 x 7) down to 2 (SDA & SCL).It also uses the I2C bus to send commands to the ATMega328P which acts as a IR remote control.
In principle you could also use the Edison board to control the IR LED, however I encountered some major problems with timing the signals. For example, when setting the IR pulses to 38 kHz (as specified in the IR remote protocol) via the mraa python binding some strange things happened: I was able to set the PWM period to 26 microseconds (unfortunately the pulsewidth_us function only accepts integer values) which corresponds to a frequency of 38.5 kHz. When using the pulsewidth function which accepts a float value to set the period to 26.3 microseconds, the PWM frequency chanced to 20 Hz and could not be changed further until performing a hard reset. As it is furthermore very hard to precisely control the right timing in a non-real-time system environment like the Linux image on the Edison Board, I decided to delegate the signal generation to an ATMega328P IC. This IC is able to run a real-time system and already has a very nice IR remote library available.
The ATMega is mounted on a board that also acts as a power supply for all components in the system including the speaker (5V, charged via the USB plug on the board), the Edison board (9V) and the four segments with the PCF8574 ICs. Furthermore, the board collects all I2C signal lanes and acts as an interconnection board for all components.
You can find all the needed EAGLE files as well as the PDFs of the schematics to reproduce the power board attached to this step. In the next step I will show you how to program the ATMega328P to act as a IR remote control.
Step 6: Program IR-LED Controller
The ATMega328P chip is also widely used in many Arduino systems including the most common Arduino UNO. This gives us easy access to a I2C controlled IR LED remote just by developing the code on a normal Arduino UNO (with all its libraries and capabilities) and later transferring the program to our SMD variant of the ATMega IC. I used the IR Remote library developed Ken Shirriff which you can find here. This very useful piece of code simplifies the 38 kHz signal generation and timing to send the right signal down to a few easy lines of code and in the end you only have to specify which numeric code you want to send with a specific protocol. To find the right code and protocol you can use for example the awesome tutorial published by adafruit.
In my case the following codes are sent via the NEC protocol to control the lamp:
Turn LED light on: 0xFFE01F (32 bits)
Turn LED light to white: 0xFFD02F (32 bits)
Turn LED power up: 0xFFA05F (32 bits)
Turn LED power down: 0xFF20DF (32 bits)
Turn LED light off: 0xFF609F (32 bits)
So if you want for example turn the lamp on, you would use the following line of code in the Arduino development engine:
In my case I wanted the ATMega to listen on the I2C address 8 for a numeric code that will then be sent using the IR-LED in the NEC format. So if I want to include a new code, I just have to add (for example via SSH over a Wi-Fi connection) it to the script running on the Edison board which is much more simple than to reprogram the IC inside the clock. I have included the source code as well as a copy of the binary hex file to program the IC in this step.
However, you still have to transfer the initial program onto your ATMega IC soldered onto the board. To facilitate this the board has a dedicated SPI connector as indicated in the first picture. You only need a few pieces of wire, an Arduino board and the free winavr software package.
Start by connecting the Arduino to your computer and uploading the ArduinoISP program given in the example section of your Arduino SDK. Next, connect the Arduino pins given in the code to the appropriate pins on the power board. If you are using an Arduino UNO the following connections have to be made:
Arduino -> power board
GND -> GND
5V -> 5V
D10 -> RST
D13 -> SCK
D12 -> MISO
D11 -> MOSI
After that you can open a command line on your computer and check whether the IC is responding. After typing the following command you should see an answer giving you the serial number and set fuses of the IC (as shown in the 2nd picture). You have to replace COM# with the actual serial port your Arduino is connected to (as shown on the bottom right in your Arduino SDK).
avrdude -v -c avrisp -p m328p -b 19200 -P COM# -n
If you are using a "fresh" IC you have to tell it now to use the 16 MHz quartz crystal as a clock input. This is done by setting so called “fuses” (see 3rd picture). Be very careful in this step to set the right fuse as given above. Else, you might render your IC inoperative.
avrdude -v -c avrisp -p m328p -b 19200 -P COM# -U lfuse:w:0xff:m -U hfuse:w:0xd9:m -U efuse:w:0x04:m
If everything has worked so far, you can upload your program onto the ATMega. You will need the “hex” file generated by the Arduino SDK when compiling the code. By enabling verbose output during the compilation (Arduino SDK options) you will easily be able to find the temporary directory where the hex-file is stored. Alternatively you can use the “I2CRemote.cpp.hex” file I provided together with the source code. However, keep in mind that it will only send the IR signal via the NEC protocol. To upload the program onto the IC type:
avrdude -v -c avrisp -p m328p -b 19200 -P COM# -U flash:w:I2CRemote.cpp.hex
You now have full functional IR remote that you can trigger and control by your Edison board.
Step 7: Prepare Digits
We are now able to use the Edison board to generate arbitrary sounds and music and to control our ATMega IR remote. This step is dedicated to the four digit boards to set the alarm time.
In principle, every digit consist of seven magnetically operated switches (reed switches) whose states are simultaneously read out by the PCF8574T IC. In order to make the single segments of a digit stick to the right place through the wood board, every reed switch is accompanied by two 4x2 mm magnets that act as an “anchor” for the two corresponding 4 mm magnets of the wood segment. Here, the reed switches are aligned off center in a way that one latch of the switch will directly be under the 5 mm center magnet of the wood segment. You can find out more about reed switches by reading this document.
I have added the corresponding EAGLE files to allow you to reproduce, modify or improve the boards. Once you have the circuit board ready, start by adding the IC and other electric components except for the reed switches. You will have to start with adding the SMD components, since the heat needed to solder them in place would otherwise melt the glue used to hold the magnets.
Now you can start gluing the 4x2 mm magnets onto the positions indicated by the round etchings on the board. As the magnets tend to move towards or away from each other, you will need a little patience to get all magnets into the right position. I found it very helpful to use the wood segments as spacers for the two magnets: just add two magnets on top of the existing 4x2 mm magnets in the wood segment, put glue on the board and fixate the wood segment in the right position with some tape.
Finally solder the reed switches to the board in the indicated position. Keep in mind that the center between two 4x2 mm magnets should coincide with one latch of the reed switch. Be very careful when handling the switches – the little glass bodies tend to break at the slightest physical stress. The best way to bend the switches in the right position was to use a bending tool designed for resistors. (e.g. like this one)
As the last step add pinheads to the backside of the circuit board. The 4x1 row is used for power supply and to interface with the Edison board via I2C. The three 3x1 rows represent a way to assign a unique address to each board by bridging two pins of each row with jumpers (see assembly step). This way, the Intel Edison knows which of the four digits you have changed.
Step 8: Buttons
The last board contains the circuitry for the two buttons to stop/snooze the alarm or check the current time. Those two are disguised as the colon between the two pairs of digits. I chose to debounce the two buttons with a R/C combination to simplify the handling in the code. You can find all needed EAGLE files in this step.
Drill two holes for the switches into the front plane. As the board is quite thin, you should support it from the other side with a small piece of wood. To get the spacing between the switches and the board even we printed small plastic spacers. Of course you could also use cardboard or small wood pieces – whatever you have lying around. When the switches are aligned right, glue the wood blocks onto them from the other side.
Step 9: Assembly
Before assembling the devices you should choose to drill a hole for the IR LED. I decided to drill it into the back side to use the wall as a reflector. This way the LED is not directly visible and still able to operate the lamp in front of the clock.
Start by fixing the Edison board onto the back plane of the box. As the supplied spacers were quit large and I did not want to drill holes into the back plane I used small spots of double sided tape and hot glue to do this.
Next add the digit boards onto the inner front site of the box. Here you can use the wood segments to align them in the right position before fastening them with hot glue. Please note that every segment has a unique jumper setting to identify them later via the I2C protocol.
Following the digit boards you can now glue the power supply and interconnection board to the top of the clock.
The last assembly step is to mount the mini speaker to the bottom plate of the clock and to connect the corresponding wires:
- the 12 V power supply with the power board
- the 9 V port of the power supply board with the Edison power socket
- the mini-speaker USB power supply with the USB plug on the power board
- the USB sound card with the Edison board and the mini speaker
- the 4 pins of the digit boards with the SDA, SCL, GND and VCC lanes on the power board
- the four lanes of the buttons board with the Edison 5V power supply, GND, D2 and D3.
- the IR LED with the IR-LED pins on the power board (see image step 6)
You are now ready to upload the python program controlling the alarm clock onto the Edison board. You can do this for example via “winscp” connecting over the SSH protocol. The python script I am running is appended in this step - feel free to modify it to tell you even more (like traffic on your typical way to work, ...)! To make the Edison board run the alarm clock program after a reboot you have to add it to the automatic start scripts:
root@myEdison:~# cd /etc/ root@myEdison:/etc# mkdir init.d root@myEdison:/etc/init.d# cp /home/root/alarmClock.sh . root@myEdison:/etc/init.d# update-rc.d alarmClock.sh defaults Adding system startup for /etc/init.d/alarmClock.sh.