RTC DS 3231 se para sin alimentación externa

LLevo un tiempo intentando solucionar el problema sin conseguirlo. Tampoco me han ayudado las búsquedas en Google.

Estoy trabajando en un proyecto que incluye un reloj RTC con un módulo DS3231. El sketch funciona perfectamente con una alimentación externa, pero cuando desconecto la alimentación el reloj se para a pesar de la pila.

He descartado un problema de hardward y he probado con varios módulos RTC. Las búsquedas que he hecho me indican que el problema no es solo mío. En un foro he encontrado una explicación con el estado de algunos registros y añaden unas líneas de código para cambiar los estados de los registros. A pesar de haber probado con ese código no he conseguido que entre en acción la pila cuando se desconecta la fuente externa.

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

#define DS3231_I2C_ADDRESS 0x68

LiquidCrystal_I2C lcd(0x3f, 20, 4);
RTC_DS3231 rtc;

const int secondsINTERVAL = 1;
unsigned long timeForAction = 0;
int initialDay;

void initClock() {
  int initDay = 11;
  int initMonth = 9;
  int initYear = 2019;
  int initHour = 10;
  int initMinute =51;
  rtc.adjust(DateTime(initYear, initMonth, initDay, initHour, initMinute, 0));
}

void displayDate(DateTime t) {
char buf_date[21];
  snprintf(buf_date, sizeof(buf_date), "%02d-%02d-%4d", 
  t.day(), t.month(), t.year());
  lcd.setCursor(0, 0);
  lcd.print(buf_date);
}

void displayHour(DateTime t) {
char buf_hour[9];
  snprintf(buf_hour, sizeof(buf_hour), "%02d:%02d:%02d",
    t.hour(), t.minute(), t.second());

lcd.setCursor(0, 1);
lcd.print(buf_hour);
}

void setup() {
  Serial.begin(9600);
  Serial.flush();
  Wire.begin();
  
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0xE);                            // Address the Control Register
    Wire.write(0x00);                           // Write 0x0 to control Register
  Wire.endTransmission();
  
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0xF);                            // Address the Status register
    Wire.write(0x00);                           // Write 0x0 to Status Register
  Wire.endTransmission();

  rtc.begin();
  lcd.init();
  lcd.backlight();
  lcd.clear();

  DateTime nowTime = rtc.now();
  initialDay = nowTime.day();
  displayDate(nowTime);

//  initClock();
}

void loop() {  
  if (millis() > timeForAction) {
    timeForAction = millis() + (secondsINTERVAL * 1000); 
    
    DateTime nowTime = rtc.now();
    if (initialDay != nowTime.day()) {
      displayDate(nowTime);
      initialDay = nowTime.day();
    }
    displayHour(nowTime); 
  }
}

EA2HW:
A pesar de haber probado con ese código no he conseguido que entre en acción la pila cuando se desconecta la fuente externa.

La pila CR2032 de 3V solo es para mantener funcionando el modulo RTC de manera de que no pierda la hora y que cuando vuelvas a energisar el Arduino este retome la hora correcta.

Suele ocurir que algunos modulos DS3231 usan una pila LIR2032 en lugar de la CR y la diferencia es que la primera es recargable y la segunda no.
Tal importante es la cosa que colocar una CR2032 en el lugar de la recargable hace que no funcione. Eso me ocurriò a mi.

Kike_GL:
La pila CR2032 de 3V solo es para mantener funcionando el modulo RTC de manera de que no pierda la hora y que cuando vuelvas a energisar el Arduino este retome la hora correcta.

Gracias por el aporte, efectivamente, la pila sirve para mantener la hora. Precisamente mi problema es que no lo hace. Si apago la alimentación externa del módulo, cuando vuelvo a encender, el RTC muestra la misma hora que tenía cuando desconecté la alimentación externa.

Gracias también por los aportes sobre las pilas. Utilizo pilas de botón no recargables CR2032 de Maxwel, el polímetro indica que tiene 3,298Vcc.

He utilizado módulos de MH (CR-2032) y ¿RU? (CR1220)

Hi,
Pregunta la instruccion que se usa al principio del programa para poner la hora y una vez que lo compilas
tienes que comentar la instruccion y vuelves a compilar el programa. Sino lo haces cuando reinizialisas el programa te cambia la hora originar.

ejemplo: compilas el programa para ponerle la hora al reloj rtc.adjust(DateTime(initYear, initMonth, initDay, initHour, initMinute, 0));

