DS3231: reloj en tiempo real y calendario para tu Arduino

DS3231

En algunos proyectos se necesita tener constancia del tiempo, de la hora, o la fecha. Ya sea por la necesidad de realizar ciertas funciones en función del tiempo, para mantener un calendario de eventos o registro, para mantener la hora en un sistema, o simplemente para crear un reloj digital con Arduino. Con el DS3231 podrás conseguirlo, otro de los componentes que agregamos a la lista.

El DS3231 es el módulo que estabas buscando, y aquí encontrarás todo lo que necesitas para su control y también te mostraré un ejemplo de cómo integrarlo con Arduino con un ejemplo práctico…

¿Qué es el DS3231?

DS3231

Antes de nada, deberías saber qué es un RTC (Real Time Clock), o reloj de tiempo real. Estos chips son muy frecuentes en multitud de aplicaciones, de hecho, tu PC tiene uno de ellos en tu placa base, y está alimentado también por una pila CR2032 también. Es la que mantiene la hora y la configuración en el BIOS/UEFI y del que la coge el sistema operativo al arrancar para estar en hora (aunque ahora, con Internet, se puede usar la sincronización con servidores para mayor precisión, pero esto es otra historia…).

El RTC lo que hace es obtener mediciones de tiempo, así de simple. La diferencia con otros tipos de relojes electrónicos es que simplemente mide el tiempo, y lo hace contabilizando pulsos de señal de reloj, sabiendo la frecuencia y periodos de la misma. Además de la hora, un RTC también permite llevar una contabilidad de los días, semanas, meses y años. Es decir, la fecha completa…

Para que eso sea posible, el RTC debe ir acompañado de un Xtal o cristal de cuarzo que actuará como resonador, el que aporta la frecuencia. Adicionalmente, necesita una circuitería electrónica capaz de llevar el recuento y almacenar la fecha en una memoria. La circuitería debe ser capaz de contabilizar segundos, minutos, horas, días, semanas, meses y años.

Esa memoria es volátil, por eso necesita de la pila, para tener alimentación constante. Si no tiene pila o se agota, se borrará… Eso es lo que le ocurre a los PCs cuando se le agota la pila, dan una hora incorrecta. Si la configuras mientras el PC está encendido, la hora se mantendrá, ya que el RTC se está alimentando, pero es durante los procesos durante los que está apagado cuando se necesita de esa batería…

Para proyectos DIY, los makers suelen usar dos chips RTC habituales, que son el DS1307 y el DS3231. Ambos se fabrican por Maxim (antes Dallas Semiconductor), y es el DS3231 el más preciso de los dos, ya que no se ve tan afectado por variaciones de temperatura como lo hace el primero. Por ello, no fluctúa tanto dependiendo de la temperatura, y mantiene la hora de forma más precisa.

En ocasiones, con diferencias de temperatura notables, el DS1307 podría tener un desfase de hasta 1 o 2 min al día. Algo intolerable para algunas aplicaciones.

El DS3231 no es que no se vea afectado por las variaciones, sino que tiene sistemas de medición y compensación de la temperatura built-in para garantizar una precisión de 2ppm, lo que equivaldría a un desfase de tiempo de unos 172ms al día, es decir, algo más de 1 segundo a la semana como máxima. Y en la práctica, suelen variar solo 1 o 2 segundos al mes.

En cuanto a la forma de comunicarse con el RTC DS3131 para obtener los valores de fecha que consigue, se hace mediante bus I2C. Y para la alimentación, puedes usar 2.3 a 5.5v para el DS3231, lo que es algo más bajo que los 4.5 a 5.5v del DS1307, por lo que puede ser más eficiente energéticamente y hacer que la pila dure más.

Además, debes saber que estos módulos suelen tener una EEPROM adicional AT24C32 para almacenar algunos registros y mediciones previas, lo que es bastante práctico.

Aplicaciones

En cuanto a las aplicaciones, ya he citado algunas, como para implementar un reloj con Arduino, para crear un sistema que actúe en función de la hora que sea, para mantener l hora en equipos como PCs y otros muchos dispositivos electrónicos y electrodomésticos que tienen hora, etc.

También se puede usar en proyectos para crear temporizadores para iluminación, sistemas de riego, datalogger, etc. Las aplicaciones pueden ser de lo más numerosas…

Comprar un RTC DS3231

El módulo DS3131 es barato, y lo puedes encontrar en algunas tiendas especializadas de electrónica o en grandes superficies como eBay, AliExpress, Amazon, etc. Si te interesa tener uno, aquí tienes algunas recomendaciones:

Integración con Arduino del DS3231

Captura de pantalla de Arduino IDE

Si quieres integrar tu DS3231 con tu placa Arduino y comenzar a crear proyectos «temporizados», primero debes realizar las conexiones oportunas. Para poderlo conectar, es tan simple como:

  • El pin SLC de la placa DS3231 debes conectarlo al A5 de tu Arduino UNO.
  • SDA del DS3231 va conectado a A4 de Arduino.
  • Vcc del módulo irá a 5V de Arduino.
  • GND a GND.
