Problem saving current time and date on DS1302

Hi everyone!

I just started to work with Arduino and I need to save current time on DS1302. I tried to upload an example code to my system and I succeed. But, after starting that example code or unplugging DS1302 module (self-made) and plug it back, RTC deletes last time information and starts back from “Jan 1970, 00:00:00”

What do I need to save my last time information (probably save it to some kind of variable and call it back) and use it again when I start later (or cutting off power from arduino and giving it back? I searched whole forum but I couldn’t find an answer)

(Sorry if I did any kind of mistake, I read “How to use this forum - please read.” but maybe I didn’t see something)

You can see my code below:

/*----------------------------------------------------------------------*
 * Display the date and time from a DS1302 RTC every second.            *
 *                                                                      *
 * Set the date and time by entering the following on the Arduino       *
 * serial monitor:                                                      *
 *    year,month,day,hour,minute,second,                                *
 *                                                                      *
 * Where                                                                *
 *    year can be two or four digits,                                   *
 *    month is 1-12,                                                    *
 *    day is 1-31,                                                      *
 *    hour is 0-23, and                                                 *
 *    minute and second are 0-59.                                       *
 *                                                                      *
 * Entering the final comma delimiter (after "second") will avoid a     *
 * one-second timeout and will allow the RTC to be set more accurately. *
 *                                                                      *
 * No validity checking is done, invalid values or incomplete syntax    *
 * in the input will result in an incorrect RTC setting.                *
 *                                                                      *
 * Jack Christensen 08Aug2013                                           *
 *                                                                      *
 * Adopted for DS1302RTC library by Timur Maksimov 2014                 *
 *                                                                      *
 * This work is licensed under the Creative Commons Attribution-        *
 * ShareAlike 3.0 Unported License. To view a copy of this license,     *
 * visit http://creativecommons.org/licenses/by-sa/3.0/ or send a       *
 * letter to Creative Commons, 171 Second Street, Suite 300,            *
 * San Francisco, California, 94105, USA.                               *
 *----------------------------------------------------------------------*/ 
 
#include <DS1302RTC.h>
#include <Streaming.h>        //http://arduiniana.org/libraries/streaming/
#include <Time.h>             //http://playground.arduino.cc/Code/Time

// Set pins:  CE, IO,CLK
DS1302RTC RTC(2, 3, 4);

// Optional connection for RTC module


void setup(void)
{
  Serial.begin(9600);
    
  // Activate RTC module

  
  Serial << F("RTC module activated");
  Serial << endl;
  delay(500);
  
  if (RTC.haltRTC()) {
    Serial << F("The DS1302 is stopped.  Please set time");
    Serial << F("to initialize the time and begin running.");
    Serial << endl;
  }
  if (!RTC.writeEN()) {
    Serial << F("The DS1302 is write protected. This normal.");
    Serial << endl;
  }
  
  delay(500);
    
  //setSyncProvider() causes the Time library to synchronize with the
  //external RTC by calling RTC.get() every five minutes by default.

  Serial << F("RTC Sync");
  if (timeStatus() == timeSet)
    Serial << F(" Ok!");
  else
    Serial << F(" FAIL!");
  Serial << endl;
}

void loop(void)
{
    static time_t tLast;
    time_t t;
    tmElements_t tm;

    //check for input to set the RTC, minimum length is 12, i.e. yy,m,d,h,m,s
    if (Serial.available() >= 12) {
        //note that the tmElements_t Year member is an offset from 1970,
        //but the RTC wants the last two digits of the calendar year.
        //use the convenience macros from Time.h to do the conversions.
        int y = Serial.parseInt();
        if (y >= 100 && y < 1000)
            Serial << F("Error: Year must be two digits or four digits!") << endl;
        else {
            if (y >= 1000)
                tm.Year = CalendarYrToTm(y);
            else    //(y < 100)
                tm.Year = y2kYearToTm(y);
            tm.Month = Serial.parseInt();
            tm.Day = Serial.parseInt();
            tm.Hour = Serial.parseInt();
            tm.Minute = Serial.parseInt();
            tm.Second = Serial.parseInt();
            t = makeTime(tm);
      //use the time_t value to ensure correct weekday is set
            if(RTC.set(t) == 0) { // Success
              setTime(t);
              Serial << F("RTC set to: ");
              printDateTime(t);
              Serial << endl;
      }
      else
        Serial << F("RTC set failed!") << endl;
            //dump any extraneous input
            while (Serial.available() > 0) Serial.read();
        }
    }
    
    t = now();
    if (t != tLast) {
        tLast = t;
        printDateTime(t);
        Serial << endl;
    }
}