Una vez compilado el programa y pongas la hora tienes que comentar la instruccion  //rtc.adjust(DateTime(initYear, initMonth, initDay, initHour, initMinute, 0));y vuelves y compila el programa. De ahora en adelante te debe dar hora la correctamente cuando reinizialisas el micro.. Otra Pregunta ese modulo tiene la memoria at24c32?

La instrucción (función) que utilizo para iniciar el programa initClock() está comentada y, cada vez que la utilizo, lo primero la descomento y luego, después de compilar, vuelvo a comentarla.

Prefiero inicializar, de momento, el reloj de esta forma compilando unos 12 segundos antes de la hora real consiguiendo una precisión de +-2s. El desarrollo del proyecto prevé la conexión con un NTP a través de ethernet, pero estoy parado con este problema.

Veo que el moderador ha desplazado la consulta al apartado de hardware. No es un problema de hardware puesto que el montaje electrónico es muy simple y no tiene errores (es el tema que mejor conozco). El problema es más bien mixto porque probablemente se trata de un ajuste inicial de comandos del chip que regulan el funcionamiento de la alimentación con la pila y eso se realiza mediante software (Wire).

Los montajes con DS3231 son muy populares y agradecería cualquier experiencia con el ajuste de flags que garanticen la alimentación del reloj del chip sin alimentación externa. Lo cierto es que he revisado Internet y no encuentro documentación adecuada. Solo queda el recurso del fabricante con el estudio de la hoja de datos.

tauro0221:
Otra Pregunta ese modulo tiene la memoria at24c32?

Gracias otra vez, he utilizado dos módulos, uno con memoria (DS3231S) y otro sin memoria (DS3231SN), ocurre lo mismo con los dos.

En un foro de Arduino en inglés se cita este problema y el autor de la solución se explaya con el funcionamiento cuyo significado no acabo de entender porque tampoco he estudiado a fondo el comportamiento del chip. Desde luego que el código que utiliza no me funciona a mí.

#define DS3231_I2C_ADDRESS 0x68
Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0xE);                            // Address the Control Register
    Wire.write(0x00);                           // Write 0x0 to control Register
  Wire.endTransmission();
 
  Wire.beginTransmission(DS3231_I2C_ADDRESS);
    Wire.write(0xF);                            // Address the Status register
    Wire.write(0x00);                           // Write 0x0 to Status Register
  Wire.endTransmission();

Estas instrucciones ponen el control y el estado del registro a 0

Pero sigue sin funcionar.

El módulo que utiliza la pila CR2032 lleva una memoria ATHYC532

Gracias

La función que inicializa el reloj que he escrito initClock() está comentada en el sketch, solo la descomento para inicializar el reloj y la comento inmediatamente.

