Set RTC to compile time, but RTC not retaining time after power cycle.

Linus/Unix issue?
http://forum.arduino.cc/index.php?topic=179213.msg1334184#msg1334184

Your code appears to set the arduino date/time back to the compile-time values each time it starts. I don't think you ever actually set the time IN theDS3231 nor are you telling the Arduino to READ the time from the RTC (as the syncprovider).

A sketch I wrote:

#include "arduino.h"

#include "Wire.h"
#include <Time.h>
#include "DS3231RTC.h"

DS3231RTC RTC3231;
tmElements_t tm;
void setup()
{
  Serial.begin(9600);
  tm.Year=2013 - 1970;
  tm.Month = 7;
  tm.Day = 30;
  tm.Hour= 19;
  tm.Minute = 57;
  tm.Second = 0;
  
//  RTC3231.write(tm);
  setSyncProvider(RTC.get);   // 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()
{
  Serial.print("Temp: ");Serial.print(RTC3231.getTemp()*1.8+32); Serial.println();
  Serial.print("Time: ");
          Serial.print(month()); Serial.print(" ");
          Serial.print(day()); Serial.print(" ");
          Serial.print(year()); Serial.print(" ");
          Serial.print(hour()); Serial.print(" ");
          Serial.print(minute()); Serial.print(" ");
          Serial.print(second()); Serial.print(" ");
          Serial.println();
  delay(1000);
}

I downloaded GitHub - trunet/DS3231RTC: An arduino library for DS3231 Real-time clock to support the DS3231

The RTC time is set initially with:

RTC3231.write(tm)

Moderator edit:
</mark> <mark>[code]</mark> <mark>

</mark> <mark>[/code]</mark> <mark>
tags added.

the idea is to set DATE and TIME just the once
then remove the code

I have exactly the same problem: RTC works fine as long as it is powered via Vcc however, it does not retain the time when powered off.

I have RTC module ZS-042 and I have:

  1. removed the diode of the battery charging circuit
  2. put a CR2032
  3. checked the charge of the battery with a 400ohms load and reads fine (3V)
  4. I have checked DS3231's leg-14 and it gives 3V

Could it be I have got a faulty RTC unit?

Take a look at the value set in Bit 7 of Control Register 0Eh. It should be set to 0.

From the data sheet:

Control Register (0Eh)
Bit 7: Enable Oscillator (EOSC). When set to logic 0,
the oscillator is started. When set to logic 1, the oscillator
is stopped when the DS3231 switches to VBAT. This
bit is clear (logic 0) when power is first applied. When
the DS3231 is powered by VCC, the oscillator is always
on regardless of the status of the EOSC bit. When
EOSC is disabled, all register data is static

http://datasheets.maximintegrated.com/en/ds/DS3231.pdf

Hi,

I use this library:

But is there a way to set the time into the rtc 'live' while running?

Everytime I use: (for example)

setTime(13, 12, 11, 2, 11, 2014);
RTC.set(now());

the program 'hangs' and time is not progressing anymore....after a reset time is displayed again as before but not updated/adjusted.

Using only setTime seems like to work but I think it's not saved/written to the rtc......

I can not confirm what you observe. Here is a sketch which uses setTime to set the clock on the Arduino and then uses RTC.set(now()) to set the RTC with that time. The RTC does not hang.

#include <Wire.h>
#include <Time.h>
#include <DS3232RTC.h>

tmElements_t tm;

void setup() {

  Serial.begin(9600);

  Serial.println("Setting time on Arduino");
  setTime(13, 12, 11, 2, 11, 2014);//setting AVR time
  displayAVR_Time();
  Serial.println();
  Serial.println("Settting time on RTC from Arduino");
  RTC.set(now());//setting RTC to AVR_Time
  displayRTC_Time();
  Serial.println();

  Serial.println("DS3231RTC Read Test");
  Serial.println("-------------------");
}

void loop() {

  displayAVR_Time();
  displayRTC_Time();
  Serial.println();
  delay(1000);
}

void displayAVR_Time(void)
{
  Serial.print("AVR Time = ");
  Serial.print(hour());
  Serial.write(':');
  print2digits(minute());
  Serial.write(':');
  print2digits(second());
  Serial.print(", Date (D/M/Y) = ");
  Serial.print(day());
  Serial.print('/');
  Serial.print(month());
  Serial.print('/');
  Serial.print(year()); 
  Serial.println(); 
}

void displayRTC_Time()
{
  RTC.read(tm);//TimeElements variable
  Serial.print("RTC Time = ");
  print2digits(tm.Hour);
  Serial.write(':');
  print2digits(tm.Minute);
  Serial.write(':');
  print2digits(tm.Second);
  Serial.print(", Date (D/M/Y) = ");
  Serial.print(tm.Day);
  Serial.write('/');
  Serial.print(tm.Month);
  Serial.write('/');
  Serial.print(tmYearToCalendar(tm.Year));
  Serial.println();
}

void print2digits(int number) {
  if (number >= 0 && number < 10) {
    Serial.write('0');
  }
  Serial.print(number);
}

Using it within the setup() it works just fine, but for example on some button presses it doesn't.

Would like to adjust the clock 'live' and not by programming it again....

Creamers,

There are many examples found with Google search about using a button or buttons to adjust the time on an RTC.

Check them out, and if you want to pursue this further, please start a new thread about changing the time setting on an RTC from button presses, and be sure to post your code using the code tags.

Hi cattledog,

thanks to your suggestion I have set now bit-7 of 0E register to zero.

What I observe now is that when I turn Vcc off the clock stops ticking, so when Vcc is on again the clock starts ticking from the minute that I switched Vcc off.

I have also set bit-7 of register 0F to zero to check Oscillator Stop Flag (OSF). I can see it keeps zero after turning Vcc off/on.

Any idea of why the clock stop ticking when it goes from Vcc to VBat?

Tamadite,

If you have done it correctly, I don't think the problem is in your settings. You have the oscillator enabled, and the device does not think the oscillator stops, that is, the oscillator stop flag is not being set when Vcc is removed.

If you disable the oscillator, does the flag get set?
If you remove Vcc and the battery, does the flag get set?

Did the module work correctly before you removed the diode and changed the battery?

I have the same module, and it works fine with a LIR 2032 and the diode in place. I have seen advice about cutting the trace between the diode and R5 to avoid overcharging, but so far i have not seen any problems.

cattledog,

yes to your two first questions.

Concerning the third, I would say that everything worked fine until the CR2032 that came with it exploded for obvious reasons. However, I cannot not categorically say that it worked. I would rather say that I noticed the problem after the battery exploded.

The timer failed with Vbat also with the diode connected (after the explosion).

What I am going to do now is to order a new one from a provider that sales it with a LIR2032.

Thanks for supporting my troubleshooting!

I do not know if am suffering an overdose of bad luck. I have got my new DS3231 with a LIR2032 battery but I do still have the same problems as with the old one that is, the time gets lost when the power supply gets unplugged.

This is the status of the registers I get when I unplug the power supply:

0x0E: 28d (00011100)
0x0F: 8d (00001000)

Any idea?

@Tamadite--

Sorry to hear that your problems persist with the new module. Is it the same ZS 042 module Please post the code that you are using to initially set the time on the RTC. If you are using a ds3231/3232 library, please reference the source for that library.

If you leave the power connected to the Arduino and run a different sketch which doesn't use the RTC and then come back to a sketch using time from the RTC, is the time correct?

When you say that the "time gets lost" does it mean that it restarts from the time when the power was removed?

Are you sure that the new battery is good? Is there a way that you can test it in some other battery powered device?.

I have also seen postings about defects in the battery holders which have poor grounds

@cattledog

yes, I use module ZS042. I have tested the charge of the battery with a 400ohms load showing more than 3volts so it seems the battery is Ok.

I have also checked the battery voltage on the circuit -not on the battery holder, showing also the same good battery value (>3V).

When I run a different sketch that does not make use of the RTC to later load up back the sketch that exploits the RTC's features, then I can observe the clock is still on time, no changes/deviations.

"time gets lost" was a good question! Actually what I can observe is that when I do a power cycle (unplug/plug power) on the unit, the clock starts from the original configuration time that is, if the clock got originally set at 21:00 and then I do a power cycle at 21:10 then the clock starts again at 21:00. On certain occasions it gets completely off that is, it starts at a what seems to be a random/garbage time. Unfortunately I cannot reproduce this behavior; it just happens. None of these behaviors set the bit-7 of 0F register to 1.

I have also noticed that I get bit-7 of register 0F to flag 1 only when I take off the battery while the unit is unplugged. No any other circumstance makes bit-7 to flag 1.

Here you go the sketches I use to read and write registers on the RTC. As you can see, I only use the <Wire.h> library to read/configure:

// === replace 0x0F by 0x0E to read 0E register ===
// Reads register 0Fh

#include <Wire.h>
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  
  Wire.beginTransmission(0x68); // 104 is DS3231 device address
  Wire.write(0x0F); // start at register 0F
  Wire.endTransmission();
  Wire.requestFrom(0x68, 1); // request one byte
  if(Wire.available()) {
    Serial.println("Reading data...");
    byte b;
    b = Wire.read();
    Serial.print("Current Register Value (0F): ");
    Serial.println(b);
  }else{
    Serial.println("RTC not availabe!");
  }
  Wire.endTransmission();
}
 
