I've been wanting to make an interesting clock variant for some time now and I thought it would be cool to have each digit represented by an analogue gauge, so here is my design for an alternate clock. The top two dials represent the hour (in a 24 hour format) and the bottom 2 dials represent the minutes. The whole system is run by an Arduino connected to an I2C Real Time Clock module and an I2C PWM Servo Driver. Having both the RTC and the Servo Driver on I2C, is definitely a bit of overkill for this simple project but it does leave a lot of IO free for future expansion and the servo control is exceptionally steady (no jitter)

The dials are made from a combination of laser cut wood (stained dark) and perspex. Each dial has a white perspex backing which has been engraved and infilled with acrylic paint to achieve a high contrast on the numbers. There is a second piece of clear perspex over the front of each dial to enclose the pointer and stop small fingers from touching the moving parts. The dials are mounted on a 6mm plate which is tilted backwards about 10 degrees which makes the whole unit fairly sturdy. The electronics are mounted onto the back of the board using small self taping screws on the appropriate mounting points for each module (svg here)

The software to drive the whole thing is rather simple, Adafruit supplies lots of lovely sample code for both the RTC and the PWM driver so it was just a matter of tying those together. The simple plan was to be able to set a number between 0 and 9999 onto all 4 dials by working out the minimum and maximum range for a dial and subdividing by 10. That didn't quite work out and I had a little detour into the realms of PROGMEM to map new values into the servos in a way that didn't consume any additional RAM (again thinking about the expansion possibilities). I found the PGMWrap library was a very useful tool which allowed me to store my static map of values into the flash memory instead of in RAM. Full Source code is here and included below.

I'm using fairly generic 9g micro servos to drive the pointer on each dial. Although all 4 servos came in the same batch there appear to be two different types with differing time ranges. All 4 servos were sufficiently different in accuracy that I ended up having to map the exact positions of each of the dial numbers onto corresponding PWM values for the servo driver. This again had the added bonus of being very exact when moving to each position although it was a little time consuming to set up. The pointer was glued onto a modified servo horn and screwed into place before the clear perspex was added. It's a bit glue heavy and not particularly repairable so hopefully it won't break any time soon.

 I left the setServoPosition function in the code so that I could easily use the dials for a hit counter or other number display. I never did find out how to declare and use a 2 dimensional array from the PROGMEM so if anyone figures out how to do that I would love to know please, it would simplify the mapping just a little bit more and much more streamlined code because the PWM servo driver is technically capable of handling 4 of these displays at once.