En este tutorial aprenderás cómo usar un módulo de reloj en tiempo real (RTC) DS3231 con un ESP32.
Un módulo RTC es un reloj externo que mantiene el seguimiento de la hora y fecha actuales. Funciona de forma independiente a la alimentación principal del sistema, permitiendo mantener la hora precisa incluso cuando la energía está apagada.
Te mostraré cómo usar un RTC en combinación con el ESP32 en modo deep-sleep, cómo ajustar el RTC para el horario de verano y cómo sincronizar el RTC con un servidor de tiempo por internet.
Partes necesarias
Para este proyecto necesitarás un módulo RTC DS3231 y un ESP32. Yo uso el ES32 lite como microprocesador, ya que tiene una interfaz de carga de batería que permite alimentar el ESP32 y el RTC con una batería LiPo. Sin embargo, cualquier otro ESP32 o ESP8266 también funcionará. Para mostrar la hora, elegí un OLED, pero también podrías usar un LCD display.

ESP32 lite

Cable USB de datos

Módulo RTC DS3231

Juego de cables Dupont

Protoboard

Pantalla OLED
Makerguides is a participant in affiliate advertising programs designed to provide a means for sites to earn advertising fees by linking to Amazon, AliExpress, Elecrow, and other sites. As an Affiliate we may earn from qualifying purchases.
Conceptos básicos del chip DS3231
El DS3231 es un chip pequeño (38 x 22 x 14 mm) con un reloj en tiempo real (RTC) de alta precisión y un oscilador de cristal compensado por temperatura integrado. Este chip incluye un soporte para batería, lo que le permite funcionar incluso cuando la fuente de alimentación principal está desconectada.

El RTC mantiene el seguimiento de segundos, minutos, horas, día de la semana, fecha, mes y año. Para meses con menos de 31 días, la fecha se ajusta automáticamente, incluyendo correcciones para años bisiestos. El reloj puede operar en formato de 24 o 12 horas. Proporciona dos alarmas de calendario programables y una salida de onda cuadrada programable. La comunicación es vía bus I2C.
Una referencia de voltaje de precisión compensada por temperatura y un circuito comparador monitorean el estado de VCC, detectan fallos de energía, proporcionan una salida de reset y cambian automáticamente a la fuente de alimentación de respaldo cuando es necesario. El dispositivo integra un sensor de temperatura digital accesible vía interfaz I2C.
La siguiente sección lista las principales características del DS3231 (source):
Especificaciones técnicas
- Voltaje de operación: 3.3–5.5V
- Chip de reloj: Chip de reloj de alta precisión DS3231
- Precisión del reloj: 2ppm en el rango de 0-40°C, error anual aproximadamente 1 minuto
- Dos alarmas de calendario
- Salida de onda cuadrada programable
- El reloj en tiempo real genera segundos, minutos, horas, día de la semana, fecha, mes y año, con compensación para años bisiestos válida hasta 2100
- Sensor de temperatura incorporado con una precisión de ±3°C
- Chip de almacenamiento: AT24C32 (capacidad de almacenamiento de 32K)
- Interfaz de bus IIC, velocidad máxima de transmisión 400KHz (cuando el voltaje de operación es 5V)
- Puede conectarse en cascada con otros dispositivos IIC, la dirección 24C32 puede modificarse puenteando A0/A1/A2, la dirección por defecto es 0x57
- Usa batería CR2032 para asegurar que el reloj siga funcionando normalmente tras un corte de energía
Diagrama de bloques del DS3231
El siguiente diagrama de bloques muestra los componentes internos del DS3231. Puedes ver el oscilador de cristal, el sensor de temperatura, el control de energía y la interfaz I2C.

