Reloj dual con RCT3231 y Arduino

Un reloj en tiempo real (RTC en inglés) es un componente destinado a mantener la hora actual en dispositivos electrónicos que necesitan conocer la hora exacta. Los módulos con mayor difusión en los canales de venta por Internet incluyen circuitos integrados RTC fabricados por Maxim Integrated. Estos módulos incluyen una pila de botón, como alimentación de reserva, con el fin de que el reloj siga funcionando cuando se apaga la alimentación principal. Debido al escaso consumo, una pila CR2032 puede durar más de cinco años.

Los primeros módulos están basados en el circuito integrado DS1307, actualmente, los más modernos incluyen el DS3231S y DS3231M. Los primeros disponen de un oscilador a cristal compensado en temperatura (TXCO) que proporciona una precisión de 2 ppm a temperaturas de 0 a 40 grados. El modelo M alcanza una precisión de 5 ppm.

Maxim Integrated, DS3231 Datasheet

Adafruit oferta un módulo que incluye un DS3231S con una pila CR1220. Además, en Internet, hay una oferta abundante de módulos “low cost”, de diferentes distribuidores chinos, basados en el DS3231SN que incluyen un soporte para baterías de Ion-Litio LIR2032 con circuito para la recarga y una memoria ATMEL832 24C32N.

Antes de utilizar algunos de estos módulos es necesario tener en cuenta dos observaciones importantes:

Los módulos con cargador se suministran mayoritariamente con pilas CR2032 NO RECARGABLES en lugar de baterías LIR3220. Es desaconsejable utilizar pilas no recargables sometidas a una tensión de carga. Por un lado, aunque se utilicen baterías recargables tipo LIR3220, la tensión suministrada desde la fuente de alimentación externa a 5V a través de un ineficiente circuito compuesto por una resistencia de 200 ohmios y un diodo tipo 1N4148. Este diseño, en serie, puede dar lugar a un deterioro y consiguiente destrucción de la batería a largo plazo. Por otro lado, el bajo consumo del módulo le proporciona una duración a la pila de cinco años, al menos, lo que hace ineficiente o innecesario el uso de una batería recargable.

El Internet hay abundantes debates sobre este tema. Algunos autores recomiendan como medida más prudente para utilizar estos módulos, suprimir la alimentación a la batería eliminando el diodo y la resistencia en serie de 200 ohmios. Asimismo, es aconsejable suprimir el diodo LED que indica el encendido para reducir el consumo. En cualquier caso, parece razonable considerar que no se debe utilizar este módulo con una pila CR3220 sin eliminar antes el circuito de carga.

La segunda observación, trata de la recuperación del tiempo real después de apagar la alimentación principal. El RTC DS3231 sigue funcionando correctamente sin la fuente de alimentación principal, mientras la batería de respaldo suministre una tensión igual o superior a los 2,7 Vcc (Power-Fail Voltage – Vpf) en el pin 14 Vbat del DS3231. Sin embargo, si se utiliza la instancia rtc.adjust(DateTime(init_year, init_month, init_day, init_hour, init_minute, init_seconds)); para ajustar el tiempo, cuando se apaga y se vuelve a conectar la fuente principal, el DS3231 devuelve el tiempo que se introdujo en el ajuste y no el tiempo real.

A pesar de esto, si se compila de nuevo el sketch sin ajustar el tiempo, antes de apagar y encender la alimentación principal, el DS3231 devuelve la hora real. Esto ocurre con varios módulos que he probado utilizando la librería RCTlib.h.

Hardware .-

Para este trabajo he montado los escasos componentes en una placa de circuito impreso perforada estándar de 2,54mm de 60 X 40 mm (24 X 16 orificios) que incluye el módulo RTC, el Arduino NANO y las salidas.

El display 2004 se aloja en la parte superior de una caja de aluminio Minibox reciclada de de 105 X 75 X 30 mm, los conectores son Dupont. He añadido salidas digitales D5 a D9 para el futuro desarrollo de un sistema de puesta en hora.

Los componentes .-

  • Arduino NANO
  • RTC3231
  • Adaptador I2C PCF8574
Circuito impreso y esquema

Características .-

La información que puede presentar la pantalla puede modificarse. En este trabajo presenta:

  • Fecha en formato día * nombre del mes * año (cuatro dígitos).
  • Nombre del día de la semana.
  • Hora local en formato HH:MM:SS
  • Hora UTC en formato MM:SS
  • Cambio automático de fecha a las 0 hora local, cambio automático del horario de verano e invierno.

El sketch .-

He utilizado la librería de Adafruit RTClib.h que proporciona las clase y métodos necesarios para extraer la fecha y el tiempo UTC. Una vez creado el objeto rtc.

Las funciones

  • void process_date() {};
  • void process_time() {};

Procesan la hora local y UTC simultáneamente y muestran los resultados en el display. El loop() es muy sencillo, en cada bucle comprueba, en primer lugar, si ha cambiado el día en base a la hora local y, si es así, la cambia en el display. En segundo lugar, comprueba si se ha cambiado de horario de invierno o verano, si es así, ajusta la variable time_offset que añade la diferencia horaria de cada periodo.

La función check_next_day() es la encargada de comprobar la hora local ha pasado al día siguiente, teniendo en cuenta de que el tiempo que pilota el reloj es la hora UTC.

La función check_period() es la encargada de calcular la diferencia horaria entre la hora UTC y la local en periodo de invierno y verano y almacenarla en la variable global time_offset. La dificultad consiste en el cálculo, en tiempo real, del día de los meses de marzo y octubre que corresponde al último domingo.

El código se puede descargar desde el repositorio de GitHub.

Adenda, 19 de abril de 2020. Nuevo ajuste del tiempo

Ajustar la hora por medio de la compilación del código con la modificación del propio código y el engorro de calcular los segundos que tarda en compilar el sketch para ajustar la hora al segundo se puede evitar programando un sistema de ajuste de la hora externo.

Hay diferentes métodos para poner en hora el reloj.

  • Por medio de un ajuste automático, GPS, NTP u hora estándar desde el PC.
  • Por medio de pulsadores similar al que utilizan los relojes comerciales.
  • Por medio del monitor del puerto serie.

En principio he pospuesto los dos primeros métodos que requieren un esfuerzo de programación complejo pero que no descarto en el futuro.

El más rápido de programar es el tercero, para ello he creado una instancia en el loop que detecta si hay información en la entrada del monitor.

if (Serial.available()) {
char set_time[14];
size_t count = Serial.readBytesUntil(‘\n’, set_time, 14);
process_set_time(set_time);
}

Los datos que se introducen en el monitor son la fecha y la hora a los que se desea ajustar el RTC con el formato: “DDMMYYYYhhmm”, día, mes, año, hora y minuto. La función process_set_time(set_time); recibe los caracteres y procesa la cadena transformando cada dato en valores int. Finalmente los vuelfa en la memoria del RTC.

Este método tiene el inconveniente de que es necesario conectar el reloj al IDE del Arduino y activar el monitor serie, pero tiene la ventaja de que la entrada ajusta el reloj instantáneamente sin necesidad de compilar y, además, no tiene el problema de mantenimiento del tiempo real con la batería de respaldo cuando se apaga la fuente de alimentación principal. Problema que ocurre cuando se ajusta el tiempo en el momento de la compilación utilizando la misma función rtc.adjust(year, month, day, hour, minute, second);

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google photo

Estás comentando usando tu cuenta de Google. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s