I present, for your consideration, the first of what will hopefully be several of my projects detailed here, the RGB Clock
Functionally, it’s pretty simple. There are 3 lights (no, Picard, only 3 this time), each one representing the hours, minutes and seconds of a standard timepiece. But instead of showing numbers, each RGB light will cycle through the color spectrum as the value of each place increases.
Now at this point, you’re either thinking “huh, that’s pretty nifty” or “Pshh, how they hell do you read a clock like that?” If you’re in the first camp, then right on. If you’re somewhat skeptical, then no worries. Obviously this isn’t intended to be a “readable” clock in the traditional sense. I consider it to be psudo-practical art.
Getting into more of the gory details, this project started when I ran across a particularly interesting Instructable called “Ghetto Pixels – Building an open source BlinkM” by user jimthree. BlinkMs are tiny RGB LEDs with a microchip attached which allows the light to be controlled via I2C. This Instructable makes use of an open source “re-engineering” of the BlinkM functionality for the ATTiny45 platform called CYZ_RGB. With that in hand, it is a short trip with a RGB LED, some resistors, and a soldering iron to obtain little I2C-controlled, light-up widgets.
I particularly liked the “dead bug” style of putting the modules together. Seeing as how I had most of the materials on hand already, I decided it would be fun to churn out a few of these and find something clever to do with them. I then noticed a Chronodot sitting on my desk, and soon after, the RGB Clock idea took form.
Having worked with the Arduino platform for a while at this point, I reached for a Boarduino and began hooking up wires. Since these modules accept the same I2C commands as the official BlinkM modules, the BlinkM Arduino test sketches are compatible. Using the BlinkMTester script, I set the I2C address and tested each ghetto pixel individually. Once each pixel had a different address, they were all wired together and I verified that each could be independently controlled. At this point, the “display” of the clock was complete, and it was just a matter of finding a time source.
The Chronodot (seen above on the left of the long protoboard) is a breakout board for the DS3231 chip. The DS3231 is a wicked-accurate Real Time Clock that can be accessed over the I2C interface. There is a 3V button cell battery on the bottom of the PCB that will allow the chip to keep time in the event of main power loss. The DS3231 is also able to compensate for temperature. It’s probably overkill for this kind of project, but I had one on hand, and the ability to preserve time when power is removed was very valuable. This is because there’s no way to set the clock without re-programming the Boarduino. I’ll explain this when I go over the code, but it’s not pretty. If I decide to go further with this (as in, make it for someone else), I’ll throw some buttons on it to allow for simple setting.
I’ll direct your attention to the picture above. I would consider this to be the first version of the RGB clock. The case is the box from an iPod Nano (the tiny, square one). I found a bit of board that fit perfectly (with a little bit of trimming). To that, I soldered on the sockets for an ATMega328 and the three ghetto pixels. There’s also a 16MHz resonator which allows the ATMega to run the Arduino bootloader. The Chronodot fits into female headers which allow it to sit over the ATMega to save board space. Power (5V) is provided by a small connector, whose wires exit the box through holes drilled in the side. From there, the wires are spliced onto the power lines of a USB cable. I love the USB spec. 5V and around 500mA is perfect for a whole bunch of microelectronics project. I would have just soldered the USB +5V and GND lines to the board, but the connector allows the board to be disconnected for rework/upgrade if needed.
That’s pretty much it for the hardware part. And now, for some code. I’ll just do a bit of a walk-through of some points of interest.
The BlinkM_funcs.h file is pulled from the BlinkM Arduino library and test sketches (2007-11, Tod E. Kurt, ThingM). This contains the I2C commands required to communicate with the ghetto pixels.
The setup portion of the code initiates the I2C interface (Wire.begin() ), sets the fade speed for the lights, performs an initial read of the Chronodot, and sets the lights to the appropriate colors.
In the main program loop, time is first read from the Chronodot, and hours, minutes, and seconds are converted from binary coded decimal to their actual decimal values. If a change in any of those values is detected, the appropriate light (or lights) change to the corresponding color for that value. Rinse, repeat.
The RGB value for hours, minutes, and seconds is stored in a simple struct with R/G/B values. The RGB values for the desired value are determined by accessing an array of pre-set values based on the value of minutes/hours/seconds (depending on which is being set). In colortables.h, there are arrays for 12hr time, 24hr time (which is used), and 0-60 for the seconds and minutes. These arrays (supposedly) give a better distribution of color as time progresses than a simple hue to RGB conversion. A friend pointed these tables out to me and I think they work pretty well. You end up seeing (or, possibly, perceiving) a wider range of colors.
As an alternative to these tables, I did leave in a (commented) function to convert hue to RGB. Hue ranges from 0-360. It’s some simple math to get the appropriate hue value from the hours/minutes/seconds and with this function, you can get the necessary RGB values for use when setting the lights. I might play with this again in the future to see if I can get smoother transitions through the color spectrum as the values increase.
You can spy my code here: RGB Clock on github
And that’s about it. Feel free to offer and feedback. I think at this point, future plans for the project include a re-tooling of the color display (continuous transition through the spectrum as opposed to smash cuts to the next color) and possibly spinning a fabbed PCB.