DS1307 returning incorrect time / date

Hi Guys,

I am having an issue that I was wondering if anyone has seen before. I am using a DS1307 with an Arduino Due as a RTC. Its is connected via I2C, which I also have an EEPROM chip (M24M02-DR) on. They have different addresses. I am using the RTClib (JeeLabs) library to set the time using rtc.adjust(). I then read the values back from the DS1307 using now() a few time a second and store them as year, month, day, hour, minute, second and unixTime. I use the values as they change for delays etc. in my code.

All of this works perfectly but every once in a while the the values returned from the DS1307 are incorrect, This is extremely rare but when it occurs it seems to freeze the DS1307 as all values returned by now() from then on are the same. Polling the power to the Arduino fixes the issue and now() immediately starts to return the correct values.

An example of this occurring would go as follows,

  • I set the the time and date on the DS1307 to 05/03/2021 at 12:50:00
  • I read this back from the clock and display it on the LCD as 05/03/2021 12:50:00
  • A few time a second I check if the value has changed and if so the display is updated
  • After a few weeks or months of working perfectly the date/time returns from the DS1307 as 21/21/2021 21:21:21
  • The code continues to run correctly reading and display I/O etc but the values returned from the now() function call is always 21/21/2021 21:21:21

I would really like to figure out what could be causing the DS1307 to return the incorrect values, as some of the code I run relies on the time for delays. My issue is that I cannot recreate the problem and it occurs randomly so it is very hard to come up with a fix for it that I could test. I have multiple copies of my hardware setup and running and it will eventually occur on most of them even if it takes months to happen so I can confirm that its not a faulty piece of equipment. Any thoughts or suggestions on this would be greatly appreciated.

Update: Turns out the info wasn't fully correct, the clock being used is actually a DS3231. I thought it was a DS1307 as that is how it is declared in the software (I didn't set the hardware up). So it turns out the library I am using (attached as RTClib1) was created for the DS1307 and I am using it on a DS3231. I have compared it to a branch of itself (attached as RTClib2) which was created by adafruit to work with other RTC's including the DS3231. There are some small differences but I don't think they would cause the issue mentioned as they are addressed (0x68) the same. I have also included the RTC circuit which is connected to the SDA and SCL pins of the due micro controller. Again any thoughts or suggestions on this would be greatly appreciated

RTClib1.cpp (9.2 KB)

RTClib.h (2.93 KB)

RTClib2.cpp (63.7 KB)

RTClib2.h (18.4 KB)

Please post the code.

There is no need to access the RTC several times per second, look at the Time library for examples of synchronizing a software clock with the RTC at intervals.

Hi david_2018, thanks for the reply, I will definitely look into the examples of synchronizing a software clock with the RTC at intervals. I actually cant post the code as I am not allowed to do so (I am not the original creator), it is also extremely complex and contained in hundreds of .cpp/.h files, with thousand and thousand of lines of code, so I wouldn't expect anyone to dig through it. I understand this is not helpful but the code I use to read / write to the clock works perfectly. I was just trying to see if anyone has had a similar issue when using the DS1307 and had any ideas why this issue would occur in general, for example if I had two I2C devices using the same address etc. Thank you again for your reply

In general: Don't use the Due.

When you buy a cheap DS1307 module, then it has a cheap crystal.
Can you try a DS3231 ? That one has the crystal inside the chip.

Do you use a breadboard ? They have often bad contacts.
Do you use SDA next to SCL in a flat ribbon cable ? That is not okay.

I suggest to remove the 1k5 or 1k pullup resistors from the Due board and see what happens.
If you are afraid to damage the Due board, then at least measure the sink current. See at the bottom of this page I wrote. The sink current should be below 3mA.

We don't mind 10000 lines of code. We also really would like to see your code to interface with the RTC. There are many bad Arduino sketches online, and when it comes to the Wire library, well, what can I say, try this search: github issues "no need to wait" - Google Search

Hi Koepel,

Thank you so much for the reply. I am actually working on a project that someone else has built. It is a custom PCB board that used the DUE micro controller so all connections are on the PCB. I spoke to him just now and it turns out the the clock were using is in fact a DS3231 (labeled incorrectly in the software). I have attached a image of the clock connections on the PCB.

After I found this out I looked back at the code and the person who wrote it used the JeeLabs RTCLib library and used all the code that was created for the DS1307. So when we call functions like begin, adjust or now they are called from a library initially written for the DS1307. I have compared this to the adafruit library which is a branch of the JeeLabs original RTCLib and there are some small differences but I don't think they would cause the issue mentioned as they are addressed (0x68) the same etc. I have attached the library I am currently using as RTClib1 and the adafruit one as RTClib2 in case anyone wanted to look over it to see if they think using the original JeeLabs may be an issue. The only functions I currently use from the RTClib are begin, adjust and now.

Also thank you for the link on the I2C, it is excellent .

There is no need to access the RTC several times per second, look at the Time library for examples of synchronizing a software clock with the RTC at intervals.

Constantly banging on the i2c bus with a rtc.now() is bound to produce a lock up at some point.

In my experience an architecture which uses the time library synchronized to the rtc and reads the time from the local processor is far more reliable.

@cattledog thanks for the reply. I am 100% going to look into this. When I started working on the code it called rtc.now() 10 times a second. I did half that to 5 and will probably reduce it again. Do you know of any good examples that use the time library synchronized to the rtc and read the time from the processor that I could start with. Sounds like a much better solution

Here is an example of using the Time Library with synchronization to an rtc using the syntax of RTClib. The default syncronization interval is 5 minutes. See the Time Library documentation for how to set a different synch interval. Time Library, Timekeeping and Time/Date Manipulation on Teensy

#include <Wire.h>         //http://arduino.cc/en/Reference/Wire (included with Arduino IDE)
#include "RTClib.h"
#include <TimeLib.h>         //http://www.arduino.cc/playground/Code/Time  
//RTC_DS1307 RTC;
RTC_DS3231 RTC;

uint32_t syncProvider()
{
  return RTC.now().unixtime();  //either format works
}

void setup(void)
{
  Serial.begin(9600);
  Wire.begin();
  RTC.begin();
  setSyncProvider(syncProvider);//the function to get the time from the RTC
  if(timeStatus() != timeSet) 
    Serial.println("Unable to sync with the RTC");
  else
    Serial.println("RTC has set the system time");      
}

void loop(void)
{
  timeDateDisplay();  
  delay(1000);
}

void timeDateDisplay(void)
{  
  Serial.print(dayShortStr(weekday()));
  Serial.print(" ");
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(' ');
  Serial.print(month());
  Serial.print("/");
  Serial.print(day());
  Serial.print("/");
  Serial.print(year()); 
  Serial.println(); 
  Serial.print("Unix Time ");
  Serial.println(now());
  Serial.println();
}

void printDigits(int digits)
{
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(':');
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

To find the cause of the problems, we need a lot more information.
Was the schematic of the Due copied ? Are those pullup resistors on your board as well ? Did you measure the sink current ? Is the DS3231 running at 3.3V ? What else is connected to the I2C bus ? Are there ground loops ? and so on. There are so many things that we don't know.

The I2C bus should work 100% all the time. Always. I really don't care how often you use the I2C bus. I guess I disagree with cattledog. I also prefer to choose either the TimeLib or the RTClib, not both.