DS1307 RTC adjust drift automatically

Nice work.

I imagine the DS1307 drift is going to be quite dependent on temperature. But as long as the temperature is relatively constant, you should be good to go.

Some day I'll try to do something similar with an Arduino, a radio receiver for the US time signal and the Chronodot... and then create a auto-correct function for the aging trim in the DS3231.

sbright33:
Let me know! The error seems consistent to me, so now there is much less error per day.

OK, I'll setup the clock and load the sketch this weekend. It will be at least 10 days plus a few more to monitor results before I post back to this thread with my results, but I will.

Thanks for writing and sharing this code!

Jake

You could guess after 2 days. I also wrote some code which is related to this. It uses GPS to measure and calibrate millis() and the Arduino clock within hours, no need to wait 100 days. So long as you keep it inside where the temperature is 60-80 degrees it is easy to obtain accuracy of 1ppm, which is about 1 seconds every 11 days. Or even 10ppm with some effort which is 1 second every 100 days, or 3 seconds per year. The only hardware you need for this code is GPS. I also have code which uses Wifly to do the same thing with NIST server.

If you've got the time, I can help you keep it!

Sounds good. I need to put the ds1307 on a breadboard this weekend and set the time. I'll let you know how it goes.

Thanks!

sbright33:
...Or even 10ppm with some effort which is 1 second every 100 days, or 3 seconds per year....

Pardon my ignorance. I thought lower PPMs were better than higher PPMs re: clock drift. Why would an increase to 10PPM drift be preferable to 1PPM? Did you perhaps mean 0.1PPM or 100PPB?

I thought the whole point of adjusting the aging trim in the DS1307 or DS3201 was to minimize the clock drift.

Of course my mistake 0.1ppm

sbright,

I have my cheap ds1307 setup. I'll be installing your code either tonight or tomorrow and will let you know how it works out.

Jake

Looks like I'll have to use a GPS receiver since sourcing the radio-based receivers appears difficult, plus I get the benefit of a GPS system, if I want it. The breakout board from adafruit appears enticing, it'll be interesting to see to what extent trimming the oscillator will work. What is the minimum time you think you need to trim with reasonable perfection? For something as accurate as the DS3231, I figured I'd need at least a month.

Using PPS pin you can measure 1us drift each second. So you get 1ppm in about...
1 second!

It makes more sense to wait 20 minutes and use 1ms drift method instead.

http://arduino.cc/forum/index.php/topic,120288

Sbright,

I have your code installed and it appears to be working :smiley: I'll monitor it for a few days.

Thanks,
Jeff

Hi Guys,

I have modified the Time and DS1307RTC Libraries to do drift correction and store the drift info in the RTC battery backed memory. I’ve also included an Arduino sketch to do the RTC time setting and drift calibration. Take a look at the link below if you’re interested.

Howard

http://limchonghan.wordpress.com/driftcorrectedds1307/

Code posted here about drifting of ds1307 is dead ! anybody have that code please share

http://limchonghan.wordpress.com/driftcorrectedds1307/

I saved it few years ago... and still have it ;D

Here
Project GitHub - gion86/PlantLight: Automatic light switch based on light sensor and date/time RTC
Library GitHub - gion86/DS1307_RTC: DS1307 Real time clock library for the ATTiny85 (ATTinyX5)
I made a little project with that code, slightly modified: it's working pretty well once you get the drift correction for you clock/oscillator...

DS1307 Drift Corrected.zip (26 KB)

@gion86

Thanks for sharing the code !

Can you please explain these 2 lines of code!

di.DriftDays = 1000;     // valid value 0 to 65,535
di.DriftSeconds = 2725;  // fine tune this until your RTC sync with your reference time, valid value -32,768 to 32,767

also how to calculate these values , if my clock is 6 sec/day fast.

Please explain any other code lines related to correction !

The variable DriftSeconds holds the "quantity" of second your clock is going to drift in DriftDays days. So if you clock is 6 sec/day fast you have to set:

di.DriftDays = 1;
di.DriftSeconds = 6;