void loop()
{}
// Clears bit-7 of register 0Fh

#include <Wire.h>
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  
  Wire.beginTransmission(0x68); // 104 is DS3231 device address
  Wire.write(0x0F); // start at register 0F
  Wire.endTransmission();
  Wire.requestFrom(0x68, 1); // request one byte
  
  if(Wire.available()) {
    Serial.println("Reading data...");
    byte b;
    b = Wire.read();
    Serial.print("Current Register Value (0F): ");
    Serial.println(b);
    b = b << 1;
    b = b >> 1;   // clears bit-7
    Wire.beginTransmission(0x68); // 104 is DS3231 device address
    Wire.write(0x0F); // start at register 0F
    Serial.print("New Register Value (0F): ");
    Serial.println(b);
    Wire.write(0b00001000); // write register   
  }else{
    Serial.println("RTC not availabe!");
  }
  Wire.endTransmission();
}
 
void loop()
{}
// Clears bit-7 of register 0Eh

#include <Wire.h>
 
void setup()
{
  Wire.begin();
  Serial.begin(9600);
  
  Wire.beginTransmission(0x68); // 104 is DS3231 device address
  Wire.write(0x0E); // start at register 0E
  Wire.endTransmission();
  Wire.requestFrom(0x68, 1); // request one byte
  
  if(Wire.available()) {
    Serial.println("Reading data...");
    byte b;
    b = Wire.read();
    Serial.print("Current Register Value (0E): ");
    Serial.println(b);
    b = b << 1;
    b = b >> 1;   // clears bit-7
    Wire.beginTransmission(0x68); // 104 is DS3231 device address
    Wire.write(0x0E); // start at register 0E
    Serial.print("New Register Value (0E): ");
    Serial.println(b);
    Wire.write(0b00011100); // write register   
  }else{
    Serial.println("RTC not availabe!");
  }
  Wire.endTransmission();
}
 
