Cómo hacer un reloj con Arduino y el módulo DS3231
Montas un reloj con Arduino usando millis(), lo dejas encendido una semana y descubres que va dos minutos adelantado. Y si se corta la luz, vuelve a empezar desde las 00:00.

Montas un reloj con Arduino usando millis(), lo dejas encendido una semana y descubres que va dos minutos adelantado. Y si se corta la luz, vuelve a empezar desde las 00:00. El problema no es tu código: el Arduino no está pensado para medir el tiempo real durante días, y para eso existe el módulo DS3231.
En esta guía vamos a construir un reloj con Arduino y DS3231 que muestra la hora y la fecha en una pantalla LCD de 16x2, mantiene la hora aunque lo desenchufes y se desvía alrededor de un minuto al año. Es el proyecto que usamos en el taller para enseñar I2C, y cuesta menos de 12 euros en piezas.
Por qué un reloj con Arduino necesita un RTC
El Arduino Uno usa un resonador cerámico de 16 MHz. Es suficiente para temporizar parpadeos o leer sensores, pero su precisión ronda el 0,5 %. Eso son hasta 7 minutos de error al día en el peor caso, aunque en la práctica suelen ser unos segundos o pocos minutos. Además, al reiniciarse pierde todo.
Un RTC, del inglés real time clock, es un chip dedicado solo a contar el tiempo. Tiene su propio cristal y una pila de botón que lo mantiene funcionando cuando el Arduino está apagado. El Arduino solo le pregunta la hora cuando la necesita.
DS3231 frente a DS1307
En las tiendas verás dos módulos muy comunes. El DS1307 es más barato, pero usa un cristal externo sin compensación y puede desviarse varios segundos al día según la temperatura. El DS3231 lleva un oscilador compensado por temperatura integrado y su precisión es de unas 2 partes por millón entre 0 y 40 °C. Eso equivale aproximadamente a un minuto al año. Por uno o dos euros de diferencia, el DS3231 es la elección clara.
Materiales y conexiones
| Componente | Precio aproximado | Nota |
|---|---|---|
| Arduino Uno o Nano | 4 a 8 euros | Un clon funciona igual |
| Módulo DS3231 (tipo ZS-042) | 2 a 4 euros | Incluye zócalo para pila |
| Pila CR2032 o LIR2032 | 1 euro | Lee la sección de la pila |
| LCD 16x2 con adaptador I2C | 3 a 5 euros | Ahorra cables |
| Protoboard y cables dupont | 2 euros | Reutilizables |
Los dos módulos usan el bus I2C, así que comparten solo cuatro líneas. En un Arduino Uno:
- VCC de ambos módulos a 5V.
- GND de ambos a GND.
- SDA de ambos a A4.
- SCL de ambos a A5.
En el Nano los pines son los mismos. Si nunca has montado algo así, revisa antes nuestra guía sobre cómo usar una protoboard sin errores, porque un cable en la fila equivocada es el fallo más habitual en este proyecto.
El DS3231 responde en la dirección I2C 0x68. Muchos módulos ZS-042 también llevan una memoria EEPROM en 0x57. La pantalla con adaptador suele estar en 0x27 o en 0x3F. Si la pantalla se enciende pero no muestra nada, carga el ejemplo de escáner I2C del IDE y confirma la dirección real.
Programar el reloj con Arduino paso a paso
Instala dos bibliotecas desde el gestor del IDE de Arduino: RTClib, de Adafruit, y LiquidCrystal I2C. Después sigue este orden.
- Inicializa el RTC. En setup(), llama a rtc.begin(). Si devuelve falso, el Arduino no ve el módulo: revisa SDA, SCL y la alimentación.
- Ajusta la hora una sola vez. La forma más cómoda es rtc.adjust(DateTime(F(__DATE__), F(__TIME__))), que copia la fecha y hora en que se compiló el programa.
- Inicializa la pantalla. Crea el objeto LCD con su dirección, 16 columnas y 2 filas, y enciende la retroiluminación.
- Lee la hora en loop(). rtc.now() devuelve un objeto con hour(), minute(), second(), day(), month() y year().
- Formatea con ceros. Si el minuto es menor que 10, imprime un 0 delante. Si no, verás 14:5 en lugar de 14:05.
- Actualiza una vez por segundo. Guarda el último segundo mostrado y solo reescribe la pantalla cuando cambie. Así evitas parpadeos.
El DS3231 incluye además un sensor de temperatura que usa para compensar el cristal. Con rtc.getTemperature() puedes mostrarla en la segunda línea. Tiene una resolución de 0,25 °C, pero mide la temperatura del chip, no del ambiente, así que tómala como orientativa.
El consejo de los tutoriales que conviene ignorar
Casi todos los ejemplos que circulan dejan la línea rtc.adjust(...) dentro de setup() y te dicen que así la hora siempre queda bien. Funciona la primera vez, y por eso parece correcto. Pero es justo lo contrario de lo que quieres.
Cada vez que el Arduino se reinicia, por un corte de luz o al abrir el monitor serie, vuelve a ejecutar setup() y pone el reloj en la hora en que compilaste el programa. Si lo compilaste el martes a las 10:12, el viernes tu reloj volverá a marcar martes a las 10:12 tras cualquier reinicio. Toda la ventaja de tener un RTC con pila desaparece.
Hay dos formas correctas de hacerlo:
- Envuelve el ajuste en una condición: solo si rtc.lostPower() devuelve verdadero, es decir, si el chip perdió la alimentación y la pila.
- O sube el programa una vez con el ajuste, comenta esa línea y vuelve a subirlo.
Nosotros usamos la primera opción en todos los relojes del taller.
Cuidado con la pila del módulo ZS-042
Este es un detalle que casi nadie menciona. Muchos módulos ZS-042 incluyen un pequeño circuito de carga, formado por una resistencia de 200 ohmios y un diodo, pensado para pilas recargables LIR2032. Si pones una CR2032 normal, que no es recargable, el módulo intentará cargarla con 5V. Con el tiempo la pila puede hincharse.
Tienes tres opciones:
- Usar una pila LIR2032 recargable.
- Alimentar el módulo a 3,3V, con lo que la carga es mínima.
- Desoldar o cortar la resistencia o el diodo del circuito de carga y usar una CR2032. Es lo que hacemos nosotros: un toque de soldador y listo.
Con una CR2032 nueva y el circuito de carga desactivado, el DS3231 mantiene la hora varios años sin alimentación principal.
Ideas para ampliar el proyecto
Una vez que el reloj funciona, el DS3231 abre muchas posibilidades. Tiene dos alarmas programables y una salida SQW que puede despertar al Arduino del modo de bajo consumo. Con eso puedes hacer un registrador de datos que guarde lecturas cada 15 minutos en una tarjeta microSD, o un temporizador para un sistema de riego como el de nuestro proyecto de riego automático para macetas con Arduino. También sirve para añadir marcas de hora fiables a cualquier montaje con sensores sin depender de la wifi.
Preguntas frecuentes
¿Qué precisión tiene el módulo DS3231?
Entre 0 y 40 °C tiene una precisión de unas 2 partes por millón, lo que significa aproximadamente un minuto de desvío al año. Fuera de ese rango de temperatura la precisión baja un poco, pero sigue siendo mucho mejor que la del DS1307 o la del propio Arduino.
¿Por qué mi reloj con Arduino vuelve a una hora antigua al reiniciarse?
Casi siempre es porque la línea rtc.adjust() sigue activa en setup(). Cada reinicio vuelve a poner la hora de compilación. Hazla condicional con rtc.lostPower() o coméntala después de ajustar la hora la primera vez.
¿Se puede usar el DS3231 con ESP32 o ESP8266?
Sí. Funciona por I2C a 3,3V sin problemas y la biblioteca RTClib es compatible. En el ESP32 los pines I2C por defecto suelen ser el GPIO 21 para SDA y el GPIO 22 para SCL.
More in Proyectos
Proyectos
Cómo hacer una cerradura RFID con Arduino paso a paso
Pierdes las llaves del taller dos veces al mes, o quieres que tu hermano pequeño deje de abrir el cajón de las herramientas.
Proyectos
Estación meteorológica casera con ESP32 y sensor BME280
El primer invierno que montamos una estación meteorológica casera en el balcón del hacklab, marcaba 3 grados más que el...
Proyectos
Riego automático para macetas con Arduino paso a paso
El verano pasado me fui diez días de vacaciones y volví a encontrar la albahaca seca y el tomate cherry doblado sobre la...