sábado, 30 de mayo de 2026

ESP32: Reloj con RTC interno, sincronización NTP y Deep Sleep


La idea de este post es aprender sobre tres temas interesantes y útiles del ESP32 que servirán mucho para proyectos actuales y futuros: el RTC, el modo Deep Sleep y la sincronización NTP.

Ya en un post anterior (servidor web con sensor DHT11) tocamos el tema de la sincronización con un servidor NTP, pero hoy vamos a utilizarlo de otra manera.

Qué nos proponemos:

  1. Entender el RTC interno: Olvidarnos de módulos externos y aprender a usar el reloj que ya viene dentro del ESP32.
  2. Sincronización NTP: Aprender a "preguntar" la hora a Internet para que nuestro reloj sea atómico.
  3. Eficiencia con Deep Sleep: Entender cómo poner a dormir el chip para que la batería no se agote en un suspiro.
  4. Modularización: Seguir practicando cómo separar el código en archivos para que sea limpio y profesional.
  5. Solucionar problemas reales que nos encontramos durante la marcha y nos hacen desesperar y querer tirar todo a la basura: Aprender qué es el Time Drift y cómo ganarle la batalla.

Para este proyecto vamos a usar componentes que probablemente ya tengas en tu cajón de proyectos:
  • ESP32: En mi caso uso un WEMOS D1 R32, pero cualquier ESP32 te sirve.
  • Pantalla OLED SSD1306: La clásica (primera vez que la uso, pero uno la ve en todos lados ahora) de 128x64 píxeles que se conecta por I2C.
  • Pulsador (Push Button): El que va a "despertar" a nuestro microcontrolador.
  • Resistencia de 10kΩ: Fundamental para que el botón funcione correctamente (luego te explico por qué).
  • Protoboard y cables.

Tabla de Conexiones

Si estás usando el WEMOS D1 R32, aquí tienes el mapa para no perderte. Si tenés otro modelo de ESP32, chequea bien los pines correspondientes. Es importante ubicar los pines SDA/SCL y algún pin marcado como RTC para el botón (push).

Componente Pin del ESP32 Notas
OLED VCC 3.3V o 5V Según tu modelo de pantalla
OLED GND GND Tierra
OLED SCL GPIO 22 Reloj I2C
OLED SDA GPIO 21 Datos I2C
Botón (Terminal 1) 3.3V Entrada de voltaje
Botón (Terminal 2) GPIO 27 Señal de entrada
Resistencia 10k GPIO 27 a GND Configuración Pull-down

Ojo con el botón: Es MUY importante conectar la resistencia entre el GPIO 27 y GND. Esto mantiene el pin en "bajo" (0V) mientras no tocamos el botón, evitando que el ruido eléctrico despierte al ESP32 por error.

1. ¿Qué es el RTC del ESP32?

El RTC (Real-Time Clock) es un módulo interno del chip capaz de mantener la fecha y la hora "con precisión" (más o menos..., veremos más adelante).

A diferencia de otros microcontroladores que nos obligan a comprar módulos externos (como el famoso DS3231), el ESP32 ya lo trae de serie. Como bien explican en Vasanza - RTC Interno, es vital para proyectos de data logging o riego automático. Eso sí, hay que tener en cuenta que si le quitamos la alimentación por completo, la hora se borra, por eso necesitamos "ayuda" externa para ponerlo en hora al principio.

2. Sincronización vía NTP

Para que nuestro reloj sea exacto, usamos el Network Time Protocol (NTP). Básicamente, es el lenguaje que usa el ESP32 para preguntarle a un servidor en Internet: "¿qué hora es exactamente?".

El ESP32 se conecta a servidores como pool.ntp.org mediante el puerto UDP 123. Es un proceso rápido, pero requiere que configuremos el GMT_OFFSET (para que sepa en qué país estamos) y el DAYLIGHT_OFFSET para el horario de verano. Si quieres profundizar en cómo sincronizarlo, te recomiendo este artículo sobre Sincronizar RTC.

3. Modos Sleep: ¿Cómo ahorrar batería?

Aquí es donde ocurre la magia. Si dejamos el ESP32 encendido a tope, consume unos 160-260 mA (variando un según modelos... en este caso estoy usando un WEMOS D1 R32 que no es el más ahorrador...), por eso usamos los modos de ahorro.

Según fuentes como Luis Llamas o Last Minute Engineers, el ESP32 tiene varios estados. Nosotros usaremos el Deep Sleep. En este modo, el CPU y el Wi-Fi se apagan por completo, pero —y aquí está el secreto— el módulo RTC se queda encendido. El consumo baja a unos increíbles 10 ~ 150 µA.

Para este proyecto, el ESP32 se despertará solo cuando pulsemos un botón (despertador externo GPIO).


El reto: El "Time Drift" (o por qué mi reloj se atrasa o se adelanta volviéndome loco)

Durante mis pruebas armando este proyecto me golpee la cabeza contra la pared durante un rato largo (por decir poco...). El oscilador interno del ESP32 no es perfecto. Sin un cristal de cuarzo externo de 32kHz, el reloj tiende a desviarse varios minutos en unas pocas horas.

¿La solución? En cada despertar, el código hace una sincronización NTP rapidísima. Así, aunque el reloj interno haya "derrapado" un poco mientras dormía, al mostrarte la hora siempre será la correcta. Admito que no era la idea original mientras armaba este proyecto, la idea era sincronizar una sola vez el RTC del ESP32 y luego (mientras se mantuviera conectado) leer siempre la información del mismo.

Estructura Modular

Como ya vimos en nuestro post sobre modularización, hemos separado el código en trocitos lógicos:

  • wifi_connect: Para entrar y salir de Internet sin dramas.
  • time_manager: El encargado de hablar con el NTP y ajustar el RTC.
  • display_utils: El artista que dibuja en la pantalla OLED.

Ventajas de la encapsulamiento! Si mañana queŕes usar una pantalla distinta, solo cambias el archivo del display y el resto del proyecto sigue funcionando perfectamente.

Consejos finales para tu montaje

  1. ¡Apaga el display! Muchos se olvidan de usar displayPowerOff() antes de dormir. Si el display se queda encendido, de nada sirve que el ESP32 esté en Deep Sleep; la batería adiós gracias.

  2. Hardware: Usa una resistencia de 10kΩ en modo Pull-down para el botón del GPIO 27. Si no, "despertares fantasma" que te van a enloquecer.

  3. Alimentación: Alimenta por el pin 5V/VIN para que el regulador de la placa haga su trabajo y proteja tu ESP32.

Como siempre, todo el código estará disponible en github: https://github.com/mcattani/reloj_esp32_rtc_ntp_dsleep

Espero que este post les haya interesado. Todos los comentarios son bienvenidos. Y si quieren, pueden invitarme un cafecito!

Invitame un café en cafecito.app

No hay comentarios.:

Publicar un comentario