DS1307 and DS3231 RTC’s Running Fast

Ok,

So I made a clock. A Big Clock.

(The Veroboard Construction was Version 1, that used an Atmega328 uC. What a pain! If you do not have the supporting Circuitry (i.e. the USB Interface Chip to program), it is very difficult to update the program.)

Version 2 uses a Wemos D1 Mini Module, which gives me the easy programming interface, and the ability to do NTP Time Syncs, and I can also just do program updates through the Network.

    

Basically the uC uses a RTC Module to keep track of the time, and then pushes the outputs through Shift Register LED Drivers (Max6971), which then runs Segments made out of LED Strips.

The RTC Module keeps the realtime clock running, even when power is removed to the clock itself. So that whenever the clock is turned on, it has the right time (or that is what it was supposed to be doing).

On site, the clock was only powered for about 10 – 12 hours a week, and the rest of that time it was powered off, with the RTC just keeping track of time.

The problem I was having with the clock is that it was running fast, by that I mean a minute or so fast per week!. Trying additional decoupling caps on the RTC module did not help.

I originally was using a DS1307 RTC Module,

Which is not a Temperature Compensated device, so I expected it not to be completely accurate, but not to such an extent. So I tried another one of the same modules, same result.

Ok, some more research lead me to the DS3231 RTC Module,

Temperature Compensated, Internal Crystal Oscillator, with a rated accuracy of +- 2ppm (0 to 40deg). So that should be accurate to within 1 minute a year.

Tried it, and same result. 6 Weeks, and the clock was running 6 minutes fast!

Eventually a lot of googling helped me find my problem. Here is my code :

void loop () {
 while (CurrentS==PrevS) { //HOLD UNTIL SECOND TICKS OVER
 DateTime now = rtc.now();
 CurrentS = now.second();
 ...
 } //loop

Which means that the uC continually polls the RTC, and then only once the second bit changes, does the rest of the code run. This means that it is hammering the RTC module thousands of times a second. Which the RTC module does not like, and it causes the internal registers to glitch.

All I had to do was change the way my code worked, I enabled the square wave output on the RTC, and connected that to my uC. Which now meant the uC only queried the RTC when the seconds had changed

void loop () {
 sqwstate = digitalRead(RTCsqwpin);
 // compare the buttonState to its previous state
 if (sqwstate != lastsqwstate) {
  if (sqwstate == HIGH) { // We have had a Seconds Tick
   DateTime now = rtc.now();
   Serial.print(now.hour(), DEC);
   Serial.print(':');
   Serial.print(now.minute(), DEC);
   Serial.print(':');
   Serial.print(now.second(), DEC);
   Serial.println();

DoTime();
...
}

 

And Bingo, that fixed the problem. I last set that clock on the 29 January 2017. It is now 4 April 2017, and the clock is still accurate to within 1 second. so that is a Success.

Hope this little tip can help somebody else out.

P