Go Down

Topic: DS 1307 stays behind in time day by day... (Read 2 times) previous topic - next topic

stefanosfok

Hi All,

I am having an Arduino Uno Rev.3 connected with an RTC DS1307 and an LCD 2x16.
I am displaying the time and date using the RTC on the LCD.
After a week I noticed that the time displayed in the LCD and the time in my PC have a difference of a few minutes.
For example: PC time --> 11:04:17 and my RTC -->11:01:41
My RTC is not keeping the time as it should be but stays day by day a little behind from the "actual" time.
Do you have any ideas on how I can synchronize my RTC with my PC system time?

Many Thanks!

Jack Christensen

The Time library, http://www.arduino.cc/playground/Code/Time has a Processing sketch that runs on the PC for this purpose. Have not used it myself. I might search the forum a bit too, as this is a question that comes up occasionally and there are likely other solutions available.

BTW, if your example is typical of your actual observations, i.e. a 156 second difference in a week's time, that is an unusually large error (258 ppm). I'd expect a DS1307 to be more accurate than that by a factor of ten or more. It might be worth posting your code. (I'm assuming the PC is being kept accurate via NTP, etc.)

Quote
After a week I noticed that the time displayed in the LCD and the time in my PC have a difference of a few minutes.
For example: PC time --> 11:04:17 and my RTC -->11:01:41


MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Riva

I have always found the DS1307 to be a poor keeper of time.
The way I improved the timekeeping in a standalone project with no computer connection was to work out how much time the RTC loses per day and then at the midnight hour add to the current RTC time and save it. You could modify this to update hourly instead of daily.

Code: [Select]
//Enumerations
const int driftComp = 9;    //Seconds to adjust clock by per day to compensate for RTC drift
const int delayComp = 500;  //Micro seconds to delay clock adjust by (driftComp * 1000) - delayCom = 8.5 seconds per 24 hours

void adjustClock(){
    static boolean driftApplied = false;

    RTC.readClock();
    int h=RTC.getHours();

    // RTC Drift compensation
    if(h == 0)                              //Is it the midnight hour
    {
        if(!driftApplied) {                 //Have I already done drift compensation
            int seconds = RTC.getSeconds(); //Get seconds
            seconds = seconds + driftComp;  //Apply drift
            delay(delayComp);               //Apply delay
            RTC.setSeconds(seconds % 60);   //Put seconds
            RTC.setClock();                 //Set clock
            driftApplied=true;              //Signal drift applied
        }
    }
    else{                                   //Not midnight hour
        driftApplied = false;               //Reset drift applied
    }
}

stefanosfok

Thank you Jack and Riva for your answers.
Riva because I am quite new to the Arduino. How can I use your code?
What I am asking is how can I use void adjustClock() function on my program?

My code is a very simple code and i state it below:
Code: [Select]

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib
#include <LiquidCrystal.h>
#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;
LiquidCrystal lcd(12, 11, 10, 5, 4, 3, 2);
void setup () {
 
  lcd.begin(16, 2);
  lcd.clear();
  Serial.begin(57600);
  Wire.begin();
  RTC.begin();

  if (! RTC.isrunning()) {
    Serial.println("RTC is NOT running!");
    // following line sets the RTC to the date & time this sketch was compiled
    //RTC.adjust(DateTime(__DATE__, __TIME__));
  }

}

void loop () {
   
  DateTime now = RTC.now();
   
  lcd.clear(); // Clear the LCD screen
  lcd.print("Time: ");
  if (now.hour() < 10) lcd.print("0"); // Check if we need to add leading zero
  lcd.print(now.hour(), DEC); // Output current hour
  lcd.print(":");
  if (now.minute() < 10) lcd.print("0"); // Check if we need to add leading zero
  lcd.print(now.minute(), DEC); // Output current minute
  lcd.print(":");
  if (now.second() < 10) lcd.print("0"); // Check if we need to add leading zero
  lcd.print(now.second(), DEC);
  lcd.setCursor(0, 1);
  lcd.print("Date: ");
  if (now.day() < 10) lcd.print("0"); // Check if we need to add leading zero
  lcd.print(now.day(), DEC); // Output current hour
  lcd.print(":");
  if (now.month() < 10) lcd.print("0"); // Check if we need to add leading zero
  lcd.print(now.month(), DEC); // Output current minute
  lcd.print(":");
  if (now.year() < 10) lcd.print("0"); // Check if we need to add leading zero
  lcd.print(now.year(), DEC);
 
  Serial.println();
  delay(1000);
  lcd.clear();
}


Thank you!!!

Jack Christensen

Well the code does seem pretty straightforward. DS1307 accuracy is governed by the crystal's accuracy, circuit layout, and temperature. Many crystals used with DS1307s have specs of ±20 or ±30 ppm. My expectation would be for the circuit to operate reasonably close to that. While I don't consider 20-30 ppm to be great accuracy, practically, it's probably OK for many applications, but represents a minimum standard IMHO.
MCP79411/12 RTC ... "One Million Ohms" ATtiny kit ... available at http://www.tindie.com/stores/JChristensen/

Go Up