void loop()
{}

On the sketch that exploits the RTC features, I make use of <Wire.h>, <RTClib.h> and <Time.h> libraries. For instance:

RTC_DS1307 RTC;		
DateTime now;	

void setup() {
  Wire.begin();
  RTC.begin();
  now = RTC.now();
  RTC.adjust(DateTime(__DATE__, __TIME__));
}

void loop()
{}

Post the full code which uses

RTC.adjust(DateTime(__DATE__, __TIME__));

to set the RTC to the sketch compile time.

After you set the RTC, run the code again with the RTC.adjust() line commented out.

Then try your power cycles. I think that you are resetting the rtc to the original compile time.

@cattledog

My goodness! I am happy I am not working for NASA sending rockets to planet Mars!!!

Stupid me, I was convinced the problem was on the RTC module without questioning the code. Your magic sentence "I think that you are resetting the rtc to the original compile time" got all my bells to ring... I told to myself: "sure that is the problem! I am aware I am doing that but unfortunately I had not related it to the problem".

The time on the RTC was set at compilation time. After a power cycle the setup() was again setting it up to "who knows" because there was no reference to take the time from.

Now I have modified the code -the time is not any longer set by the setup(), and everything works as expected that is, the time is kept even after a power cycle.

I am pretty much sure the old RTC works properly too.... just SBK.

Thank you so much! :slight_smile:

Could you post your final code? I am at a loss of how to set the clock initially and not reset the clock after a power cycle... Seems you got it nailed down.

how to set the clock initially and not reset the clock after a power cycle...

If you have the same situation as Tamadite, (the RTC resetting to the time the sketch was initially compiled) then once you set the time in the RTC, you need to comment out the line in our code which is setting it.

Ah! I missed it was a manual process -- didn't realize it was an "upload time" "re-upload sketch w/o set time"

The battery issue is confusing - seems the (z5-042) comes "defective" and you've got to cut a trace for it to make sense to work as sent (with a battery) -- really assumed there would be logic there to use the battery for backup only (ie: arduino host power down/sleep, battery would switch over)...
Seems you have to reset the time anytime you change the battery, not a big deal, just assumed it would be smarter -- and we all know what happens when one assumes...

Thanks,
... dj