RTC being reset

I've added a DS1307 RTC to my Uno. I can set the time/date and read it OK within a sketch and once set the time increments as expected.

The 'issue' I have is that everytime I upload a sketch to the board the rtc 'looses' the time/date and has to be set again. Is this behaviour expected?

What is the 'recommended' method of automatically setting the RTC ? Currently I'm setting it from DATE and TIME if the year read from the RTC is less than 2014.

Most RTC modules have a backup battery on them so they maintain the time even when power is removed. It sounds like you are calling a routine that resets the clock each time you upload the program. When I was using a RTC, I had an initialization function that used the Serial link to read the time from my PC. After I loaded the time from my PC once, I commented out the call so I didn't reinit each time I uploaded.

Perhaps a more elegant way is to set a flag stored in EEPROM that is 0 if the clock has not been initialized and 1 if it has. Read the EEPROM flag in setup() and then decide whether you need to initialize the clock.

Last time I looked at this you when the RTC has lost all power the time is set to 0 and stays there until you reset it. So you just read the time if its 0 you write the new new and that's it.

Mark

The RTC module has a battery. The first sketch I used set the time/date and displayed the time/date to the serial monitor (which was correct). The next sketch I uploaded just read the RTC and returned a 'reset' date/time - date of 1 Jan 2000. Every time I upload a sketch the returned date/time has been reset. I have this code immediately after the includes

SoftI2C i2c(A4, A5);
DS1307RTC rtc(i2c);

but there is nothing else that refers to the rtc until I read it. As the RTC is being powered from the uno and power isn't removed between uploading the different sketches I wouldn't think it would be the RTC battery?

DATE and TIME will not do what you want. That is the time that the sketch was compiled. Better than nothing I guess, but I wouldn't bother. You need some method of setting it that is more current, like sending a serial command.

Are you really using the RTC or using a library that uses the Arduino internal timer as a clock?

Are you really using the RTC or using a library that uses the Arduino internal timer as a clock?

Good question. How do I know if I’m using the rtc or internal timer? I got the rtc and i2c libraries from https://github.com/rweather/arduinolibs which is the site suggested by the supplier of the rtc hardware.

I use it like

#include <SoftI2C.h>
#include <DS1307RTC.h>
#include <avr/pgmspace.h>
#include <string.h>

//For the RTC
SoftI2C i2c(A4, A5);
DS1307RTC rtc(i2c);

....

RTCTime time;
RTCDate date;

rtc.readDate(&date);
rtc.readTime(&time);

I've found the isRealTime() method for determining if there is an rtc on the i2c bus or not - and its returning false meaning that the rtc hardware has not been found. Oh dear!

Any ideas - as I've wired the rtc module SDA to A4 and SCL to A5. I've checked and I have 5v between gnd and vcc on the rtc module.

The rtc module is a E-Tecstar RTC I2C DS1307 AT24C32 Real Time Clock Module For Arduino AVR ARM PIC and I'm using an Arduino Uno R3.

Any help would be greatly appreciated as I haven't got much experience yet with the hardware side of things.

I think we need all your code.

Since you haven't told us which RTC module can you please post a link to
its datasheet or details?

In particular does it have pull-up resistors on the I2C bus? If not you'll need
to add your own, 4k7 between each pin of the I2C and Vcc.

RTC chips need to have their oscillator-enable bits set high to run, and beware
of code that programs the initial time - you don't want that to run everytime
thereafter.

I suggest write one sketch to set the time and enable the oscillator, then your
main sketch should only be reading it, not updating it. After initial setup there
is then no danger of overwriting the time or killing the oscillator since you
don't write to the RTC in it.

If you use Wire.h it enables the internal pullups on the I2C bus. They are quite often good enough for devices close to the UNO.

Use an I2C address scanner to verify the address

// I2C Scanner
// Written by Nick Gammon
// Date: 20th April 2011

#include <Wire.h>

void setup() {
  Serial.begin (115200);

  // Leonardo: wait for serial port to connect
  while (!Serial) 
    {
    }

  Serial.println ();
  Serial.println ("I2C scanner. Scanning ...");
  byte count = 0;
  
  Wire.begin();
  for (byte i = 8; i < 120; i++)
  {
    Wire.beginTransmission (i);
    if (Wire.endTransmission () == 0)
      {
      Serial.print ("Found address: ");
      Serial.print (i, DEC);
      Serial.print (" (0x");
      Serial.print (i, HEX);
      Serial.println (")");
      count++;
      delay (1);  // maybe unneeded?
      } // end of good response
  } // end of for loop
  Serial.println ("Done.");
  Serial.print ("Found ");
  Serial.print (count, DEC);
  Serial.println (" device(s).");
}  // end of setup