setup() {
  //initClock()
{

void initClock() {
  int initDay = 11;
  int initMonth = 9;
  int initYear = 2019;
  int initHour = 10;
  int initMinute =51;
  rtc.adjust(DateTime(initYear, initMonth, initDay, initHour, initMinute, 0));
}

Utilizo un arduino NANO y lo alimento indistintamente con una fuente externa regulada de 5Vcc en el pin 5V y a través de la entrada USB

Hi,
Yo tuve problemas con un modulo que tiene la memoria y me dio trabajo hacerlo funcionar. Pense tirarlo a la basura pero decidi encontrar el problema. Logre bajar el esquematico de mi modulo y encontre que no se si es un problema que pusieron una resistencia de un valor muy alto y la bateria cuando remueves el Vcc no le va a suplir suficiente voltaje al reloj. El circuito esta hecho para cargar la bateria pero la resistencia esta muy alta. La resistencia que yo me refiero es la R6 que es de 470K. Segun Maxim la bateria debe de conectarse directamente al clock. Porque de esa resistencia tan alta no le se. Posiblemente la que debe ir es la resistencia R5 y la R6 debe de ir donde esta la R5. Bueno para solucionar el problema removi la R6 y puse un jumper y removi el diodo y puse una bateria regular. El reloj trabajo normarmente sin perder la hora. Esto no quire decir que tu tienes el mismo problema pues no se si tu modulo es igual al mio. Adjunto el esquematico para que veas de lo que estoy explicando.

Bueno... estoy desconcertado. La batería o la pila entran en función cuando la tensión de alimentación en el pin 14 del DS3231 cae por debajo del Vpf (Power Fail Voltaje, cuyo valor típico es de 2,575V -según la datasheet) en el DS3231 (el esquema de bloques has puesto corresponde a un módulo RTC con el chip DS 1307Z).

La resistencia R6 de 470K es parte de un divisor de tensión que se completa con R4 de 1,5M, lo cual reduce la tensión de entrada por 0,76, es decir, con una tensión de batería de 3,2V caería a 2,43V, es decir, sólo un poco por encima de la tensión mínima (2,3).

Es posible que sea éste el problema, es decir: que con una pila nueva (CR) a plena carga esté por debajo de la tensión mínima de funcionamiento. No parece lógico y si es cierto no entiendo cómo los foros no están repletos de quejas.

Voy a seguir experimentando sobre este supuesto. Hay dos detalles que me mosquean:

Adafruit es el fabricante de un módulo que lleva una pila 1220, sin memoria y con una carga paupérrima y sugiere la posibilidad de una actualización de la hora cada vez que haya un reseteo (un apagado y encendido de la fuente exterior). Esto es posible con la instrucción que detecta si ha fallado la tensión de la batería pero sería una ñapa con un error de, al menos, 12 segundos.

El otro módulo que he probado es un conjunto chino muy extendido que dispone de una memoria y que acepta una batería con recargable LIR2032 manejando tensiones de más de 4V, lo cual me hace dudar de si funcionaría.

Hi,
Si miras las especificaciones de Maxim ellos conectan la bateria directamente al pin Vbat. Si el fabricante dice que se conecte en esa forma porque no conectarla en la forma que el fabricante indica. Adjunto link de las especificaciones de Maxim. Por eso fue que yo la conecte como dice maxim que se conecte y no tuve mas problemas.

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

Gracias tauro0221. Es cierto, pero también es cierto que todas las hojas de especificaciones son orientativas. En la página 9 del manual, Maxim, indica que el pin Vbat es el 14. Ésta es una fuente de respaldo para cuando la alimentación externa aplicada en el pin 2 Vcc caiga por debajo de la tensión Vpf.

De acuerdo con las especificaciones del chip, los fabricantes de módulos aplican sus soluciones. Adafruit fabrica un módulo en el que inserta la batería directamente en el pin 14 Vbat y me ha fallado. El módulo que dispone de memoria (probablemente el más difundido cuyo fabricante desconozco) también me ha fallado. Lo que me ha fallado, lo que me desconcierta es que sin conectar el módulo la tensión en Vbat es superior a los 3V.

En el manual de Maxim, en la página 10, Tabla 1, indica la lógica del control de alimentación:

Si Vcc < Vpf y Vcc < Vbat entonces se activa la alimentación desde Vbat, lo cual quiere decir que en el pin 14 del chip tiene que tener una tensión superior a 2,33V para que funciones si Vcc (0 cuando está desconectada la fuente exterior).

La única explicación de que no me funcione el proyecto es que la tensión en Vbat esté por debajo de las especificaciones a pesar de mis mediciones o que el sistema de control de alimentación falle. (¿pero en cuatro módulos diferentes?)

El diagrama de bloques que has puesto en un post creo que corresponde a un trabajo publicado por un autor que lo que busca es reducir el consumo de la batería al mínimo eliminando el sistema de carga lenta de una batería de litio recargable y colocando una pila CR. Yo he utilizadoi pilas CR directamente y estoy esperando unas baterías ILR2032 para probar. Sigo haciendo pruebas y muchas gracias por la ayuda.

Hi

Los modulos mios son 3 chinos que compre en ebay y los 3 tuvieron el mismo problema de perder la hora cuando le quitabas la energia. Los iba a tirar a la basura hasta que encontre ese circuito y los 3 siguen al pie de la letra el esquematico con los mismo valores de los componentes. Yo resolvi el problema como ya mencione en el hilo anterior. Por eso te adverti que compararas el esquematico para ver si es igual al tuyo. Algunas veces la solucion no es la misma para todo el mundo. Como yo los iba a tirar a la busura no perdia nada haciendole la revision. Los 3 ya llevan un buen tiempo trabajando sin problemas. Ahora usan baterias regulares.

Tienes razón voy a probar. Tengo dos de esos módulos chinos con memoria y los voy a "operar". Pero también tengo otros módulos de Adafruit cuya pila CR1220 se conecta directamente a Vbat y tampoco funcionan.

Voy a seguir investigando y si lo resuelvo lo pondré en este hila. Muchas gracias por la ayuda.

A ver, tal vez la cosa sea un problema de hardware pero no pierdes nada con probar este código.
Yo usaba una librería y con esto solucioné mi problema

las librerías son de pjrc

Ejemplo TimeRTC.ino

/*
 * TimeRTC.pde
 * example code illustrating Time library with Real Time Clock.
 * 
 */

#include <TimeLib.h>       // https://github.com/PaulStoffregen/Time
#include <Wire.h>
#include <DS1307RTC.h>  // https://github.com/PaulStoffregen/DS1307RTC

void setup()  {
  Serial.begin(9600);
  while (!Serial) ; // wait until Arduino Serial Monitor opens
  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()
{
  if (timeStatus() == timeSet) {
    digitalClockDisplay();
  } else {
    Serial.println("The time has not been set.  Please run the Time");
    Serial.println("TimeRTCSet example, or DS1307RTC SetTime example.");
    Serial.println();
    delay(4000);
  }
  delay(1000);
}

void digitalClockDisplay(){
  // digital clock display of the time
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(" ");
  Serial.print(day());
  Serial.print(" ");
  Serial.print(month());
  Serial.print(" ");
  Serial.print(year()); 
  Serial.println(); 
}

void printDigits(int digits){
  // utility function for digital clock display: prints preceding colon and leading 0
  Serial.print(":");
  if(digits < 10)
    Serial.print('0');
  Serial.print(digits);
}

Si miras tiene esta instrucción

setSyncProvider(RTC.get);   // the function to get the time from the RTC

Donde se llama la hora del RTC

y con
setSyncInterval(900);
puedes decirle que lo repita cada tanto tiempo (en este caso cada 900 seg) como para asegurarte que este sincronizado.

Bueno... ya me voy aclarando algo aunque aún no encuentro una acción-respuesta segura.

En primer lugar estoy utilizando un módulo chino con un esquema de bloques diferente al que se ha presentado en este hilo. Diferente chip y diferente esquema.

He encontrado por fin un esquema de bloques de este módulo antes ya había dibujado las entradas de Vcc y Vba.

En primer lugar, y lo más importante, es que la batería está conectada directamente a la entrada Vbat, y el circuito de carga viene de Vcc con una resistencia de 200 ohmios y un diodo 1N4148. Este diseño se basa en utilizar una batería recargable ILR2032. No sé en qué le puede afectar a la pila CR2032 tener un circuito de carga conectado. En teoría lo importante es que cuando se desconecta la fuente de alimentación externa (pin 14 del chip DS3231) la tensión que suministra la batería debe ser superior a 2,3V y he comprobado siempre que la tensión es de 3,2V al menos. Eso para mí es un misterio.

Ahora los dos módulos funcionan con pila CR2032, pero no siempre, fallan de vez en cuando. Vol a eliminar la resistencia de 200 con la pila CR2032 en uno de los módulos a ver que pasa y el otro le colocaré una batería ILR2032.

Esquema Bloques.jpg

Post#2 que te respondí?

Suele ocurir que algunos modulos DS3231 usan una pila LIR2032 en lugar de la CR y la diferencia es que la primera es recargable y la segunda no.

El resto de la respuesta se lee en el post#2, no voy a repetirlo.

Gracias surbyte,

Utilizo la librería RTClib con la que estoy familiarizado aunque no descarto utilizar otras que permita manipular los registros.

No he contestado antes porque esperaba un par de baterías de litio recargables LIR2032 para probar. Han llegado, lo he probado, y sigue sin funcionar.

Tengo bastante experiencia en el montaje de proyectos de electrónica y aunque con mis limitaciones puedo interpretar esquemas y especificaciones de circuitos integrados. El circuito integrado DS3231 sólo necesita una tensión positiva de corriente continua entre los 2,3V y 5,5V (Valor típico 3V) en el pin 14 (Vbat).

Vbat mantiene la el funcionamiento del reloj cuando la tensión de una fuente externa aplicada en Vcc (pin 2) cae por debajo de la Vpf (power-fail voltage, 2,4V). No importa si en Vbat hay una batería recargable. una pila desechable o incluso una fuente regulada siempre que la tensión sea mayor de 2,3V e inferior de 5,5V.

Estas condiciones se cumplen con los dos tipo de módulos que utilizo, con pila o con batería. Es evidente que estoy haciendo algo mal y ahora puedo descartar que la causa sea el tipo de diseño de la placa del módulo, con cargador o sin cargador. Es más, si desconecto la fuente de alimentación externa, el RTC no se resetea con los valores iniciales sino con la fecha y la hora de la última compilación.

Llevo un par de semanas sin poder resolver el problema y esperaba encontrar alguna ayuda en este foro, en cualquier caso estoy muy agradecido por la atención que me habéis prestado.

Me disculpo por la forma en el que he subido la imágenes, he leído la forma correcta de hacer y, la verdad, es que no tengo la capacidad suficiente para entenderlo.