//print date and time to Serial
void printDateTime(time_t t)
{
    printDate(t);
    Serial << ' ';
    printTime(t);
}

//print time to Serial
void printTime(time_t t)
{
    printI00(hour(t), ':');
    printI00(minute(t), ':');
    printI00(second(t), ' ');
}

//print date to Serial
void printDate(time_t t)
{
    printI00(day(t), 0);
    Serial << monthShortStr(month(t)) << _DEC(year(t));
}

//Print an integer in "00" format (with leading zero),
//followed by a delimiter character to Serial.
//Input value assumed to be between 0 and 99.
void printI00(int val, char delim)
{
    if (val < 10) Serial << '0';
    Serial << _DEC(val);
    if (delim > 0) Serial << delim;
    return;
}

Do you have the backup battery in your circuit? Is it known good?

-- alto777

Thanks for reply.

Yes, I have backup battery. It's completely operational, I checked wiring and measured its voltage (3.3V).

It's unusual to get as far as you did and fail.

Is your circuit very similar to a suggested reference design from the data sheet? Such schematics may have some subtleties you overlooked or didn't bother with.

What is the sketch you are using to reconnect to the DS1302? The sketch you shared looks like it will always just set the current time.

-- a7

I checked the datasheet of DS1302, and I didn't see anything can block me. So I guess, this is not the point I should look at.

