RTC resets to sketch upload time

Hi,

I'm using this code w/ DS1307 RTC:

void setupRTC () {
  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(F(__DATE__), F(__TIME__)));
  }
}

It only prints "RTC is NOT running!" the first time I upload it. However, every time I pull the power from the Arduino and then restart it, the RTC clock resets, not to 2000-01-01 00:00:00, but instead to the sketch compile time "F(DATE)", and "F(TIME)".

I'm not clear how it can be resetting, if the RTC is running, and the RTC must be running since the "NOT running" line isn't being printed, right?

I know many people explain you need to upload the sketch 2x, the second time with that "rtc.adjust(...)" line commented, but I think that is only if that line isn't in the "if (! rtc.isrunning())" statement, right?

Instead of checking if the clock is running or not check the year and if it’s zero then the clock is probably not set or it’s the year 2100 already.

Both the 1302 & 1307 have a flag (CH, bit 7 of the seconds register)) that indicates that the oscillator has been halted, either deliberately or otherwise.

You code checks the state of the flag:

if (! rtc.isrunning()) {

and if the clock isn't running it sets it to the date and time the sketch was compiled.

So - you are either setting the flag or the chip is losing power and it is set when power is restored.

Hi Dan,

“rtc.isrunning()” is always TRUE, since the code inside that loop never runs. My full code is below. This creates a “LOGGERnn.CSV” file each time I reset the power, and the timestamps always restart at the same place. To me this means, 1) The RTC battery works, and the RTC runs, since it never resets to 2000-01-01 00:00:00, but 2) when the USB power is pulled, it doesn’t keep clicking forward, it resets to the last time it was set. But it doesn’t do that in the loop you pointed out, because the PRINT statements don’t happen…

//import libraries
#include <OneWire.h>
#include <DallasTemperature.h>
#include <RTClib.h>
#include <Wire.h>
#include <SD.h>
#include <SPI.h>


#define ONE_WIRE_BUS 9      // Thermometer pin #
const int chipSelect = 10;  // SD card is always on 10

// Set up a oneWire instance to communicate with any OneWire device
OneWire ourWire(ONE_WIRE_BUS);
DallasTemperature sensors(&ourWire);
RTC_DS1307 rtc;
File dataFile;


void setup() {
  Serial.begin(57600);
  setupSD();
  setupRTC();
  setupTemp();
}


void loop(void) {
  loopTemp();
  loopRTC();
  dataFile.flush();
  delay(1000);
}


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


void setupSD() {
  //Serial.print("Initializing SD card...");
  // make sure that the default chip select pin is set to
  // output, even if you don't use it:
  pinMode(SS, OUTPUT);
  
  // see if the card is present and can be initialized:
  if (!SD.begin(10, 11, 12, 13)) {
   // Serial.println("Card failed, or not present");
    while (1) ; // Wait forever since we cant write data
  }
  //Serial.println("card initialized.");

  dataFile = SD.open("LOGGER.CSV", FILE_WRITE);
  // Open up the file we're going to log to!
  // Pick first unused file
  char filename[] = "LOGGER00.CSV";
  for (uint8_t i = 0; i < 100; i++) {
    filename[6] = i/10 + '0';
    filename[7] = i%10 + '0';
    if (! SD.exists(filename)) {
      // only open a new file if it doesn't exist
      dataFile = SD.open(filename, FILE_WRITE); 
      break;  // leave the loop!
    }
  }
}


void setupTemp(void) {
  sensors.begin();
}


void loopTemp() {
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println(sensors.getTempCByIndex(0));
  dataFile.print(sensors.getTempCByIndex(0));
  dataFile.print(", ");
}


void loopRTC() {
    DateTime now = rtc.now();
    String timeStr = String(now.year()) + ", ";
    timeStr = timeStr + String(now.month()) + ", ";
    timeStr = timeStr + String(now.day()) + ", ";
    timeStr = timeStr + String(now.hour()) + ", ";
    timeStr = timeStr + String(now.minute()) + ", ";
    timeStr = timeStr + String(now.second());
    Serial.println(timeStr);
    dataFile.println(timeStr);
}

mankoff: ...when the USB power is pulled, it doesn't keep clicking forward, it resets to the last time it was set

The RTC has no way to reset to some previous arbitrary time on its own. If it's doing that it's because your code is setting it.

Post your log files.

Log file LOGGER00.CSV is:

25.75, 2015, 9, 10, 14, 44, 19
25.75, 2015, 9, 10, 14, 44, 21
25.75, 2015, 9, 10, 14, 44, 23
25.75, 2015, 9, 10, 14, 44, 24
25.75, 2015, 9, 10, 14, 44, 26

I last ran "rtc.adjust(DateTime(F(DATE), F(TIME)));" at 14:44 (~30 minutes ago). The device has been powered off since then. I just plugged it in now at the time of this post, 15:17, but the time is 14:44 from the RTC.

If I plug and unplug it 10x, I'll get ten "LOGGERnn.CSV" files, and each will start at 2015 09 10 14 44 19 (the 19 will change by a second or two, I think because startup sometimes happens a bit slower.

I jus did it a again (3 minutes later it is now 15:20), created LOGGER01.CSV, which contains:

25.69, 2015, 9, 10, 14, 44, 19
25.75, 2015, 9, 10, 14, 44, 21
25.75, 2015, 9, 10, 14, 44, 23
25.75, 2015, 9, 10, 14, 44, 24
25.75, 2015, 9, 10, 14, 44, 26
25.75, 2015, 9, 10, 14, 44, 28
25.75, 2015, 9, 10, 14, 44, 30
25.75, 2015, 9, 10, 14, 44, 32
25.75, 2015, 9, 10, 14, 44, 34
25.75, 2015, 9, 10, 14, 44, 35
25.75, 2015, 9, 10, 14, 44, 37
25.75, 2015, 9, 10, 14, 44, 39
25.75, 2015, 9, 10, 14, 44, 41

It's being set to the original time. It's weird that the "RTC is NOT runing! (sic)" message isn't showing up in the log, but sometimes bugs are weird, until you figure them out.

I would try: 1. Adding an else clause with a message to the log file that says "RTC is running". 2. Commenting out the rtc.adjust() call.

OK, you are right, it appears to not be running. But if it isn't running, then commenting out the adjust() call, means the clock is set to 2000-01-01 01:01:00.

The RTC battery is at 3 v. I've followed the instructions here to set this up: https://www.adafruit.com/products/1141

mankoff:
OK, you are right, it appears to not be running. But if it isn’t running, then commenting out the adjust() call, means the clock is set to 2000-01-01 01:01:00.

The RTC battery is at 3 v. I’ve followed the instructions here to set this up: https://www.adafruit.com/products/1141

Are you just guessing?

Try commenting out the adjust call and see what happens. Add an else statement and a print to the log as a control for your other statement. And measure the voltage at the battery pin on the RTC. Could you have put in a bad battery? Or upside down? There are so many ways to be wrong. Being wrong is normal.

No, not a guess. I did comment out the adjust call and see what happens. It prints "not running" and the time is 2000-01-01. I think it is a hardware issue, not a software issue as I previously assumed. Thank you for helping debug so far. I'll speak with my colleague who purchased and mounted the RTC shield.

I think what’s happening is the first time you plug in the RTC from power down state it is not running and the time gets set the oscillator started AND the ‘RTC is NOT running!’ message is printed. This all happens before you have time to connect the serial monitor to see the message.
When you connect the serial monitor the MCU resets but by now the oscillator is running so the time does not get set again.
To check this you could put a big (5 or 10 second) delay right at the start of setup after Serial.begin so you have time to open the serial monitor after applying power and before the first time the RTC check is run after power up.
I still think the method to use is checking the year for zero instead.

Please use code tags for future code posts.

I think the RTC code is working, since I get no compilation errors, and it runs (even if it resets after power loss). BUT I notice that the #include statement isn't syntax-highlighted like the other #include statements, and the GUI continues to "Recommend RTClib" even after it is #included.

Does anyone know why this occurs, and could this be part of the issue?

|500x472

What Riva posted makes sense except that the "not running" message doesn't show up in the log. But even ignoring that it doesn't explain why your RTC resets when you remove power. Something is probably wrong with the hardware.

Not all libraries are highlighted in the IDE. It's recommendation is probably just a bug. It isn't causing the RTC to reset.

jboyton: What Riva posted makes sense except that the "not running" message doesn't show up in the log. But even ignoring that it doesn't explain why your RTC resets when you remove power. Something is probably wrong with the hardware.

Not all libraries are highlighted in the IDE. It's recommendation is probably just a bug. It isn't causing the RTC to reset.

We have 4 of these shields and all of them are acting the same way. What could be some of the hardware issues? I went back through them along with the tutorial on soldering the headers on (the only thing I had to solder). What pins power and ground the RTC chip on the shield?

What shield?

I have a shield that used to have a DS1307 on it. It didn't have that problem.

Maybe I'm wrong and there's a problem with the library. Which RTClib is it?

Shield: https://www.adafruit.com/products/1141

Library: https://github.com/adafruit/RTClib

@bforsythe, the datasheet: http://datasheets.maximintegrated.com/en/ds/DS1307.pdf

Vcc = pin 8 Gnd = pin 4 Vbat = pin 3

Anything is possible, but it would be surprising if four of these were all defective or if the library and examples didn't work properly.

What happens when you upload the "ds1307" example sketch and then cycle the power? Does the displayed time keep resetting to the compile time or does it advance like it should?

Yes, what shield? It's clear that your chip is not running under battery power. There could be a circuit defect which you can test for if you can find the schematic for the shield. Vbat must show up at the chip pin.

It's also possible that even if Vbat is getting to the chip, there have been cases where fake ds1307's will not run under battery power.

http://forum.arduino.cc/index.php?topic=303406.0

@cattledog -- look at reply #15. It's an Adafruit board. It's unlikely that it's a fake DS1307.

All four boards being defective seems improbable, although not impossible. Are the batteries in upside down?

Could it be that we are testing w/ USB power? This thread makes it sound like that might be the problem. I don't have a battery (for the Arduino board, I do for the RTC) to test this.

http://forum.arduino.cc/index.php?topic=209057.0