Go Down

Topic: Set RTC to compile time, but RTC not retaining time after power cycle. (Read 2580 times) previous topic - next topic

Ashton

I'm revisiting an annoying problem I've had for a while, having my DS3231 RTC keep the correct time during power off.  Plus each time I compile I need the RTC (fresh new or existing pre-set) to be set to compile time, even if it is already running.  Most of the examples I have use something similar to:
Code: [Select]
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__));
}



My full code is as follows:
Code: [Select]
// Daily Alarm Test using DS3231 RTC
//
#include <Wire.h>
#include "RTClib.h"
#include <LiquidCrystal_I2C.h>
#include <Time.h>
#include <TimeAlarms.h>
LiquidCrystal_I2C lcd(0x27,20,4);
RTC_DS1307 RTC;
time_t syncProvider()
{  return RTC.now().unixtime(); }

void setup () {
 Wire.begin();
 RTC.begin();
 setSyncProvider(syncProvider);
//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__)); //Set RTC to compile time
//  }

Alarm.alarmRepeat(8,0,0, Event1);  // Daily event time 24 Hr
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
pinMode(7, OUTPUT); // Daily test output to controller zone
digitalWrite(7, HIGH); //Turn on Q3 Transistor
}

void loop () {
clockDisplay();
Alarm.delay(1000);
}

void clockDisplay(){
 DateTime now = RTC.now();
 char buf[20];  // -------------------- RTC Time --------------------
 sprintf(buf, "%02d:%02d:%02d %02d/%02d/%4d", now.hour(), now.minute(), now.second(), now.month(), now.day(), now.year());
 lcd.setCursor(0,0);
 lcd.print(buf);

char buf1[20];  // ------------------  Arduino Time -----------------
sprintf(buf1, "%02d:%02d:%02d %02d/%02d/%4d", hour(), minute(), second(), month(), day(), year());
lcd.setCursor(0,1);
lcd.print(buf1);
}  

void Event1(){ // *********** Daily Alarm Output ****************
 digitalWrite(7, LOW);  //alarm test output
 delay(4000);
 digitalWrite(7, HIGH); }


Could it be that the DS3231 doesn't set correctly using the DS1307 commands, etc.?
These are new RTC units, the battery voltages are 3.29-3.3V

mrburnette

Quote
Could it be that the DS3231 doesn't set correctly using the DS1307 commands, etc.?


Sounds like a dead backup battery (or one not charging if rechargeable.). Try sample code.



http://playground.arduino.cc/Code/time


Quote
* The I2C 'DS3231' interface is very straight forward and
   virtually identical to the register addresses of the popular DS1337
   and DS1307 RTCs, which means that existing code for the Arduino,
   Basic Stamp, Cubloc, and other controllers should work with no modification.
   For reference purposes see >> https://www.adafruit.com/products/255

Ashton

That example was not much help to me.
Every time I close the Serial Monitor,  I'm prompted "waiting for sync message", it doesn't display the time until the Unix time is re-entered.
Like: T1375316871

Maybe I'm missing something.

dannable

Quote
if (! RTC.isrunning())


Not applicable to the 3231. It's a flag set on the 1307.

Take a look at the data sheet.
Beginners guide to using the Seeedstudio SIM900 GPRS/GSM Shield

Ashton

I found a code example that solved my problem here: http://www.l8ter.com/?p=417

Code: [Select]
DateTime now = RTC.now();
DateTime compiled = DateTime(__DATE__, __TIME__);
if (now.unixtime() < compiled.unixtime()) {
Serial.println("RTC is older than compile time! Updating");
// following line sets the RTC to the date & time this sketch was compiled
RTC.adjust(DateTime(__DATE__, __TIME__));


Tests so far are good.


JohnHoward

#6
Aug 01, 2013, 04:41 am Last Edit: Aug 01, 2013, 06:22 am by Coding Badly Reason: 1
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:

Code: [Select]
#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 https://github.com/trunet/DS3231RTC to support the DS3231

The RTC time is set initially with:

RTC3231.write(tm)


Moderator edit: [code] [/code] tags added.

mmcp42

the idea is to set __DATE__ and __TIME__ just the once
then remove the code
there are only 10 types of people
them that understands binary
and them that doesn't

Tamadite

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?

cattledog

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

From the data sheet:

Quote
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

creamers

Hi,

I use this library:

https://github.com/JChristensen/DS3232RTC

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......

cattledog

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.

Code: [Select]
#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);
}

creamers

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....

cattledog

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.

Tamadite

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?

Go Up