Friday, 18 January 2013

Tiny LED Clock

Now that I have finished the new circuit for the old LED clock and that was running nicely, I got to thinking that the ATMega328 used in that was overkill, 18 pins, most of which were unused. I'd gone with that as it was fairly simple to use an Arduino for development. But back in the simple LED clock all it was doing was reading I2C from the RTC and writing it to the LED display using the same I2C bus, and that only took two pins. I decided to have a look at the ATTiny45, an 8 pin device which could do I2C. I rigged up a test circuit with the Arduino ISP programming the ATTiny45 (using the approach suggestedby high-low tech).
It looks a bit like an ode to the flying spaghetti monster, but basically, the orange wires are the ISP connections from the Arduino, running the ArduinoISP project (the capacitor is needed on UNO boards to stop the Arduino resetting). The rest are the black and red of power and the white and green and the I2C clock and data to the Adafruit RTC module and LED display. It all looked promising until I clicked build, as unfortunately the wire library used for I2C comms on the Arduino isn't supported on the ATTiny range.
I found the TinyWire library, which did provide I2C support on the ATTiny range, but the RTC lib and the Adafruit display libraries used wire and didn't work. The example which came with the TinyWire actually used the DS1307 RTC, but just made the call to read and processed the BCD response in the main code. That approach was all I really needed there for the RTC. The display was more of an issue as there I couldn't used the Adafruit library code. However, I had found a slight issue with that. Only slight, it only had a problem between 23:59 and 1:00. Basically the time is converted into an integer as hours x 100 + minutes, so 23:59 is just 2,359. The trouble comes with midnight. This adds up to 0 and so the display just shows '  :  '. A minute later we get '  : 1', nine minutes after that we get '  :10', and so on until '  :59' is finally followed by ' 1:00'. So I decided I could get around that be extracting the bits of the library I needed and converting them to use TinyWire rather than Wire, and in the process ensuring I left leading zeroes where required.
So finally, I ended up with a very simple circuit, but more complex software. I made the finished board the same size as the LED display, which sits on top. I could have used a smaller button cell, but the CR2032 is ubiquitous, and I had spare holders and cells, and it just fitted in the space. The only other components are the decoupling capacitor, pull up resistors for the I2C bus and the 32.768KHz RTC crystal.
One downside to this approach was not being able to set the RTC without writing mode code. I went with the easier option of installing the battery, then wiring up the I2C bus (without the ATTiny45 installed) via the display connector to an Arduino. This ran some simple code which set the RTC to the PC clock. I then disconnected that, installed the ATTiny45 and the Adafruit LED baclpack and the unit was complete.
I've wired this to a USB cable, and it now shows the time next to my PC. When the PC is off, the power to the USB goes off and so does the display. The RTC maintains the time thanks to the battery, and next time the PC is switched on, on comes the display with the right time on it.