I wanted to make an LED clock, but how to get the LEDs into a circle? A LED strip would bend into a circle but the light would be projected in the wrong direction. So we had the idea of using total internal reflection. I had bought some 5mm thick frost acrylic, which originally I imagined would go in front of the LEDs to diffuse the light. But it happened to make a really nice light pipe. The unexpected bonus was that the too-bright LED light was toned down into something that was easy to look at.
Fardin did all the drafting with AutoCAD, which is a good thing because I wouldn't know where to start to get the geometry right. The circumference of the circle formed would have to be the length of a 12 LED strip, at 60 LEDs/meter that was 20 cm. The LEDs had about 2mm height above the 20 cm strip, so that changed the actual required circumference a little. The light pipes were designed to clip onto the LEDs, and the clip was not at centre of the outside visible surface. That threw another variable into the calculation. In any case, using various construction lines in AutoCAD, Fardin was able to get it all to fit perfectly, with the holes in the panel in the right position, at the proper angles, and lenses that would work with the panel and 20 cm LED strip.
Another engineering problem with this design was how to make the lenses fit into the holes on the front panel. We went for a friction fit, and through much tweeking and variations to the shape (including curving the sides), got the lenses to friction fit well. Fardin's skill was key to success in this endeavour.
Later I learned that our laser cutter did not have the repeatability to cut the panel and lenses to fit every time. Also, kids often have trouble getting the lenses into the panel. So I went looking for solutions.
One solution was to create a series of numbered test lenses, each of a slightly different size. We would cut the test lenses on the day of the workshop, decide which lens fit the best, then cut the rest of them to that size. We would also cut a smaller size, as some of the panel holes would still be too small.
Another solution, when a lens is too tight, is to file the edges. I like this because its another tool for the kids to use, and that is a key point of the workshop ie tangible experience.
One more solution for too-small lenses is super glue. I fall back on this one quite a lot these days. A small drop on the back of the panel is covered by the lens and not at all visible.
The electronics design for the colock is trivial. I designed to be cheap and simple to assemble.
For the buttons, I liked some that I found at an online retailer, but they were too expensive. I ended up using the web to find a factory that would manufacture the same part. The cost was a fraction, about 25 cents per button. Minimum order was 500, so I had to invest a few hundred bucks to get set up to deliver 500 workshops. It took about 6 weeks for my order to get to the top of their queue. I got a call from China, to ask what colour of green would I like? How about 6128? I asked them to make it like the green in the Italian flag. I decided on red, white, and green to acknowledge our friends in Italy who came up with the Arduino. I guess the sales person didn't know a lot about flags of the world, because the colour ended up being something more like frog green. It takes a little imagination to see the flag. Apologies!
There are a few aspects of the firmware that are worth noting.
Since there are 60 seconds and 60 minutes, but only 12 LEDs, usually these values are displayed by 2 LEDs. For instance:
1 LED1=80% LED2=20%
2 LED1=60% LED2= 40%
3 LED1=40% LED2=60%
4 LED1=20% LED2=80%
Hope that made sense.
There are three colours, overlaid, to create the time display. These are blue for hours, red for minutes, and yellow for seconds. You can of course vary the colours as you like, and that is one way that we let the workshop kids put their mark on their clock, by changing the colours.
The generation of the displayed colours is done by writing into a buffer, first writing in the hour colour, then the minutes, then the seconds. The colours can be "on top of each other", for instance if hour =3 and second=15, blue and yellow are overlaid, and we expect to see green. In order to achieve this, compositing (ie mixing colour, with partial transparency) is required. The compositing must account for the fact that mixing light does not always result in the expected colour, ie the one you would get when mixing paint. In terms of light primaries (ie red green and blue), yellow is red+green, and blue is blue. But green is not red+green+blue...green is green! So when you overlay yellow and blue, you need to take away the red and blue. But the way to calculate the colour is to work in HSV (Hue Saturation Value), and calculate the angle (hue) that is between the two hues being mixed. I had some problems getting this algorithm to work, and ultimately compromised, having succeeded in getting a good green (for yellow & blue), a good orange (for red & yellow), but not quite a good purple (for red & blue)
Another important consideration for the firmware is power usage. The power comes through the Nano's USB port, and typically one does not want to exceed 250 mA. But 12 LEDs, full on at 25mA or more, will exceed that. While the clock will never have 12 LEDs on at once, I reckon some people might like to have some special features, say like a nightlight mode with all LEDs on at brightest white. So in order to avoid the current ever being too high, I used a lookup table to map 0-100% brightnesses into suitable values. At the same time, using the lookup table for gamma correction, ie making sure that 50% looked like 1/2 the light of 100%.
The time keeping required some special attention. I learned after having designed the board that the Nano usually has a resonator, not a crystal. The result is, the time keeping leaves something to be desired. The colock can lose 7 minutes in a day.
One answer to this is a calibration constant. There are 86400 seconds in a day. So let's say for instance up to 10 minutes of compensation is required. That's 600 seconds. In order to compensate for 10 minutes error we need to be able to add or subtract (600/86400) ie 1 second every 144 seconds. That translates into about +-7 milliseconds per second. Just adjusting by milliseconds per second does not provide much precision, so better to have a second every so often when another millisecond is added or dropped. This is the gist of the calibration algorithm.
For greater precision, that answer is to add a real time clock, which I later added to the board layout. The slot accepts a low-cost RTC that can be purchased on popular web sites.