void loop() {}

From looking at the board I would say that it has pull up resistors.

This is the test code that reports on the status of the rtc. It should display a 1 in the serial monitor but displays a 0 meaning it can’t find the rtc.

include <SoftI2C.h>
#include <DS1307RTC.h>
#include <avr/pgmspace.h>

//For the RTC
SoftI2C i2c(A4, A5);
DS1307RTC rtc(i2c);

void setup()
{
  Serial.begin(19200);
  
  Serial.print("rtc ");
  Serial.println(rtc.isRealTime());
}

void loop()
{
}

From looking at the rtc .cpp code in the library, the address of the rtc on the i2c bus is 0x68.

The result from the scanner is

I2C scanner. Scanning ...
Found address: 80 (0x50)
Found address: 104 (0x68)
Done.
Found 2 device(s).

and looking at the rtc .cpp code it is using 0x68 as the i2c address for the rtc.

Curious, why are you using the SoftI2C library on pins A4/A5 of your UNO?

If I disconnect the rtc hardware, the scanner sketch shows no devices so at least the rtc hardware is present on the i2c bus.

The rtc hardware is E-Tecstar RTC I2C DS1307 AT24C32 Real Time Clock Module For Arduino AVR ARM PIC

and I got the instructions from here RTC Real Time Clock Module Quickstart Guide | Freetronics

and the libraries from here GitHub - rweather/arduinolibs: Arduino Cryptography Library

I'm using A4 and A5 because that is what the instructions from above said.

If I change the address of the rtc on the i2c bus in the code from 0x68 to 0x50 (the other address found with the scanner) then the rtc code reports that the rtc is present but returns rubbish values for the date/time after they have been set.

Here is an example of a well behaved RTC sketch. It only loads the current compile date and time if it sees that the current status of the RTC is not running in which case it loads the compiled time and date. If you wish to reload the time and date you just have to un-comment one line in the startup function, upload, then re-comment the line. This does require a RTC library i think from Adafruit.

// Date and time functions using a DS1307 RTC connected via I2C and Wire lib

#include <Wire.h>
#include "RTClib.h"

RTC_DS1307 RTC;

void setup () {
    Serial.begin(57600);
    Wire.begin();
    RTC.begin();
//   If wanting to set date/time even if running uncomment the next statement   
//    RTC.adjust(DateTime(__DATE__, __TIME__));

  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__));
  }
}

void loop () {
    DateTime now = RTC.now();
    
    Serial.print(now.year(), DEC);
    Serial.print('/');
    Serial.print(now.month(), DEC);
    Serial.print('/');
    Serial.print(now.day(), DEC);
    Serial.print(' ');
    Serial.print(now.hour(), DEC);
    Serial.print(':');
    Serial.print(now.minute(), DEC);
    Serial.print(':');
    Serial.print(now.second(), DEC);
    Serial.println();
/*    
    Serial.print(" since midnight 1/1/1970 = ");
    Serial.print(now.unixtime());
    Serial.print("s = ");
    Serial.print(now.unixtime() / 86400L);
    Serial.println("d");
    
    // calculate a date which is 7 days and 30 seconds into the future
    DateTime future (now.unixtime() + 7 * 86400L + 30);
    
    Serial.print(" now + 7d + 30s: ");
    Serial.print(future.year(), DEC);
    Serial.print('/');
    Serial.print(future.month(), DEC);
    Serial.print('/');
    Serial.print(future.day(), DEC);
    Serial.print(' ');
    Serial.print(future.hour(), DEC);
    Serial.print(':');
    Serial.print(future.minute(), DEC);
    Serial.print(':');
    Serial.print(future.second(), DEC);
    Serial.println();
    
    Serial.println();
 */
    delay(500);
}

Thank you for the info. I've changed the rtc library I'm using to the rtclib one you suggested in your post and now everything is working fine. I've set the time/date, switched off the uno waited 5 minutes and switched it back on and the date/time is still OK. Uploading different sketches also doesn't affect the time.

The problem was with the i2c/rtc library I was using as I referenced in a previous post. I got the rtclib from here http://arduino-info.wikispaces.com/DS1307_RealTime_Clock_Brick

Thank you all very much for your helpful replies. I've learnt such a lot today that I think my head is going to explode! I've just got to change my main program to now use rtclib as the test program is working - which is for another day.

It’s been my experience as well that using Wire and RTClib is the way to go with the DS1307 RTC modules.

#include <Wire.h>
#include "RTClib.h"

It’s a wild world out there with all the different libraries running around.