Recuerda instalar la biblioteca para usar el RTC DS3231 en tu Arduino IDE o no funcionará el código…

Ahora ya tienes conectado el sistema, lo siguiente es escribir el código fuente del sketch para programarlo. Puedes modificar los códigos y adaptarlos a tus necesidades, pero podrías empezar por simplemente obtener la fecha de un RTC DS3231 conectado a Arduino:


#include <Wire.h>
#include "RTClib.h"
 
// RTC_DS1307 rtc;
RTC_DS3231 rtc;
 
String daysOfTheWeek[7] = { "Domingo", "Lunes", "Martes", "Miércoles", "Jueves", "Viernes", "Sábado" };
String monthsNames[12] = { "Enero", "Febrero", "Marzo", "Abril", "Mayo",  "Junio", "Julio","Agosto","Septiembre","Octubre","Noviembre","Diciembre" };
 
void setup() {
   Serial.begin(9600);
   delay(1000); 
 
   if (!rtc.begin()) {
      Serial.println(F("No se encuentra el RTC"));
      while (1);
   }
 
   // Si se ha perdido el suministro eléctrico, fijar fecha y hora
   if (rtc.lostPower()) {
      // Fijar a fecha y hora (poner la de compilación del sketch)
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
      
      // Fijar a fecha y hora específica. En este ejemplo el 2021-01-01 a las 00:00:00
      // rtc.adjust(DateTime(2020, 1, 1, 0, 0, 0));
   }
}
//Imprimir completa obtenida la fecha en decimal
void printDate(DateTime date)
{
   Serial.print(date.year(), DEC);
   Serial.print('/');
   Serial.print(date.month(), DEC);
   Serial.print('/');
   Serial.print(date.day(), DEC);
   Serial.print(" (");
   Serial.print(daysOfTheWeek[date.dayOfTheWeek()]);
   Serial.print(") ");
   Serial.print(date.hour(), DEC);
   Serial.print(':');
   Serial.print(date.minute(), DEC);
   Serial.print(':');
   Serial.print(date.second(), DEC);
   Serial.println();
}
 
void loop() {
   // Obtener fecha actual y mostrar por Serial
   DateTime now = rtc.now();
   printDate(now);
 
   delay(3000);    //Espera 3 segundos
}

Y para poder usar la fecha del RTC para programar alguna tarea, como por ejemplo para el enendido o apagado de unas luces, para un riego automático, o para que suene una alarma, etc. Recuerda que para manejar dispositivos de mayor voltaje puedes usar transistores o relé:


#include <Wire.h>
#include "RTClib.h"
 
const int outputPin = LED_BUILTIN;
bool state = false;
 
// RTC_DS1307 rtc;
RTC_DS3231 rtc;
 
void setup() {
   Serial.begin(9600);
   delay(1000);
 
   if (!rtc.begin()) {
      Serial.println(F("Couldn't find RTC"));
      while (1);
   }
 
   if (rtc.lostPower()) {
      rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
   }
}
 
// Se comprueba si está programado el encendido
bool isScheduledON(DateTime date)
{
   int weekDay = date.dayOfTheWeek();
   float hours = date.hour() + date.minute() / 60.0;
 
   // Configuración de horas de 08:30 a 9:30 y de 22:00 a 23:00 (usando decimal)
   bool hourCondition = (hours > 8.50 && hours < 9.50) || (hours > 22.00 && hours < 23.00);
 
   // Configuración del día Lunes, Sábado y Domingo con números (recuerda que en inglés comienza la semana en Domingo=0, Lunes=1,...
   bool dayCondition = (weekDay == 1 || weekDay == 6 || weekDay == 0); 
   if (hourCondition && dayCondition)
   {
      return true;
   }
   return false;
}
 
void loop() {
   DateTime now = rtc.now();
 
   if (state == false && isScheduledON(now))      // Apagado
   {
      digitalWrite(outputPin, HIGH);
      state = true;
      Serial.print("Activado");
   }
   else if (state == true && !isScheduledON(now))  // Encendido
   {
      digitalWrite(outputPin, LOW);
      state = false;
      Serial.print("Desactivado");
   }
 
   delay(3000);
}


Sé el primero en comentar

Deja tu comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

*

*

  1. Responsable de los datos: Miguel Ángel Gatón
  2. Finalidad de los datos: Controlar el SPAM, gestión de comentarios.
  3. Legitimación: Tu consentimiento
  4. Comunicación de los datos: No se comunicarán los datos a terceros salvo por obligación legal.
  5. Almacenamiento de los datos: Base de datos alojada en Occentus Networks (UE)
  6. Derechos: En cualquier momento puedes limitar, recuperar y borrar tu información.