If you clock was slow by 6 it should be (signed):

di.DriftDays = 1;
di.DriftSeconds = -6;

If you a have a not integer number of seconds you can multiply both variable by the same factor. So for example if you have 25.67 sec/day:

di.DriftDays = 100;
di.DriftSeconds = 2567;

In the internal of the library those 2 variables will be divided by each other:

float driftCorrection = float(rtcTime - driftInfo.DriftStart);
driftCorrection /= float(SECS_PER_DAY * driftInfo.DriftDays);
driftCorrection *= float(driftInfo.DriftSeconds);

In driftCorrection you will have the floating point number of seconds per day of you drift, which is then used to calculate the current time:

// due to conversion of driftCorrection to long, accuracy of time returned is +/- 0.5sec
time_t curTime = rtcTime - long(driftCorrection);

I have to make clear that this is not my code, but I took it from the blog post above
http://limchonghan.wordpress.com/driftcorrectedds1307/. But I have tested and I'm using in a project so I can say that is working. :wink:

I'm trying to run the above code, but unsuccessfully.

sketch_jul28a:34: error: 'tmDriftInfo' does not name a type

 tmDriftInfo di;


sketch_jul28a.ino: In function 'void setup()':

sketch_jul28a:48: error: 'di' was not declared in this scope

   di = RTC.read_DriftInfo();


sketch_jul28a:48: error: 'class DS1307RTC' has no member named 'read_DriftInfo'

   di = RTC.read_DriftInfo();

sketch_jul28a:51: error: 'class DS1307RTC' has no member named 'write_DriftInfo'

   RTC.write_DriftInfo(di); // once you're happy with the drift setting you only have to read the DriftInfo and pass it to now2() or now3() function to get your drift corrected time

sketch_jul28a.ino: In function 'void loop()':

sketch_jul28a:59: error: 'di' was not declared in this scope

   LcdDisplayDateTime(now3(di));

sketch_jul28a:59: error: 'now3' was not declared in this scope

   LcdDisplayDateTime(now3(di));

sketch_jul28a.ino: In function 'void processSerialCommand()':

sketch_jul28a:142: error: 'tmDriftInfo' was not declared in this scope

         tmDriftInfo diUpdate = RTC.read_DriftInfo();  // update DriftInfo in RTC

sketch_jul28a:143: error: 'diUpdate' was not declared in this scope

         diUpdate.DriftStart = newTime;

sketch_jul28a:144: error: 'class DS1307RTC' has no member named 'write_DriftInfo'

         RTC.write_DriftInfo(diUpdate);

sketch_jul28a:151: error: 'tmDriftInfo' was not declared in this scope

       tmDriftInfo diRead = RTC.read_DriftInfo();

sketch_jul28a:152: error: 'diRead' was not declared in this scope

       if (diRead.DriftStart == 0 | diRead.DriftDays == 0 | diRead.DriftSeconds == 0) {

sketch_jul28a:158: error: 'diRead' was not declared in this scope

       SerialDisplayDateTime(diRead.DriftStart); Serial.println();

exit status 1
'tmDriftInfo' does not name a type

You have to include the library in your project.
How are you compiling? With the Arduino IDE?

marthinius:
I'm trying to run the above code, but unsuccessfully.

You will note that this thread is pretty old, and I suspect rather pointless even when it was current. Inaccuracies in the DS1307 were down to lack of temperature compensation as much as hardware drift. If your fix does not provide temperature compensation, you are probably on a futile venture, which may explain why the original code is hard to find. In the meantime the price of the DS3231 has come down to much the same as the DS1307, and doesn't need all this stuff. If you need to be serious about clock accuracy, you might look at that.

Yes Nick_Pyner is right.
Newer models offer a clock with temperature compensated oscillator and that makes the difference.
I have switched to a Maxim DS3232 clock, and used this library which is very usefull:

Maybe we should close this thread...

Most definitely. It was a dumb thread in 2012.

I might point out that, if you just want to tell the time, the 3231 will run with DS1307 code. No changes required. I don't use any library, but this probably applies with libraries as well.