Preface
I started this project wanting to make a simple binary clock that could only tell the time; however, it quickly grew to include more features. At present this project is able to tell time using a DS1302 RTC module, with a CR2032 as a backup for time keeping, it can display siple animations, has an alarm clock, and automatically dims based on ambient lighting. I also intend to add buttons to allow for easier time/alarm setting that doesnt require reprogramming the micro controller every time.
Parts and Tools Used
- 1x Arduino pro mini
- 1x 5V DC supply
- 2x SN74HC595 shift registers
- 1x 1KΩ resistors
- 1x 10KΩ resistors
- 16x 220Ω resistors
- 16x LED's
- 2x DIP16 Sockets
- 1x RTC module
- 1x CR2032
- 16x LED holders
- 1x Toggle Switch
- 1x DC Barrel Jack Plug/Connector
- 1x 10K LDR
- 1x Piezo Speaker
- Male and Female Headers
- Insulated copper wire (solid core and stranded)
- Bussing Wire
- Wooden Box
- Spray Paint
- Drill press
- Wire strippers
- Soldering iron
- Box cutter
- Straight edge
The first step of construction was to drill a 4x4 grid of holes into the front panel of the wooden case used in order to install LED holders. This was done using a 19/64" drill bit in a drill press, and by measuring and marking the grid of locations in which to drill holes. Following the holes being made, the panel was sanded to remove splinters caused by the cheap wood being damaged by drilling. After sanding, the box's front and back portions were spray painted black in order to give them a nicer look. Once painting was done the LED holders were inserted and fastened into the holes, and had LEDs inserted into them, with all cathodes facing the top of the box, and anodes facing the bottom. A grid of bussing wire was used to connect all of the grounds together in rows, and then the 4 rows were joined by a column of bussing wire in the middle. Each LED then received a wire connected to the anode, whih lead to a male header. LEDs were connected to the header in groups of 8, being separated by a ground connection in the middle of the header. The rear of the panel then received a DC barrel jack socket which was connected to a length of wire, and a male header.
With the LED display now done, it was time to build the control circuitry. The first step was to solder male headers onto a new Arduino pro mini, and then to connect it to a perf board. Next to it was placed an RTC module which was inserted into the board upside down in order to make use of its male headers. The Arduino and RTC were connected using the 3 wire interface that the module uses, there are also modules that use the I2C bus, however I do not have one of these. The RTC module was then connected to the VCC and GND pins of the Arduino in order to power it, while the arduino receives power through its RAW pin in order to allow input voltages of 5V-12V. A female header was used to connect the board to the input male header from the DC barrel jack. Some example code from the Arduino forums was then used in order to test and set the values of the RTC module. The date and time were simply inserted into the startup section of the program, and when it was uploaded the serial monitor was used to ensure the correct value was being displayed. Note that you should reupload this script following setting the time with the setup variable commented out in order to keep the clock from being reset on power loss.
Once the RTC was set and tested the next step was to add the shift registers which would control the LEDs. Since the power supply is able to provide the neccessary current, we are able to light all LEDs at once, meaning that we will not have to worry about using POV, and while we could matrix this display in order to halve the nuber of needed registers, it is easier from a programming perspective to just drive them all directly. As such, the two registers were cascaded together in order to form a 16 bit register, to which we could then push data to control all of the LEDs individually. the outputs that went to the female header that connects to the display had 220Ω resistors added in order to limit the current flowing to the resistors. Standard procedure was followed for connecting the register to the Arduino with one exception, rather than connect the Output Enable line directly to ground as usual, both were tied together, and then connected to a PWM pin of the arduino so that we can then control the output brightness easily. In order to determine the ambient light value an LDR was installed to the top of the case, and connects to the board through headers. The LDR forms a voltage divider with another 10K0Ω resistor in order to measure the ambient light on an analog pin. A simple lighting test was written in order to confirm that it was able to read the ambient light value correctly.
Arduino Files:
With the circuit setup to read time and light, the next thing to add was a small piezo electric speaker. This speaker is connected to one of the Arduinos PWM pins in order to utilize the tone command to control it and playback tones. A small toggle switch was also placed on the side of the case to act as an alarm control switch. When flipped up the control pin is pulled low, and it disables the alarm, and when flipped up the alarm is enabled. Once a predefined alarm time is reached, if the alarm is enabled it will begine beeping and flashing the alarm time until the lever is flipped off. Although not incredibly loud, and crude, it performs quite well, however I may add a feature to use an audio jack to playback audio in future.
Arduino Files:
With the current feature set implemented, all connections are made to the board using headers in order to allow for easy disassembly and upgrading. The final step of the project was to combine all of the features, and create a functional clock program. I began by porting over the time reading code from the RTC test program, and wrote a function to parse data sent from it. This function takes the hours tens digits, hours ones digit, minutes tens digit and minutes ones digit, as arguments, and parses the data to be displayed on the display. The loop function also writed a PWM value based on the currently detected light level in order to control the displays brightness based on ambient light. Note that because the Output Enable line is active low, 0 is maximum brightness, and 255 is off.
The printTime function then checks if the alarm time has been reached and the alarm is activated. If so, it will flash the time for the alarm and begin beeping the buzzer, and will not stop until the alarm switch is turned off. Otherwise the time is displayed by first creating an array containing the argument values, then a for loop is iterated from 0 - 3. Since the LEDs are wired sequentally on the horizontal axis, we simply have to calculate the current column (0-3), then bitwise and the value of that index in binary with the current value we are looking at for that column. Then each calculated value is shifted to the left equal to its equivalent index in the shift registers, and added to a result variable. Once all values have been determined for the current time it is sent to the shift registers and displayed.
The clock also checks if it has incremented by 1 minute, and if so, will call the animation function. This function takes a display result given to it, and will randomly select a routine that is used to turn on every LED, before turning them off sequentially, leaving the current time displayed.
Arduino Files:
Conclusion
This project was fun, and let me play with adding lots of features to a project that intially only had 1. It was alot of fun, and taught me some liitations of working with Arduino as well. One major issue I had while building this project was a shift register with a damaged pin was leaking through one of its pins, and was frying one LED consistently. Another issue I ran into was a discovery I made in working with the Piezo Electric Speaker, wherein it appears that the is some small amount of crosstalk between PWM pins on the arduino, meaning that it is picking up small amounts of current and making sounds when the PWM register is altered. Despite these limitations, the project was still fun to work on, and I believe the end result turned out rathe well. I hope to continue adding features to this project in the future, and will likely update this post following.