This is about building a clock using the fantastic neopixel rings from Adafruit. The fun thing about this clock is that it actually has two rings of neopixels, one for telling the hours and one for the minutes, seconds and milliseconds. The clock keeps perfect time using the DS3234 DeadOn Real Time Clock chip from Sparkfun. Easy to build and fun to modify. My hope is that it will inspire others to build clocks or other art using the neopixel rings.
For those of you who want to get all my files in a simple to manage format feel free to download them from my github repository for this project at https://github.com/chrisgilmerproj/neoclock.
Step 1: Designing the Clock
I knew from the beginning that I wanted to use at least two rings of neopixels. After some work I decided the best design would be to have one ring inside the other, which keeps the original form of a clock. The smaller ring would be the hours and the remaining time would be kept on the larger ring. Some design considerations included the cost of the neopixels, the power requirement, size of the laser cut pieces, and what kind of art I wanted to put on it.
With this step completed I decided I needed to understand the electronics before creating the plans for laser cutting the clock body.
Step 2: Designing the Electronics
Designing the electronics came down to knowing in advance the elements I wanted in the clock:
- Neopixel rings (60 count and 24 count)
- Arduino (the brains)
- Clock Regulation (arduinos don't keep good time)
- Power management
The size and power requirements of the neopixels are well documented. Since they run on 5V DC I decided to go with a 5V Arduino and make things simpler for myself. With space being a consideration I decided to prototype on a regular Arduino Uno but for the final electronics I picked an Arduino Mini.
The first iteration of this project came directly from Adafruit's NeoPixel Basic Connections page. I've included the diagram from the website to make things easier. Two things are important from this:
- A 1000uF capacitor is needed to prevent the initial current jolt from damaging the pixels.
- A 470ohm resistor is needed on the first pixel of the 60 count ring (this resistor is built into the 24 count ring)
Adafruit also has a set of NeoPixel Best Practices that you should read before continuing on the design.
Keeping time on the clock is another problem. The built in clock on the arduino is not sufficient to keep good time over long periods of time. A worse problem is that the time on the arduino may need to be reset each time. Computers solve this problem by using a small battery on the clock chip to keep time between power outs. In the past I would use something like the ChronoDot from Adafruit. But in this case I wanted an excuse to use the DS3234 (DeadOn RTC) from SparkFun. You can also keep date information on the DeadOn RTC if you want to integrate that into the clock.
Finally, the power management needed some consideration. I already knew everything needed to be 5V but the amount of current needed seemed to be a mystery. A common voltage regulator in most projects is the L7805. This will take voltages up to 24V and a max current up to 1.5A. I knew I had a 12V 1.5A wall wort lying around so I decided this would be the perfect (and cheap!) voltage regulator for the project.
The remaining pieces were going to come from my box of parts or Radio Shack. They included the wires, switches, and DC power jack.
Step 3: Building the Electronics
A full list of the electronics that I bought to build this project can be found in my github repository here: Electronics Parts List. It has links to the product page for each piece and includes some additional information including the product SKU. I prototyped this quickly on a breadboard and moved onto the laser cutting and building before taking any pictures. However, I did build it to be easy to take apart so I've broken down the pieces in the photos above for you.
Look closely at the images as the wires were intentionally bent in ways to be easy to follow and to keep the entire profile of the electronics thin. Doing this initial prototyping before the laser cut designing allowed me to check thickness of the parts so I could figure out the final dimensions for the clock body.
You'll notice that i made a couple custom breadboards. I've attempted to take pictures of the backs of those boards so you can repeat them. You can buy an assortment of breadboards like these for a couple bucks and make them to fit your project.
The wiring is straight forward but the important things to remember from the images are these:
- The Mode and Set switches will need pull down resistors. I used 2.21Ohm resistors that I had lying around but any small resistor will work (preferably not less than 1kOhm). This stabilizes the connected Arduino input pins so that when they go high it is distinguishable from the noise.
- The square wave (SQW) on the DS3234 was grounded since it is not in use.
- The power from the L7805 is put into the Arduino Mini in RAW pin. Always put the power that comes into the Arduino into RAW.
- The first pixel of the 60 neopixel ring has a 470Ohm resistor to reduce any damage to the first pixel from data spikes. This shouldn't be a problem since the 24 count neopixel has a built in resistor for this already, but better safe than sorry.
- The Mode and Set switches are SPST momentary push button switches
Wire colors are:
- Red: +5VDC
- Black: Ground
- Green: Data
- Yellow, Blue, White: Special wires for DS3234
If this is your first time using neopixels you should remember that they can be thought of as a long chain. So it might seem strange to talk about a "first pixel" in a ring, but in fact there is a start and end to each chain in the rings. In this project the 24 pixels of the small ring come first and the 60 pixels of the larger ring come after. This really means I have a chain of 84 neopixels.
For wiring on the Arduino Mini:
- DS3234 connects on pins 10 - 13
- The Mode and Set switches are on pins 2 and 3
- The neopixel data comes from pin 6.
I also recommend putting the 6 headers on the bottom of the Arduino Mini so you can program it via an FTDI cable.
An important note about current: This clock requires a lot. I'm sure I could work it out but my practical experience is that anything equal or less than 500mA will eventually cause brown outs. This manifests as the clock blinking crazy colors and not keeping time. My final wall wort is 12V and 1.5A and I've never had a brown out with it. However, 1.5A is the limit that the voltage regulator (and other parts) will take. So don't exceed this amount.
Step 4: Coding the Clock
The full code for the clock can be found in the NeoClock Code on GitHub. I've included the file here but any changes will happen in the repository.
I find writing code can be daunting if you try to do everything at once. Instead of going for that I try to start from a working example and build out features as I need them. Before I get into that I want to point out that my code came from combining a lot of examples from the following repositories and the Arduino CC forum. Always give credit where it is due!
Some example code from these repositories can be found in my Code Examples Directory
The order of operations I used to build out the code went something like this:
- Confirm neopixels work with the Strand Test Example
- Attempt to run a clock with the Time Loop Code
- Modify the clock to work on two rings instead of just one
- Add the DS3234 to keep time via the DeadOn RTC Example
- Add the Mode and Set Switches
- Add Debounce code with help from the Arduion Debounce Tutorial
- Add some color themes for the clock LEDs
- Add some animations for the 0, 15, 30, and 45 minute marks
- Add compass points to clock for orienting the 0 ,15, 30, and 45 minute marks
If you want to see how I built up this code you can actually use GitHub to look at each code commit. The history for the clock is in the Commit History.
Color schemes were fun to add but in the end I only included four of them in the menu. Each theme sets a specific color on the hour, minute, second, and millisecond "hands". Really the options are endless here but I included the themes (method names listed):
However, you can find these additional methods in the code:
Animations were added because I liked the idea of old clocks chiming at the four fifteen minute points on the clock. For this clock I made the following animations:
- 15 minutes: Color the rings Red
- 30 minutes: Color the rings Green
- 45 minutes: Color the rings Blue
- Top of the Hour: Do a rainbow across the two rings
Usability turned out to be a problem with the clock because no one could orient the clock. It's just two rings of LEDs after all. So to solve the problem I added the compass points to the clock. This improved the ability to tell time a lot. Had I known about this before sending out for the laser cut pieces I might have added something to the art instead. But it turns out you can't see the art that well in the dark, so having the compass points really helps. One consideration with this is that when you decide to color a pixel you should first capture the current color and create a new blended color. This gives it a more natural feel.
One last tidbit is about the milliseconds. Milliseconds on the Arduino come off the internal Arduino crystal and not the DS3234. It is up to you if you want to display milliseconds or not but I did so the clock always appeared to be doing something. It might bug you that the milliseconds and seconds don't always line up though, but in practice no one has ever mentioned it to me when looking at the clock and I think it looks nice.
Step 5: Designing the Laser Cut Files
There are two considerations I had to make when designing the laser cut files. The first was the material I wanted to build it from and the second was how it would be constructed. I knew I wanted a wood finish with acrylic do diffuse the neopixels. To figure out the material I first ordered some samples from Ponoko:
- 1x Veneer MDF - Walnut
- 1x Veneer MDF - Cherry
- 1x Acrylic - Light Gray
1x Acrylic - Opal
The wood selections let me see what the rasterization would look like and how the burn would look on the side of the clock. The acrylic would let me test out diffusion of the neopixels and compare how it would look against the wood. In the end I decided on Cherry wood with Opal acrylic.
The dimensions of the clock were mainly determined by the size of the neopixel rings. What I didn't know was how thick it needed to be in order to fit the electronics. Having built the electronics and knowing that the wood was about 5.5mm thick I determined I needed about 15mm of space inside the clock. That meant three layers of wood. But with the front and the back already taking up the majority of the space in my design I needed to break up those rings into "ribs" that I could glue together later.
I used InkScape to draw on the template provided by Ponoko. After drawing the clock body out I then set to drawing the tree by hand. I couldn't import the original image that inspired me but it wasn't terrible figuring out how to do something similar myself.
The cost of the materials was only about $20 but the cost of cutting came out to be about $100 more. Two things contributed to this:
- Curves and Circles cost more because the machine is moving in two axes and this design has lots of curves
- Rasterization requires a lot of passes back and forth across the piece. Dropping this would have saved the most money but I liked it.
After finalizing the design I sent the EPS files to Ponoko and my pieces were done about a week later.
Note that I didn't include the Mode and Set switches or the DC Power Jack in the design. When I sent this off I still hadn't decided on those parts. To give myself more flexibility I left them off and decided I'd drill them later by hand.
Step 6: Constructing the Clock
When all the pieces arrived I constructed the clock. The first step was the clock body which required me to punch out the ribs and glue them to the back and front. I put two layers of ribs on the back and one layer on the front and set them with wood glue. For the front I used wood glue to piece the acrylic rings and the wood circles together. I had a spare central piece that I'd cut as a blank that came in handy during construction. I glued it to the back of the tree piece and that gave me a place where I could glue the neopixels later.
With the body constructed I decided to drill out holes for the switches and power jack. A little geometry (as seen in the picture) helped me align everything. Using a separate piece of wood on the outside as I drilled (very carefully!) I made the holes and glued in the switches and jack.
The electronics all went in next. I glued down the neopixels first followed by the capacitor. These I wired into the neopixel power breakout board. Then for the back I put the wires on the switches and the power jack. I also included the L7805 voltage regulator.
A quick note on orienting the rings. For the big ring of 60 pixels you need to orient the clock so that one of the pixels is exactly at the top to mark the zero minutes. Which pixel doesn't matter and I'll get to why in a minute.For the small ring of 24 pixels you need to orient the clock so that the top is actually between two pixels. The reason for this is that if you want to mark 12 hours then you end up lighting up two pixels instead of one. By having the offset, and with the diffusion of the plastic, it will appear as though you really have 12 wide pixels.
As for which pixel the code designates as the "top" for each ring, you need to edit the code a bit. I have two values in my code named "inner_top_led" and "outer_top_led". In my clocks the "inner_top_led" was 11 pixels from the start of the small ring and the "outer_top_led" was 36 pixels from the start of the big ring. If you happen to orient the rings differently then you would change these values to be the ones from your orientation. A bit of experimentation and you'll find the right value pretty quickly.
At this point I tested that everything worked as expected.
But as with all project I ran into a problem as I realized I hadn't figured out how it would hold together. I noticed that I had about 3/8 inch of space between the neopixels and the ribs so I headed over to Home Depot and got a 3/8 inch dowel and a number of neodymium magnets. I built little wood stands in three places and sanded them down so I could put two magnets on each stand (using super glue). I ended up with 3 pairs of 2 stands each. Then I glued these into the frame and held it all in place with a clamp. I did this while the glue on the stands was wet so everything would align and then dry in the correct place. This worked perfectly and I love that the release is all hidden.
Lastly I figured out I needed to hang it on the wall so I drilled in a little hangar on the back so I could put it up on the wall.
Step 7: Final Thoughts
This project was a lot of fun to build and I enjoyed learning about neopixels and the DS3234. I especially enjoyed finally building a project that looked nice from start to finish. There are a couple things I would update if I did this again, but they are minor:
- I chose two buttons instead of three for simplicity. But having a button that would allow me to go down as well as up would have been nice for setting the clock
- The mode button and the set button are indistinguishable. I often mix them up. Perhaps I'd put them on opposite sides in the future.
- I never finished the wood front. I liked the look raw at first and later got worried that if I messed up the finish it would cost a lot to fix.
- Rasterizing the tree was an ok look but I might have drawn more detail for the tree in the future.
- Dimming the clock would be a nice feature too since it is quite bright in the dark. However, the dimming is tied to the color and figuring out that bit was taking too long so I dropped it. I'd probably re-invest in that feature in the future.
Thanks for reading through this instructable. I hope you'll make your own clock or neopixel project and share it with me. Happy building!
We have a be nice policy.
Please be positive and constructive.
What ^^^^ said.
Here is some smart code for NTP automatic clock, with geopositioning, so no matter where you are, the time is correct - DST and all.
He uses FastLED library with WS2812B LEDs - same as NeoPixel.
Wow! What a great original design. I really like it!
Here are a couple ideas (not critiques). %)
a) Seems like the neopixels would be very bright at night. You could add an ambient light sensor with a small hole through the front face. Then use the light reading to scale the color values down when it gets darker in the room.
b) Might be a nice effect to add vertical spacers between each neopixel to make the light from each one more distinct in the diffusion.
Could use an ESP8266 instead of the original arduino.
So time can be syncroniszed via NTP and the functions are acessible via WLAN.
I am getting close to assembly and my question is how do you align the LED rings? Does it matter if the first LED is at the top of the clock for the minutes. Same for the hour ring - does it need to be aligned so the first LED in the ring is up at the 12 o'clock position? Or do you just set the time until the LEDs align with the right time?
I'm really excited that you're building this. I hope you share your finished clock.
For the big ring of 60 pixels you need to orient the clock so that one of the pixels is exactly at the top to mark the zero minutes. Which pixel doesn't matter and I'll get to why in a minute.
For the small ring of 24 pixels you need to orient the clock so that the top is actually between two pixels. The reason for this is that if you want to mark 12 hours then you end up lighting up two pixels instead of one. By having the offset, and with the diffusion of the plastic, it will appear as though you really have 12 wide pixels.
As for which pixel the code designates as the "top", you need to edit the code a bit. I have two values in my code named "inner_top_led" and "outer_top_led". In my clocks the "inner_top_led" was 11 pixels from the start of the ring and the "outer_top_led" was 36 pixels from the start of the ring. If you happen to orient the rings differently then you would change these values to be the ones from your orientation. The part of the code for this is here:
I'll add this to the instructable so its a bit more clear when constructing the clock. Thanks for the question!