This is a fuller description of the clock I put on Google+ yesterday.
The purpose of this is not so much to build a clock but to verify that I can make a ds1307 clock work with with a Teensy++ 2.0 board. Since I had an LCD lying around I hooked that up as well to display the time and date.
The ds1307 is a clock on a chip. This variant comes as a neat little package with a watch battery on the back. This is important because once power is disconnected from the Teensy it ‘forgets’ the current time. The ds1307 clock remembers it and keeps on ticking so when I power up the Teensy it gets the current time from the ds1307 and uses that. The ds1307 also has a few bytes of spare memory which, like the time, is also battery backed. So stuff I store there also survives loss of power.
The Teensy is a nice little package with a AT90USB1286 processor, a USB port and a load of pins I haven’t figured out properly yet. Unlike the Arduino the Teensy’s USB is supported directly by the processor. That means we can fully mimic USB functions, which I’m not interested in yet, but I also gather it means loading programs into the board is faster (though I haven’t used the Arduino). This processor has loads more memory than the Arduino UNO, though there are other variants of Arduino which may be more comparable. I program the Teensy using the Arduno IDE, however. That means the Arduino libraries for device support are available, as well as all their samples. There is a custom boot loader in the Teensy which some people might not like, ie not completely open source. It’s freely downloadable though.
The LCD is a KS0108-compatible 128×64 and I adapted the demo program for that to simply add the time pulled from the clock. All wired up it looks like the image.
The ds1307 is the red board just above of the LCD. Almost all the wires are for the LCD because the clock only needs 4 wires
The code is adapted from a demo for the LCD so there is a bit of rubbish in there that I could trim out if I were less lazy. The vital bits are the references to RTC and RTCE. RTC is a reference to the DS1307TRC class which manages fetching the time from the ds1307. The whole trick, really is this line:
which tells the time library to pull the current time from the ds1307 so when we request the time using:
time\_t currentTime = now();
we get the time from the ds1307. Actually there is some buffering going on in the library which I don’t have to care about.
But that doesn’t quite get everything I want because the time in the ds1307 doesn’t know what time zone it is in. The simplest way to handle this is to just set the time to the local time and forget this issue, but it will not look so simple when we change from/to daylight savings, or when I travel to a different time zone.
Besides, that extra non-volatile memory is quite attractive too, so I added a subclass of the DS1307TRC class called DS1307TRCE, which has a couple of extra methods to save and fetch stuff from that memory. In this case I pass a struct called config using this:
this reads from the extra memory and copies it into the config struct. There is a similar write1() method which does the opposite. What do I use this for here? I use it to hold the time zone as an offset from GMT. Having fetched the config struct I do this:
time\_t currentTime = now()+ (config.zone\*SECS\_PER\_HOUR);
That corrects the time. The current value for config.zone is +13, when we change to winter time it will be +12. I also store a string in the config struct but I don’t use it yet. I anticipate storing other stuff in there though, depending on how I want the eventual device to behave. This is nicer than hard coding things.
To change it I have another program which gets data from the serial interface. The development environment allows me to just type in stuff and it ends up in the config struct which I then write1() to the ds1307. But I might eventually build a UI on the eventual device so set what I want (when I have decided what I want it to do…)