Los pines del DS3231 son los siguientes: VCC y GND para la alimentación general y VBAT para la batería de respaldo. SCL y SDA son para la interfaz I2C.
El pin etiquetado «33kHz» emite la señal de reloj de 32kHz. INT/SQW es un pin de interrupción que puede usarse para señalar alarmas o como salida de onda cuadrada programable.
RST es el pin de reset que puede usarse para indicar al microprocesador conectado que la energía se perdió o se restauró. Los pines «33kHz», INT/SQW y RST tienen otras funciones también. Para más detalles consulta la hoja de datos enlazada abajo:
Conceptos básicos del módulo RTC DS3231
El chip DS3231 es demasiado pequeño para conectarse directamente a un ESP32 y además le faltan algunos componentes necesarios. Por eso normalmente se usa un módulo RTC DS3231. El módulo incluye los componentes faltantes y también un soporte para una CR2032 batería que proporciona la alimentación de respaldo. La imagen abajo muestra el frente y la parte trasera de un módulo típico DS3231 RTC:

En lugar de una CR2032 batería también puedes usar una batería recargable LIR2032 pero debes tener cuidado con el voltaje de alimentación. Más sobre esto más adelante.
Pinout del módulo RTC DS3231
El pinout de un módulo RTC DS3231 es esencialmente el mismo que el descrito para el chip DS3231.

VCC y GND son para la alimentación, con un voltaje de suministro de 3.3–5.5V. SCL y SDA son los pines para la interfaz I2C (con resistencias pull-up integradas de 4.7k). Los pines 32K y SQW son salidas para la señal de reloj de 32kHz y la señal de onda cuadrada programable, pero no los necesitarás aquí.
La dirección I2C del módulo RTC DS3231 es configurable mediante tres pads de soldadura (A0, A1, A2) que pueden puentease. Mira la sección resaltada en la esquina inferior derecha del módulo en la imagen anterior. La dirección I2C por defecto es 0x57, cuando no hay puentes. La imagen abajo muestra todas las configuraciones posibles y las direcciones I2C correspondientes.

Carga de batería con el módulo RTC DS3231
El módulo RTC DS3231 permite cargar la batería de respaldo desde la fuente de alimentación principal (VCC). La imagen abajo muestra el diagrama del circuito del módulo RTC DS3231. En la sección marcada en amarillo, ves una resistencia de 200Ω y un diodo 1N4148 que actúan como un circuito de carga muy simple.

Sin embargo, debes desactivar este circuito de carga cuando uses una batería CR2032 no recargable con un voltaje de suministro VCC de 5V. Y si usas una batería recargable LIR2032, VCC nunca debe superar los 4.7 voltios para una carga segura.
El Battery charging circuit of DS3231 module artículo describe los problemas del circuito de carga con más detalle y también muestra cómo desactivarlo. La siguiente tabla del artículo lista los diferentes escenarios con distintos voltajes de suministro y tipos de batería, y qué se debe hacer:
| Tipo de batería | Suministro 3.3 V | Suministro 5 V |
|---|---|---|
| CR2032 | Batería no afectada | Desactivar circuito de carga |
| LIR2032 | Batería no afectada La carga no funciona | Desactivar circuito de carga, o Asegurarse de que 5 V sean realmente 4.7 V |
Conexión del módulo RTC DS3231 al ESP32 lite
Conectar el módulo RTC DS3231 a un ES32 es sencillo. Primero conecta SCL del DS3231 al pin 23 del ESP32. Luego conecta SDA al pin 19 del ESP32. Finalmente, conecta tierra a GND y 3.3V a VCC como se muestra abajo:

Como estamos alimentando el módulo RTC DS3231 con 3.3V, puedes tener una batería CR2032 insertada mientras está conectado a la fuente de alimentación.
Código de prueba simple para el módulo RTC DS3231
Necesitarás una librería de software para comunicarte con el módulo RTC DS3231. Hay varias, pero me gusta más la Arduino-DS3231 de Korneliusz Jarzębski. Para instalarla, ve a github repo y haz clic en el botón verde «Code». Luego selecciona «Download Zip» en el menú como se muestra abajo:

