Friday, May 1, 2015

StarGate SG-1 Advanced Arduino Neopixel Clock

My fascination with clocks and watches always has been pretty hard to control.
Of course, when I saw the Adafruit Neopixel 60 LED Circle this was the first and most logical thing to come through anyone's mind. I wanted to check out what other have done with the Neopixel and found the  "Stargate LED Clock" project by David Hopkins (hopo28) on GitHub. It is a really well done clock and has some very cool visual effects. The enclosure is fantastic too - exactly as the clock is named - a Stargate. While David's clock is great, I felt that it lacked some features - it is just too uncomplicated for my taste. The ATMega chip has plenty of performance overhead and more than enough memory so I decided the load the clock with as many features as I could come up with and fit in the 32K flash memory.
I started with David's code as a foundation, made a list of enhancements and started implementing the features one by one. In the process I updated the hardware configuration as well. The clock now uses ChronoDot V2.1 as RTC and Adafruit TSL2561 Digital Light Sensor. To add audio output I added a simple piezzo speaker driven with PWM. To implement a menu system and keep it simple enough to control with only 3 buttons I need to use double-click and long-press button actions. The entire de-bounce routine was replaced.
Just to list a few of the features I have added : Menu System for setting all parameters (including the RTC calendar), using color patterns feedback and only 3 buttons, Advanced Brightness Control system, 6 programmable alarm modes, SunRise Alarm, triggered by the level of the ambient light in the room, Audio Volume control with 10 levels and automatic "Quiet Hours" mode, Westminster Quarterly Chimes and hourly beeps, 10 Alarm Songs, Full Calendar display, Custom User-Programmable Color Set (stored in the EEPROM, requires an USB computer connection).
My development platform is an Arduino Uno board but I'll migrate the clock to one of the smaller boards.
David has done  a really good job putting together the base of the clock (Thanks so much!) and it was easy for me to understand his functions and  add all these features, even when I needed to re-organize the program flow.
 Just completed the final revision  of SG-1 V2 (I had to optimize a lot of things and move some stuff to PROGMEM - as expected first I ran out of RAM and then out of program memory (blame is on the 10 alarm songs),

The development platform / prototype: Arduino Uno board, Neopixel 60 LED Circle, ChronoDot v2.1, TSL2561 Digital Light sensor, 3 buttons, piezzo speaker and a resistor.

The Main Color Set - Time is 11:14am (22 sec)

Main Color Set - Time is 1:19pm (37 sec). The Hour color changes to indicate PM.

Custom Color Set - The color of  each element of the display can be configured independently with a serial console and a text menu, displayed by the firmware. This Color Set has 2 modes and can be configured as either Dark (display off) or Custom Colors (User-defined). All colors and clock parameters, including alarm times, modes, sun Rise trigger level, etc are saved in the EEPROM.

Simple Mode - Hour, Minute and Second  - Time is 11:14am (33 sec)


 Calendar Mode : Date is May (orange) 1st (blue), 2015 (white) Friday (green). The day of the week color changes to red for the weekends. The inner part of clock's face helps to quickly determine the date. The hour dots are used for the month, and the date and year are displayed only in-between the dots. It is a bit awkward at first because of the 4 day increments per segment, but one can quickly get used to it. Only the next 32 years are displayed in two runs - each is 16 years, then a new clock face is needed to reflect the next 16 year segment.

 Alarm OFF (left) and Alarm (ON). Alarm for Week days only. Alarm time 7:00am.
One of the color sets displays the Alarm time and mode. If a dual mode is selected - for instance Alarm on Weekdays and Weekends. the display will alternate between the two alarm times.

Alarm ON on Weekdays and Weekends. Alarm Time for the Weekends is 9:55pm (a favorite TV show starts :-). Hour, Minutes and Modes are all set with  the 3 buttons.


Sun Rise Alarm Modes - triggered only once a day! It can be triggered between 4am and 9am and the actual trigger is the level of ambient light in the room (when the Sun raises). The trigger level is sampled beforehand, using a menu item and it is stored in the EEPROM. Some  of the configurable Alarm modes left-to-right: Weekdays Time Alarm + SunRise Alarm on the Weekends, Weekends only SunRise Alarm (no weekdays alarm), Every Day SunRise Alarm

Display Brightness Selector - 59 adjustable levels (left) and Auto mode (right) when the display brightness is controlled by the Ambient Room Light Level. The brighter is in the room, the brighter the clock display will be.

Volume Control (goes to 10 only, not 11:-). Left - Hourly Chime - plays Westminster quarter chimes + Bells for each hour, Right - Hourly Beep mode - beeps on top of each hour. This selector sets also the volume for the button clicks in menu mode. A special Chime Night Mode can be selected - it disables any chimes during the night time quiet hours (23:00 to 05:00)

Calendar Set Mode. All functions, modes, times and calendar can be set using 3 buttons and the menu system (using single, double-clicks and long-press actions)
The only function which requires computer is to set the Custom Colors and Mode for the Custom Color Set.

Part of the menu system - Yes / No selector for Calendar Setup. 


Yes / No selector for Sampling Ambient Light Level trigger threshold for the SunRise Alarm

 Every hour the clock does a random Star Gate visual effect- I didn't change anything in this part of the code - its all hopo28. The effects and animations are pretty cool!
The alarm song selection is a rather geeky (Star Wars, Indiana Jones Theme, etc), but the clock has a RTTTL Player routine so any Rtttl formated song from the web can be added - the only limit is the available PROGMEM space - currently 200 bytes are left from  the 32K.

The Text Menu was enhanced a bit to allow setting of the additional parameters and to provide more detailed status. I also added a separate color element for 3/6/9/12 hour dots.

Now I am working on the enclosure - thinking of something like a picture frame, but will explore other options as well. The clock face needs some improvements as well.
Toying with the idea to use the Light Sensor as sort of  a "Shift register" for the Menu. The user can simply cover with one hand the light sensor and this will change the meaning of the button functions - for instance advancing minutes with one button and when the light sensor is dark (covered), the same button decrements the minutes instead. Another feature I would like to add is an automatic DST but I doubt that ill be able to free up enough program memory for this.