Guardar Fecha y Hora en Tiny RTC

Llevo mucho tiempo analizando y estudiando el foro y todas las indicaciones que se hacen.

Estoy inmerso en un proyecto, para controlar un acuario, y tengo un problema que no se como resolver después de darle muchas muchas vueltas y cambiar mucho el código, os comento para ver si me podeis ayudar.

Tengo un Arduino Mega
Modulo Tiny RTC como este

Conexiones:
SQ -->
DS --> Digital 2
SCL --> 21
SDA --> 20
VCC--> 5V
GND --> GND
BAT -->

Consigo inicializar la hora y la fecha perfectamente y cuando inicializo el código con el botón del reset se respeta la hora perfectamente y continua desde donde estaba. El problema viene cuando lo desconecto de la alimentación se inicializa a [01/01/2000 00:00:00] y ya no avanza nada.

Os dejo dos código diferente en los dos tengo el mismo problema.

#include <Wire.h> 

//////////////////////////////////////////////////////////////////////////////////////// RELOJ
//-------------------------------------- Libreria que se usa para fijar y grabar la hora en la memoria
#include <DS1307new.h>
uint16_t startAddr = 0x0000;            // Start address to store in the NV-RAM
uint16_t lastAddr;                      // new address for storing in NV-RAM
uint16_t TimeIsSet = 0xaa55;            // Helper that time must not set again


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {

  // put your setup code here, to run once:
  Serial.begin(9600);
  
  digitalWrite( 2, HIGH);          // Test of the SQW pin, D2 = Pullup on 
  Wire.begin(); // Inicia el puerto I2C
  RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// Store startAddr in NV-RAM address 0x08 
  
  //Descomentar estas DOS lineas para fijar la hora inicialmente.
  //TimeIsSet = 0xffff;
  //RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));  
  
  RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
  if (TimeIsSet != 0xaa55)
     { RTC.stopClock();
       //Hora que se quiere fijar, si no tiene ya una fijada.
       RTC.fillByYMD(2015,8,5);  //aaaa,m,d
       RTC.fillByHMS(17,14,0);    //hh,m,s
       RTC.setTime();
       TimeIsSet = 0xaa55;
       RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
       RTC.startClock();
     }
  else
     { RTC.getTime(); 
     }
  RTC.ctrl = 0x00;
  RTC.setCTRL();

}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  // put your main code here, to run repeatedly:
  String Cadena;

  RTC.getTime();

  Cadena = "";
  if( RTC.day<10 ) Cadena += String("0");
  Cadena += String(RTC.day) + "/";
  if( RTC.month<10) Cadena += String("0");
  Cadena += String(RTC.month) + "/" + String(RTC.year);
  Cadena += "  ";
  if( RTC.hour<10) Cadena += String("0");     
  Cadena += String(RTC.hour) + ":";
  if( RTC.minute<10) Cadena += String("0");   
  Cadena += String(RTC.minute) + ":";
  if( RTC.second<10 ) Cadena += String("0");          
  Cadena += String(RTC.second);       

  Serial.println( Cadena );
  Grabar_Hora();
 
  delay(1000);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 
//-------------------- Graba la hora en el dispositivo del reloj ----------------------------------
void Grabar_Hora(){
   RTC.getRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
   RTC.setRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
   RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
   if (TimeIsSet == 0xaa55)              // check if the clock was set or not
      { Serial.println(" Correcto la grabacion de la hora del reloj"); 
      }
   else
      { Serial.println("Fallo en la grabacion de la hora del reloj ( ERR-03 Reloj )"); 
      }   
}
#include <Wire.h> 

//////////////////////////////////////////////////////////////////////////////////////// RELOJ
//-------------------------------------- Libreria que se usa para fijar y grabar la hora en la memoria
#include <DS1307new.h>
uint16_t startAddr = 0x0000;            // Start address to store in the NV-RAM
uint16_t lastAddr;                      // new address for storing in NV-RAM
uint16_t TimeIsSet = 0xaa55;            // Helper that time must not set again
//-------------------------------------- Otra libreria que se usa para leer las horas
#include <RTClib.h>
RTC_DS1307 RTCLeer; 


//////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {

  // put your setup code here, to run once:
  Serial.begin(9600);
  
  digitalWrite( 2, HIGH);          // Test of the SQW pin, D2 = Pullup on 
  Wire.begin(); // Inicia el puerto I2C
  RTC.setRAM(0, (uint8_t *)&startAddr, sizeof(uint16_t));// Store startAddr in NV-RAM address 0x08 
  
  //Descomentar estas DOS lineas para fijar la hora inicialmente.
  //TimeIsSet = 0xffff;
  //RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));  
  
  RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
  if (TimeIsSet != 0xaa55)
     { RTC.stopClock();
       //Hora que se quiere fijar, si no tiene ya una fijada.
       RTC.fillByYMD(2015,8,5);  //aaaa,m,d
       RTC.fillByHMS(17,14,0);    //hh,m,s
       RTC.setTime();
       TimeIsSet = 0xaa55;
       RTC.setRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
       RTC.startClock();
     }
  else
     { RTC.getTime(); 
     }
  RTC.ctrl = 0x00;
  RTC.setCTRL();

  RTCLeer.begin();  // Inicia la comunicación con el RTC
}

