Está en la página 1de 7

TEMA: ARDUINO - SENSORES RTC DS3231 Y DS1307

CICLO LECTIVO 2022


PROFESOR GERARDO DÍAZ

RELOJ Y CALENDARIO EN ARDUINO CON LOS RTC DS1307 Y DS3231

¿QUÉ ES UN RELOJ DE TIEMPO REAL RTC?

Un reloj de tiempo real (RTC) es un dispositivo electrónico que permite obtener


mediciones de tiempo en las unidades temporales que empleamos de forma cotidiana.

El término RTC se creó para diferenciar este tipo de relojes de los relojes electrónicos
habituales, que simplemente miden el tiempo contabilizando pulsos de una señal, sin existir
relación directa con unidades temporales.

Por el contrario los RTC son más parecidos a los relojes y calendarios que usamos
habitualmente, y que funcionan con segundos, minutos, horas, días, semanas, meses y años.

Los RTC normalmente están formados por un resonador de cristal integrado con la
electrónica necesaria para contabilizar de forma correcta el paso del tiempo. La electrónica de
los RTC tienen en cuenta las peculiaridades de nuestra forma de medir el tiempo, como por
ejemplo el sistema sexagesimal, los meses con diferentes días, o los años bisiestos.

Los RTC aportan la ventaja de reducir el consumo de energía, aportar mayor precisión y
liberar a Arduino de tener que realizar la contabilización del tiempo. Además, frecuentemente los
RTC incorporan algún tipo de batería que permite mantener el valor del tiempo en caso de
pérdida de alimentación.

En el mundo de la electrónica casera y Arduino existen dos RTC habituales el DS1307 y el


DS3231, ambos fabricados por Maxim (anteriormente Dallas Semiconductor). El DS3231 tiene
una precisión muy superior y puede considerarse sustituto del DS1307.

En el modelo DS1307 las variaciones de temperatura que afectan a la medición del


tiempo de los cristales resonadores se traducen en errores en un desfase acumulado. Esto hace
que el DS1307 sufra de un desfase temporal, que puede llegar a ser 1 o 2 minutos al día.

Para solucionarlo, el DS3231 incorpora medición y compensación de la


temperatura garantizando una precisión de al menos 2ppm, lo que equivale a un desfase
máximo 172ms/día o un segundo cada 6 días. En el mundo real normalmente consiguen
precisiones superiores, equivalente a desfases de 1-2 segundos al mes.

La comunicación en ambos modelos se realiza a través del bus I2C, por lo que es sencillo
obtener los datos medidos. La tensión de alimentación es 4.5 a 5.5 para el DS1307, y 2.3 a 5.5V
para el DS3231.

Frecuentemente estos módulos también incorporan una pequeña EEPROM AT24C32,


que puede ser empleada para almacenar registros y mediciones. En el caso del DS3231, la
medición de temperatura también está disponible, aunque tiene una precisión baja ±3ºC, y el
tiempo de adquisición puede durar hasta 1 segundo.

También incorporan una batería CR2032 para mantener el dispositivo en hora al retirar la
alimentación. Esta batería debería ser capaz de mantener alimentado durante varios años al
TEMA: ARDUINO - SENSORES RTC DS3231 Y DS1307
CICLO LECTIVO 2022
PROFESOR GERARDO DÍAZ

DS1307, y durante meses al DS3231. La tensión de alimentación de batería es de 2.0 a 3.5 para
el DS1307 y de 2.3 a 5.0 para el DS3231.

Los RTC son dispositivos ampliamente utilizados en electrónica. Todos los ordenadores
personales, servidores, tablets, y smartphone incorporan uno. También son muy frecuentes en
sistemas embebidos y, en general, en multitud de dispositivos que requieren realizar un registro
del tiempo.

En nuestros proyectos de electrónica frecuentemente necesitáramos un RTC. Por ejemplo,


podemos temporizar el encendido de luces o sistemas de riego, realizar un datalogger, o incluso
encender y apagar el propio Arduino para ahorra batería.

ESQUEMA DE MONTAJE

La conexión es sencilla y similar tanto para el DS1307 como el DS3231. Simplemente


alimentamos el módulo desde Arduino mediante 5V y Gnd. Por otro lado, conectamos los pines
del bus I2C a los correspondientes de Arduino.

La conexión de un módulo con DS1307 sería la siguiente,

Similar a la de un módulo que DS3213, que sería la siguiente,

En ambos casos la conexión, vista desde el lado de Arduino, es la misma, y quedaría así.
TEMA: ARDUINO - SENSORES RTC DS3231 Y DS1307
CICLO LECTIVO 2022
PROFESOR GERARDO DÍAZ

En Arduino Uno, Nano y Mini Pro, SDA es el pin A4 y el SCK el pin A5. Para otros modelos de
Arduino consultar el esquema patillaje correspondiente.

EJEMPLOS DE CÓDIGO

Para realizar la lectura del DS1307 y del DS3231 usaremos la librería desarrollada por
Adafruit válida para ambos modelos, disponible en este enlace. La librería proporciona ejemplos
de código, que resulta aconsejable revisar.

OBTENER LA FECHA Y HORA