I want to set current time to RTC so if I use this RTC module with another Arduino (or different sketch, doesn't matter) I can easily get real time from it. You asked me which sketch I'm using for another connection, not different (for now). You also said this sketch just sets the current time. That's my point too, I also want to save it on DS1302 module so I can use it with different sketch or with different board. I think it's possible, I mean, that's why it has a battery, right?

Seems like the sketch that doesn't set the time but somehow resets or fails to read the time must be a different sketch (or some tweak to this one).

The after plugging in image shows the sketch with RTC synch Fail.

You need to call setSynchProvider() with the appropriate argument(I think its likely to be RTC.get()) before the timeStatus() conditional test which is failing.

You need to understand, that the use of setSynchProvider() links the RTC time to the internal arduino millis() clock which is used by the time library for all the time call and displays in the program. The RTC is only read every five minutes to recalibrate the internal clock. The sketch is using time library syntax, and there is entirely different syntax for reading the RTC directly. I'm sure your RTC has the correct time in its registers, the time library just doesn't know it.

alto777:
Seems like the sketch that doesn’t set the time but somehow resets or fails to read the time must be a different sketch (or some tweak to this one).

Thanks for your help. Yes, I think that fails to read time too.

cattledog:
The after plugging in image shows the sketch with RTC synch Fail.

You need to call setSynchProvider() with the appropriate argument(I think its likely to be RTC.get()) before the timeStatus() conditional test which is failing.

You need to understand, that the use of setSynchProvider() links the RTC time to the internal arduino millis() clock which is used by the time library for all the time call and displays in the program. The RTC is only read every five minutes to recalibrate the internal clock. The sketch is using time library syntax, and there is entirely different syntax for reading the RTC directly. I’m sure your RTC has the correct time in its registers, the time library just doesn’t know it.

Actually, there was already one setSyncProvider(RTC.get()) command, but with this one, program resets itself per every five minutes. For example, if I set time as “12:45:00”, after showing “12:49:59”, it turns back to “12:45:00”, not continue with “12:50:00”. That’s why I deleted that.

Is there any different kind of solution for this? I mean, can I make my RTC visible and accessible for my Time library different way else?

Update: I added a picture of that reset, for every five minutes it returns back because of "setSyncProvider(RTC.get);"where I programmed RTC with current time.

ReturningBack.jpg

Actually, there was already one setSyncProvider(RTC.get()) command, but with this one, program resets itself per every five minutes. For example, if I set time as “12:45:00”, after showing “12:49:59”, it turns back to “12:45:00”, not continue with “12:50:00”. That’s why I deleted that.

It would appear that the ds1302 is not running. You have set the time in its registers, but it is not changing. There is a clock halt bit which should have been cleared when you set the time, but for some reason it may not have been cleared, and it sounds as if the setTime sketch is not working correctly

Yes, I think that fails to read time too.

Whats confusing is that if the clock halt bit were not set properly, you should have failed this test which occurs before the synch test.

if (RTC.haltRTC()) {
    Serial << F("The DS1302 is stopped.  Please set time");
    Serial << F("to initialize the time and begin running.");
    Serial << endl;
  }

Please provide a link to the exact library you are using, and the setTime sketch. Are you using an rtc module, or is it something you have built with the chip and support components. The crystal may be defective. Please provide some documentation on the hardware.

cattledog:
Please provide a link to the exact library you are using, and the setTime sketch. Are you using an rtc module, or is it something you have built with the chip and support components. The crystal may be defective. Please provide some documentation on the hardware.

Here are the links for libraries I used:

//http://arduiniana.org/libraries/streaming/ (for Streaming.h library)
//http://playground.arduino.cc/Code/Time (for Time.h library)
http://playground.arduino.cc/Main/DS1302RTC (for DS1302RTC.h library)

I’m using self-made rtc module, and I changed my crystal before posting here. Nothing changed.

Just for info, I actually solve this problem by adding “RTC.set(tLast)” to the following section last Saturday:

t = now();
    if (t != tLast) {
        tLast = t;
        RTC.set(tLast);
        printDateTime(t);
        Serial << endl;

And today, about 1 hr ago when it was working (I mean, arduino was connected and there was no problem), I unplugged “+5V” and “GND” wires of RTC module, just to see if it will work or not.

Surprise, they not!

It was reset itself and now when I try to set current time, it always send “RTC Sync FAIL” and continues from time “1 Jan 1970, …blablabla…”. I think that it’s because of registers you mention, clock halt and write protection. I will try as soon as possible and post what happens.

t = now();
    if (t != tLast) {
        tLast = t;
        RTC.set(tLast);
        printDateTime(t);
        Serial << endl;

This makes no sense. You are setting the RTC every second with the time derived from the time library and the millis() clock of the Arduino. When the synch comes every five minutes, you are not really getting a value determined by the RTC’s more accurate clock.

Basically, your RTC is not running.

now when I try to set current time, it always send “RTC Sync FAIL”

This sounds like you are going backwards and the Arduino is not even communicating with the RTC.

EDIT:

I’m using self-made rtc module

Can you please provide a schematic of what you have done, and perhaps a photograph of the actual setup.

cattledog:

t = now();

if (t != tLast) {
        tLast = t;
        RTC.set(tLast);
        printDateTime(t);
        Serial << endl;




This makes no sense. You are setting the RTC every second with the time derived from the time library and the millis() clock of the Arduino. When the synch comes every five minutes, you are not really getting a value determined by the RTC's more accurate clock.

Basically, your RTC is not running.
This sounds like you are going backwards and the Arduino is not even communicating with the RTC.

EDIT:Can you please provide a schematic of what you have done, and perhaps a photograph of the actual setup.

I don’t have actual setup now but it’s just a basic RTC with clock battery, on a pertinax board.

How can I make communicate my Arduino with RTC? Or, how can I set my RTC and start it? I looked a lot of RTC examples based on internet and there was not significant differences between them and my code.

How can I make communicate my Arduino with RTC? Or, how can I set my RTC and start it? I looked a lot of RTC examples based on internet and there was not significant differences between them and my code.

When you can not run library examples there is likely something wrong in your hardware setup or the chip itself.

I don’t have actual setup now but it’s just a basic RTC with clock battery, on a pertinax board.

It does not appear to be a battery issue, because when the rtc is powered the time does not advance. This is shown by the fact that every 5 minutes the synch time reverts to the time originally set in the RTC. Have you actually confirmed the voltage at Vcc2 and Vcc1 on the chip pin itself? Which is connected to the battery and which to the power supply?

It does not appear to be a stuck bit in the Clock Halt register, because if (RTC.haltRTC()) is not returning an error.

I would focus on the oscillator or ds1302 itself.

You say you changed the crystal oscillator. Is it the correct type specified for a 6pf load capacitance? Is it the correct frequency? Is it from a trusted supplier?

Is your ds1302 from a trusted supplier?

cattledog:
When you can not run library examples there is likely something wrong in your hardware setup or the chip itself.

It does not appear to be a battery issue, because when the rtc is powered the time does not advance. This is shown by the fact that every 5 minutes the synch time reverts to the time originally set in the RTC. Have you actually confirmed the voltage at Vcc2 and Vcc1 on the chip pin itself? Which is connected to the battery and which to the power supply?

It does not appear to be a stuck bit in the Clock Halt register, because if (RTC.haltRTC()) is not returning an error.

I would focus on the oscillator or ds1302 itself.

You say you changed the crystal oscillator. Is it the correct type specified for a 6pf load capacitance? Is it the correct frequency? Is it from a trusted supplier?

Is your ds1302 from a trusted supplier?

Many thanks for your interest. I completely trust DS1302 because other co-workers used them a lot of different applications. I’m not sure about oscillator, it’s 32 kHz but i don’t know its load capacitance and quality.

I’m gonna check them and prepare new board with different components. I’ll post after. Thanks again.