/////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop() {
  // put your main code here, to run repeatedly:
  String Cadena;
  
  DateTime now;
  now = RTCLeer.now(); // Obtiene la fecha y hora del RTC
  Cadena = "";
  if( now.day()<10 ) Cadena += String("0");
  Cadena += String(now.day()) + "/";
  if( now.month()<10) Cadena += String("0");
  Cadena += String(now.month()) + "/" + String(now.year());
  Cadena += "  ";
  if( now.hour()<10) Cadena += String("0");     
  Cadena += String(now.hour()) + ":";
  if( now.minute()<10) Cadena += String("0");   
  Cadena += String(now.minute()) + ":";
  if( now.second()<10 ) Cadena += String("0");          
  Cadena += String(now.second());       

  Serial.println( Cadena );
  Grabar_Hora();
 
  delay(1000);
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////

 
//-------------------- Graba la hora en el dispositivo del reloj ----------------------------------
void Grabar_Hora(){
   RTC.getRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
   RTC.setRAM(0, (uint8_t *)&lastAddr, sizeof(uint16_t));
   RTC.getRAM(54, (uint8_t *)&TimeIsSet, sizeof(uint16_t));
   if (TimeIsSet == 0xaa55)              // check if the clock was set or not
      { Serial.println(" Correcto la grabacion de la hora del reloj"); 
      }
   else
      { Serial.println("Fallo en la grabacion de la hora del reloj ( ERR-03 Reloj )"); 
      }   
}

Estoy perdido si me podéis ayudar os lo agradecería
Un saludo

Prueba a ver si la batería (de 3V que esta abajo de la foto) tiene la tensión adecuada.
A veces hay un falso contacto.
La responsabilidad de que siga fucionando cuando se corta la alimentación es de esa bateria. Asi que tus esfuerzos centralos por ahi.

mide en los puntos que te muestro en la imagen

No soy quien para dar consejos ..pero quizas podría ser lo que exponen en esta página:

Salu2

surbyte:
Prueba a ver si la batería (de 3V que esta abajo de la foto) tiene la tensión adecuada.
A veces hay un falso contacto.
La responsabilidad de que siga fucionando cuando se corta la alimentación es de esa bateria. Asi que tus esfuerzos centralos por ahi.

mide en los puntos que te muestro en la imagen

No identifico con tu imagen donde debo tomar la medida..?

Una batería donde puedes llegar a medirla.
Si lees un borne que dice BAT ahi el positivo.
Y el otro? Obvio que es GND

surbyte:
Una batería donde puedes llegar a medirla.
Si lees un borne que dice BAT ahi el positivo.
Y el otro? Obvio que es GND

Lo he leido y no marca nada, y la pila si tiene porque tambien lo he comprobado..

O sea que entre BAT y GND no lees 3.2 o 3.3V? Entonces tienes un falso contacto en el zócalo de la batería.
Yo retiraría el módulo.
Le saco la batería y reviso continuidad entre los dos contactos que tiene la batería.
Ahora es un trabajo que debes hacer tu mismo.
Primero identifica los contactos.

Debes verificar continuidad entre estos puntos mira

Positivo de la bateria y el pin 3 del DS1307
Negativo de la bateria y el pin 4 del DS1307

Demasiada electrónica para mi, yo vengo del mundo de la programación y la electrónica se me hace complicado.

Que modulo reloj me podéis recomendar..??

Pero vmarquez si usas Arduino no puedes evitarlo. Hay que lidiar con estas cosas. imagina, que pagas no se digamos 5 euros por un modulo hecho por millones o cientos de miles, y alguno puede estar con alguna falla.
Te tocó a ti. Buscas un polimetro/multimetro y mides si la pila esta presente mas alla de verla.
Sino tienes que comprar equipos mas caros, con mejor control de calidad.
Mejor que el RTC1307 es el RTC3231 porque no se corre en el tiempo como si lo hace el 1307. Pero ese es otro tema. Tmb tiene batería y tmb puede pasarte eso, aunque digamos que tienes las probabilidades a tu favor de que te vuelva a pasar.

Definitivamente un DS3231 es el módulo RTC que debes conseguir. El portapilas que usa la mayoría de DS3231 es para pila CR2032.

También funciona la pila recargable LIR3032, en las pruebas que he podido hacer la batería se recarga mientras el arduino está encendido. No he percibido recalentamientos extraños en la pila.

Con ambos tipos de pilas el reloj funciona sin problemas, aun si se queda sin alimentación el arduino.

Solo hay un detalle cuando se reprograma el arduino con el RTC conectado, puede haber congelamientos esporádicos, aunque el RTC parece no marcar la hora correcta, se soluciona desconectando el arduino por unos 15 segundos como mínimo. Al reconectar el arduino, el DS3231 no pierde la hora y funciona normalmente.