DS3231 is always 3 minutes behind computer clock

Hello,

I have been working on using an Arduino Uno and an RTC more specifically a DS3231 to control some led lighting among other things; however I noticed that every time I try to set the time to the RTC it is always 3 minutes behind my computer time. Even when I load the following example its still 3 minutes behind.

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

RTC_DS3231 rtc;

char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};

void setup () {

#ifndef ESP8266
  while (!Serial); // for Leonardo/Micro/Zero
#endif

  Serial.begin(9600);

  delay(3000); // wait for console opening

  if (! rtc.begin()) {
    Serial.println("Couldn't find RTC");
    while (1);
  }

  if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }
}

void loop () {
    DateTime now = rtc.now();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(" (");
    Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
    Serial.print(") ");
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
    
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now + TimeSpan(7,12,30,6));
    
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
    
    Serial.println();
    delay(3000);
}

I know the following two lines say
// following line sets the RTC to the date & time this sketch was compiled
rtc.adjust(DateTime(F(DATE), F(TIME)));

but I have hit compile them immediately hit upload, I expect it to be a few seconds off but not 3 minutes. I know I can do it manually but my understanding was that if I used rtc.adjust(DateTime(F(DATE), F(TIME))) it would set it to my computer time. Is there a better/more accurate way to automatically sync the RTC time with my computer time?

Joebob296

Instead of

    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

use something like:

rtc.adjust(DateTime(2018, 6, 20, 17, 10, 30));

Set the above time to be slightly ahead of whenever you decide to hit the "upload" button. With a little trial and error, you can end up with the RTC time within a couple of seconds of the PC time.

Well yes, but I was specifically asking for a way to do this automatically. I could do it manually but I'm wondering why it wont sync correctly with my computer time.

The Arduino does not "sync" with the computer. When the program is uploaded, the compiled-in time is no longer current.

Once you have set the time, with proper battery backup on the RTC, it should be valid for years.

joebob296:
I have been working on using an Arduino Uno and an RTC more specifically a DS3231 to control some led lighting among other things...

You might be able to do all of that with an ESP8266 based board, depending on "the other things".
An ESP8266 (Wemos D1 mini, NodeMCU, etc.) can automatically get time (NTP) from the internet (like your PC).
And control the LED lighting, etc.
No RTC needed.
Leo..

Have you got an LCD display and two buttons?

If you do, you might want to try this:
https://forum.arduino.cc/index.php?topic=408565.msg2823857#msg2823857

With that, it is quick and almost stupidly easy to set the date and time. (Try it!)
Besides which, a DS3231 is so accurate, how often do you expect to have to set it? No, really, it is accurate to within 1 minute per year.

If it is Daylight Saving Time adjustments that concern you, there are ways to have the Arduino make the adjustments for you based on the date. Either that, or you could include a simple "spring forward / fall back" toggle switch in your project.

if (rtc.lostPower()) {
    Serial.println("RTC lost power, lets set the time!");
    // following line sets the RTC to the date & time this sketch was compiled
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
    // This line sets the RTC with an explicit date & time, for example to set
    // January 21, 2014 at 3am you would call:
    // rtc.adjust(DateTime(2014, 1, 21, 3, 0, 0));
  }

Your setting routine is nested within a conditional statement which I don't believe will be true. Your code is not actually changing the time in the rtc.

It tests bit 7 of the status register: Oscillator Stop Flag

bool RTC_DS3231::lostPower(void) {
  return (read_i2c_register(DS3231_ADDRESS, DS3231_STATUSREG) >> 7);
}

Bit 7: Oscillator Stop Flag (OSF). A logic 1 in this bit indicates
that the oscillator either is stopped or was stopped
for some period and may be used to judge the validity of
the timekeeping data. This bit is set to logic 1 any time
that the oscillator stops. The following are examples of
conditions that can cause the OSF bit to be set:

  1. The first time power is applied.
  2. The voltages present on both VCC and VBAT are insufficient
    to support oscillation.
  3. The EOSC bit is turned off in battery-backed mode.
  4. External influences on the crystal (i.e., noise, leakage,
    etc.).
    This bit remains at logic 1 until written to logic 0.
1 Like

Thank you cattledog! That information was very helpful, the RTC is now withing one second. You were correct, I set the rtc the first time and every time I uploaded after that the code did not set the rtc due to the fact that the RTC never lost power due to the battery backup; which was exactly should of happened.

I removed the battery, disconnected the power supply for 1 minute then uploaded the program and then inserted the battery and and was within 1 second. I know I could get it closer with trial and error but for my application 3 minutes was good enough, it was more of a why isn't this working as the example stated...it was a lack of programming knowledge on my part; not the code.

Thank you,

Joebob 296