El primer ejemplo emplea el RTC para obtener los datos de fecha y hora actual.
Posteriormente se emplean estos valores para mostrarlos por puerto serie. También se muestra
como fijar la fecha y la hora, y detectar la perdida de energía.

#include <Wire.h>
#include "RTClib.h"
// RTC_DS1307 rtc;
RTC_DS3231 rtc;
String daysOfTheWeek[7] = { "Domingo", "Lunes", "Martes", "Miercoles", "Jueves",
"Viernes", "Sabado" };
TEMA: ARDUINO - SENSORES RTC DS3231 Y DS1307
CICLO LECTIVO 2022
PROFESOR GERARDO DÍAZ

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("Couldn't find RTC"));
while (1);
}
// Si se ha perdido la corriente, fijar fecha y hora
if (rtc.lostPower()) {
// Fijar a fecha y hora de compilacion
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

// Fijar a fecha y hora específica. En el ejemplo, 21 de Enero de 2016 a las 03:00:00


// rtc.adjust(DateTime(2016, 1, 21, 3, 0, 0));
}
}
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);
}

ENCENDIDO Y APAGADO PROGRAMADO

El siguiente ejemplo un proyecto habitual, emplear un RTC para activar o desactivar un


dispositivo en un horario y fechas determinados. Por ejemplo, puede servir para controlar el riego
de un jardín, encender las luces, la calefacción, desplegar un toldo, o controlar cualquier otro
dispositivo mediante un relé.

La función IsScheduledON controla el encendido o apagado. En el ejemplo, está


programado el encendido los miércoles, sábado, y domingo de 09:30 a 11:30 y de 21:00 a 23:00.
Modificando el cuerpo de esta función, podéis programar la condición de encendido y apagado
que necesitéis.
TEMA: ARDUINO - SENSORES RTC DS3231 Y DS1307
CICLO LECTIVO 2022
PROFESOR GERARDO DÍAZ

#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__)));
}
}
// Comprobar si esta programado el encendido
bool isScheduledON(DateTime date)
{
int weekDay = date.dayOfTheWeek();
float hours = date.hour() + date.minute() / 60.0;
// De 09:30 a 11:30 y de 21:00 a 23:00
bool hourCondition = (hours > 9.50 && hours < 11.50) || (hours > 21.00 && hours < 23.00);
// Miercoles, Sabado o Domingo
bool dayCondition = (weekDay == 3 || weekDay == 6 || weekDay == 0);
if (hourCondition && dayCondition)
{
return true;
}
return false;
}
void loop() {
DateTime now = rtc.now();
if (state == false && isScheduledON(now)) // Apagado y debería estar encendido
{
digitalWrite(outputPin, HIGH);
state = true;
Serial.print("Activado");
}
else if (state == true && !isScheduledON(now)) // Encendido y deberia estar apagado
{
digitalWrite(outputPin, LOW);
state = false;
Serial.print("Desactivar");
}
delay(3000);
}

DATALOGGER CON RTC

El siguiente ejemplo muestra otro caso muy habitual, el empleo de un RTC para generar un
Datalogger, es decir, un dispositivo que periódicamente registra la medición de un sensor. En el
ejemplo, emplearemos una tarjeta SD para guardar los valores.
TEMA: ARDUINO - SENSORES RTC DS3231 Y DS1307
CICLO LECTIVO 2022
PROFESOR GERARDO DÍAZ

Simplemente, obtenemos la fecha, hora, y valor del sensor, que en el ejemplo simulamos
con la función readSensor(), y guardamos los datos en la tarjeta con la función logValue(,,).

En un proyecto real podríamos guardar una o varias mediciones, separadas por comas, por
ejemplo. También podríamos variar el momento de la medición, que en el ejemplo se realiza
cada 10 segundos a, por ejemplo, cuando ocurra un evento, o en ciertas horas del día empleando
el propio RTC.

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "RTClib.h"
File logFile;
// RTC_DS1307 rtc;
RTC_DS3231 rtc;
void setup()
{
Serial.begin(9600);
Serial.print(F("Iniciando SD ..."));
if (!SD.begin(4))
{
Serial.println(F("Error al iniciar"));
return;
}
Serial.println(F("Iniciado correctamente"));
}
// Funcion que simula la lectura de un sensor
int readSensor()
{
return 0;
}
void logValue(DateTime date, int value)
{
logFile.print(date.year(), DEC);
logFile.print('/');
logFile.print(date.month(), DEC);
logFile.print('/');
logFile.print(date.day(), DEC);
logFile.print(" ");
logFile.print(date.hour(), DEC);
logFile.print(':');
logFile.print(date.minute(), DEC);
logFile.print(':');
logFile.print(date.second(), DEC);
logFile.print(" ");
logFile.println(value);
}
void loop()
{
// Abrir archivo y escribir valor
logFile = SD.open("datalog.txt", FILE_WRITE);
if (logFile) {
int value = readSensor();
TEMA: ARDUINO - SENSORES RTC DS3231 Y DS1307
CICLO LECTIVO 2022
PROFESOR GERARDO DÍAZ

DateTime now = rtc.now();


logValue(now, value);
logFile.close();
}
else {
Serial.println(F("Error al abrir el archivo"));
}
delay(10000);
}

También podría gustarte