Esto descargará un archivo llamado «Arduino-DS3231-dev.zip» a tu ordenador. Para instalar esta librería ZIP sigue los pasos habituales. Haz clic en Sketch -> Add .ZIP Library y luego selecciona el archivo Arduino-DS3231-dev.zip que acabas de descargar.

Con la librería instalada, podemos probar la función del módulo RTC DS3231. El siguiente código simple establece la hora y fecha en el módulo RTC al momento de compilación del sketch y luego imprime la hora y fecha en un bucle:
#include "Wire.h"
#include "DS3231.h"
DS3231 rtc;
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(__DATE__, __TIME__);
}
void loop() {
RTCDateTime dt = rtc.getDateTime();
Serial.printf("%4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day, dt.hour, dt.minute, dt.second);
delay(1000);
}
El código comienza incluyendo la librería Wire.h para comunicación I2C y la librería DS3231.h para comunicarse con el RTC DS3231.
Luego, creamos una instancia de la clase DS3231. En la función setup() inicializamos el RTC y establecemos la fecha y hora actuales usando rtc.setDateTime(). Las macros __DATE__ y __TIME__ insertan automáticamente la fecha y hora en que se compiló el sketch. Ten en cuenta que la hora no será actual cuando el ESP32 se reinicie después de compilar y subir el código, pero eso lo manejaremos más adelante.
En la función loop, recuperamos la fecha y hora actuales del RTC usando RTCDateTime dt = rtc.getDateTime() y usamos printf para imprimir la fecha y hora en el Monitor Serial.
Ejemplo de salida
Si subes el código y abres el Monitor Serial, deberías ver la fecha y hora impresas así:

Horario de verano con el módulo RTC DS3231
Aunque el DS3231 mantiene un seguimiento preciso de la fecha y hora, no ajusta el horario de verano (DST). Esto significa que el DS3231 mostrará la hora (y fecha) incorrecta cuando tu país cambie a DST o vuelva al horario estándar (ST).
Hay esencialmente dos formas de manejar esto. 1) podrías añadir un botón que cambie manualmente entre DST y ST y viceversa. Esto obviamente no es óptimo. 2) añadir código que realice el cambio automáticamente para la zona horaria de tu país.
En esta sección, te muestro cómo manejar automáticamente el horario de verano usando el módulo RTC DS3231. Usaremos la librería ezTime Library para esto. Puedes instalarla vía Library Manager como de costumbre:

Una vez instalada, puedes usarla para ajustar el RTC DS3231 al horario de verano con el siguiente código:
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
Timezone loc;
DS3231 rtc;
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(2024,12,4,3,16,30); // UTC
loc.setPosix(TIMEZONE);
}
void loop() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
delay(5000);
}
En el código anterior, conectamos un ESP32 con un módulo RTC DS3231 para mantener la hora actual, incluyendo ajustes para el horario de verano. El programa inicializa el RTC, establece una fecha y hora específicas, y luego recupera y muestra continuamente la hora UTC y local cada 5 segundos.
Vamos a desglosar el código en sus componentes para entenderlo mejor.
Librerías incluidas
Comenzamos incluyendo las librerías necesarias para nuestro proyecto. La librería Wire.h se usa para comunicación I2C, que es como el ESP32 se comunica con el RTC DS3231. La librería DS3231.h proporciona funciones específicas para interactuar con el módulo DS3231, y ezTime.h se usa para manejar zonas horarias y ajustes de horario de verano.
#include "Wire.h" #include "DS3231.h" #include "ezTime.h"
Constantes y variables
Luego definimos una constante para la zona horaria. En este caso usamos AEST-10AEDT,M10.1.0,M4.1.0/3, que corresponde a Melbourne, Australia. Esta cadena indica el desfase horario estándar y las reglas para el horario de verano.
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
Las partes de esta definición de zona horaria son las siguientes
- AEST: Hora estándar del este de Australia
- -10: Desfase UTC de 10 horas adelantado respecto al Tiempo Universal Coordinado (UTC)
- AEDT: Hora de verano del este de Australia
- M10.1.0: La transición al horario de verano ocurre el primer domingo de octubre
- M4.1.0/3: La transición de vuelta al horario estándar ocurre el primer domingo de abril, con una diferencia de 3 horas respecto a UTC.
Para otras definiciones de zona horaria, consulta el Posix Timezones Database. Solo copia la cadena que encuentres allí y cambia la constante TIMEZONE en consecuencia.
También creamos instancias de las clases Timezone y DS3231. La variable loc contendrá la información de la hora local, mientras que rtc gestionará el módulo RTC.
Timezone loc; DS3231 rtc;
Función setup
En la función setup() inicializamos la comunicación serial a 9600 baudios para depuración. Luego inicializamos el RTC y lo configuramos a una fecha y hora específicas (4 de diciembre de 2024, 03:16:30 UTC). Finalmente, establecemos la zona horaria usando la constante definida anteriormente.
void setup() {
Serial.begin(9600);
rtc.begin();
rtc.setDateTime(2024,12,4,3,16,30); // UTC
loc.setPosix(TIMEZONE);
}
Función loop
La función loop() se ejecuta continuamente. Primero, recuperamos la fecha y hora actuales del RTC usando rtc.getDateTime(). Luego establecemos la hora UTC usando los valores recuperados.
RTCDateTime dt = rtc.getDateTime(); UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
A continuación, imprimimos la hora UTC actual en el monitor serial en una cadena formateada. Esto incluye año, mes, día, hora, minuto y segundo.
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
También imprimimos la hora local usando la variable loc, que ha sido ajustada para la zona horaria y el horario de verano.
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Finalmente, añadimos un salto de línea para mejor legibilidad en la salida serial e introducimos un retardo de 5000 milisegundos (5 segundos) antes de que el bucle se repita.
Serial.println(); delay(5000);
Ejemplo de salida
Si subes el código y abres el Monitor Serial, deberías ver la hora UTC del RTC y la hora local (LOC) impresas:

Sincronizar el RTC DS3231 con un servidor SNTP
Aunque el código anterior ahora maneja automáticamente el ajuste para el horario de verano, aún requiere que configures manualmente la hora del RTC al iniciar el ESP32. Peor aún, requiere que conectes el ESP32 a un ordenador, cambies el código y reprogrames el ESP32. ¡Esto es molesto!
Podrías añadir botones para editar la hora y fecha mientras el ESP32 está en funcionamiento. Si quieres hacer eso, echa un vistazo al tutorial Arduino and RTC Module DS3231, donde usamos dos botones para configurar la hora.
La mejor opción, sin embargo, es sincronizar automáticamente el RTC con un proveedor de tiempo por Internet (SNTP). Para más información, consulta el tutorial How to synchronize ESP32 clock with SNTP server.
Si tienes acceso constante a internet y no te importa el consumo de energía, no necesitarías un RTC, ya que puedes sincronizar regularmente el reloj interno del ESP32. Esto ajustaría automáticamente el reloj y también manejaría el horario de verano. Consulta los tutoriales Automatic Daylight Savings Time Clock y Digital Clock on e-Paper Display.
Sin embargo, para un proyecto alimentado por batería quieres evitar usar WiFi con demasiada frecuencia, ya que consume mucha energía. Un caso común es un registrador de datos, por ejemplo para temperatura, que quieres que funcione con batería el mayor tiempo posible pero que también necesite marcas de tiempo precisas.
El siguiente código te muestra cómo hacer esto. Usa WiFi solo cuando el ESP32 se reinicia para sincronizar el RTC. De lo contrario, el ESP32 está en modo deep-sleep para conservar energía y solo se despierta ocasionalmente para obtener la hora del RTC e imprimirla:
#include "WiFi.h"
#include "esp_sntp.h"
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne
const char* SSID = "SSID";
const char* PWD = "PASSWORD";
const int SLEEP = 10; // sec
DS3231 rtc;
Timezone loc;
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTzTime("UTC", "pool.ntp.org");
setRtcTime();
}
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
void printTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
}
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
void setup() {
Serial.begin(9600);
rtc.begin();
loc.setPosix(TIMEZONE);
if (isReset()) {
syncTime();
}
printTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
void loop() {
}
Vamos a desglosar el código en sus componentes para entenderlo mejor.
Librerías y constantes
Comenzamos incluyendo las librerías necesarias para Wi-Fi, SNTP (Protocolo simple de tiempo en red), comunicación I2C y el RTC DS3231. También definimos algunas constantes para la zona horaria, credenciales Wi-Fi y duración del sueño.
#include "WiFi.h" #include "esp_sntp.h" #include "Wire.h" #include "DS3231.h" #include "ezTime.h" const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3"; // Melbourne const char* SSID = "SSID"; const char* PWD = "PASSWORD"; const int SLEEP = 10; // sec
Obviamente, tendrás que reemplazar las credenciales Wi-Fi por las tuyas propias.
Objetos RTC y zona horaria
Creamos instancias de la clase DS3231 para el RTC y la clase Timezone para manejar los cálculos de hora local.
DS3231 rtc; Timezone loc;
Función de sincronización de hora
La función syncTime() conecta a la red WiFi y configura la zona horaria para el servidor NTP. Luego llama a setRtcTime() para actualizar el RTC con la hora actual.
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTzTime("UTC", "pool.ntp.org");
setRtcTime();
}
Función para establecer la hora del RTC
En la función setRtcTime(), recuperamos la hora local y configuramos la fecha y hora del RTC en consecuencia. El año se ajusta sumando 1900 porque el campo tm_year devuelve el número de años desde 1900.
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
Ten en cuenta que también tenemos que sumar 1 a tm_mon para obtener el mes correcto, ya que la estructura de datos struct tm usa rangos inconsistentes. Por ejemplo, el día del mes comienza en 1 pero el mes del año comienza en 0:
Member Type Meaning Range tm_sec int seconds after the minute 0-61* tm_min int minutes after the hour 0-59 tm_hour int hours since midnight 0-23 tm_mday int day of the month 1-31 tm_mon int months since January 0-11 tm_year int years since 1900 tm_wday int days since Sunday 0-6 tm_yday int days since January 1 0-365 tm_isdst int Daylight Saving Time flag
Función para imprimir la hora
La función printTime() recupera la fecha y hora actuales del RTC y las imprime en el Monitor Serial. También imprime la hora local usando el objeto de zona horaria.
void printTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
Serial.printf("RTC: %4d-%02d-%02d %02d:%02d:%02d\n",
dt.year, dt.month, dt.day,
dt.hour, dt.minute, dt.second);
Serial.printf("LOC: %4d-%02d-%02d %02d:%02d:%02d\n",
loc.year(), loc.month(), loc.day(),
loc.hour(), loc.minute(), loc.second());
Serial.println();
}
Función para comprobar el reinicio
La función isReset() comprueba si el ESP32 se despertó del deep sleep por un temporizador u otra causa. Esto ayuda a determinar si se debe sincronizar la hora o no.
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
Función setup
En la función setup() inicializamos la comunicación serial, el RTC y establecemos la zona horaria. Si el ESP32 está arrancando desde cero (no despertando del deep sleep), sincronizamos la hora. Finalmente, imprimimos la hora y ponemos el ESP32 en modo deep sleep por la duración especificada.
void setup() {
Serial.begin(9600);
rtc.begin();
loc.setPosix(TIMEZONE);
if (isReset()) {
syncTime();
}
printTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
Función loop
La función loop() está vacía porque el ESP32 no ejecutará código mientras esté en deep sleep. Solo se despertará para ejecutar la función setup() nuevamente tras la duración del sueño.
void loop() { }
Mostrar la hora del RTC en OLED
Como ejemplo final, quiero mostrarte cómo añadir un OLED para mostrar la hora y fecha del RTC en una pantalla. Esto es solo una extensión simple del código anterior.
Conectar el OLED es fácil, ya que también es un dispositivo I2C. Simplemente conecta SDA, SCL, VCC y GND del OLED en paralelo con el DS3231 como se muestra abajo

Abajo está el código que muestra la hora y fecha en el OLED. Ten en cuenta que usa la librería Adafruit_SSD1306, que puedes instalar vía Library Manager como de costumbre.
#include "WiFi.h"
#include "esp_sntp.h"
#include "Wire.h"
#include "DS3231.h"
#include "ezTime.h"
#include "Adafruit_SSD1306.h"
const char* TIMEZONE = "AEST-10AEDT,M10.1.0,M4.1.0/3";
const char* SSID = "SSID";
const char* PWD = "PASSWORD";
const int SLEEP = 10; // sec
DS3231 rtc;
Timezone loc;
Adafruit_SSD1306 oled(128, 64, &Wire, -1);
void oled_init() {
oled.begin(SSD1306_SWITCHCAPVCC, 0x3C);
oled.setTextSize(2);
oled.setTextColor(WHITE);
}
void syncTime() {
WiFi.begin(SSID, PWD);
while (WiFi.status() != WL_CONNECTED)
;
configTime(0, 0, "pool.ntp.org");
setRtcTime();
}
void setRtcTime() {
struct tm t;
getLocalTime(&t);
rtc.setDateTime(t.tm_year+1900, t.tm_mon+1, t.tm_mday, t.tm_hour, t.tm_min, t.tm_sec);
}
void displayTime() {
RTCDateTime dt = rtc.getDateTime();
UTC.setTime(dt.hour, dt.minute, dt.second, dt.day, dt.month, dt.year);
oled.clearDisplay();
oled.setCursor(10, 15);
oled.println(loc.dateTime("H:i:s"));
oled.setCursor(2, 45);
oled.println(loc.dateTime("d/m/Y"));
oled.display();
}
bool isReset() {
return esp_sleep_get_wakeup_cause() != ESP_SLEEP_WAKEUP_TIMER;
}
void setup() {
rtc.begin();
loc.setPosix(TIMEZONE);
oled_init();
if (isReset()) {
syncTime();
}
displayTime();
esp_sleep_enable_timer_wakeup(SLEEP * 1000000);
esp_deep_sleep_start();
}
void loop() {
}
Las únicas adiciones y cambios al código son la función oled_init(), que inicializa el OLED, y la función displayTime(), que muestra la hora y fecha en el OLED. Si subes el código a tu ESP32 deberías ver lo siguiente en el OLED:

¡Y eso es todo! Ahora deberías poder usar el RTC DS3231 junto con un ESP32.
Conclusiones
En este tutorial aprendiste cómo usar un módulo de reloj en tiempo real (RTC) DS3231 con un ESP32.
El ESP32 lite con un reloj en tiempo real es especialmente adecuado para proyectos alimentados por batería que necesitan mantener la hora precisa sin consumir mucha energía. Usos comunes son data loggers o relojes electrónicos. Para estos últimos, recomiendo pantallas e-Paper, ya que consumen casi nada de energía. Consulta nuestros tutoriales, Analog Clock on e-Paper Display y Digital Clock on e-Paper Display.
Si quieres aprender un poco más sobre relojes con diferentes tipos de pantalla y sincronización de tiempo, echa un vistazo al Digital Clock on e-Paper Display,
Si tienes alguna pregunta, no dudes en dejarla en la sección de comentarios.
¡Feliz bricolaje ; )

