Chisme 142 del Lince: reloj RTC, el reloj maestro del casco
Víctor Vílchez, el Lince de la Noche, entró en la cueva con una sonrisa de oreja a oreja y las alas a la espalda. Va a programar un reloj RTC.
—Hoy lo hago bien —anunció—. Alas y aerodeslizador, coordinados. Despego a las 17:40 en punto.
La Gata Montesa miró su reloj, miró el de la pared y miró el suyo de bolsillo. Marcaban tres horas distintas.
—Víctor.
—Dime.
—Tus alas creen que son las 17:37, el aerodeslizador cree que son las 17:43 y tu móvil, que son las 17:40. Despegas tú, pero ellos no se ponen de acuerdo.
—Eso es imposible. Todo está sincronizado.
—Marge entró anoche en el taller con una bolsa de pilas «nuevas».
El Lince se quedó en silencio. Luego, con mucha dignidad, se quitó el casco.
—Necesito un reloj maestro —dijo—. Uno que no dependa de nadie: ni del móvil ni de la corriente. Uno que cuente el tiempo sin parar y al que todas las piezas del traje puedan preguntar la hora.
La Gata sonrió.
—Creo que sé dónde hay uno. Y cabe en un casco.
Introducción: reloj RTC
En este chisme 142 vas a construir el reloj maestro del casco del Lince: un módulo de reloj de tiempo real (RTC) con el chip DS1302 conectado a la ESP32 Plus, que sabe qué hora y qué día es aunque la placa esté apagada.
En la historia, todas las piezas del traje (las alas, el aerodeslizador, la máscara del Chisme 141) deben coordinarse con un mismo reloj. Las alas y el aerodeslizador llegarán en otros chismes. Este es el primer paso: un reloj que cuenta el tiempo por su cuenta y que podemos ajustar, leer y comprobar.
Antes de montarlo, practica en el simulador del reloj maestro, que tiene modo demostración.
Qué necesitamos
- La ESP32 Plus de Acebott. Esta vez la programamos con el Arduino IDE (placa «ESP32 Dev Module»), sin librerías.
- Del kit avanzado de robótica: el módulo de reloj DS1302 (en la placa pone «MH real time clock modules-2»).
- Una pila CR2032 puesta en el módulo.
- Cinco cables Dupont.
Qué es un reloj de tiempo real
Un RTC (del inglés real time clock) es un pequeño chip que cuenta el tiempo y guarda segundos, minutos, hora, día, mes y año. La ESP32 también cuenta el tiempo, pero lo pierde cada vez que se apaga. El RTC lleva su propia pila, así que sigue contando aunque quites el USB. Puedes leer más en la Wikipedia: reloj en tiempo real.
¿Cómo cuenta? Con un cristal de cuarzo que vibra exactamente 32768 veces por segundo. Ese número es 2 elevado a 15, así que el chip lo divide entre 2 quince veces y obtiene un pulso por segundo. Es el mismo principio que el de un reloj de pulsera de cuarzo.
Conexión

| Módulo reloj | ESP32 Plus |
|---|---|
| VCC | 3V3 (3,3 V) |
| GND | G |
| CLK | pin 14 |
| DAT (o I/O) | pin 13 |
| RST (o CE) | pin 25 |
Con el USB desenchufado, y guiándote por los rótulos del módulo. Alimentamos el reloj a 3,3 V: el DS1302 funciona entre 2 y 5,5 V, y así sus señales son de 3,3 V, como las de la ESP32.
Cómo habla el chip: tres hilos
El DS1302 no es I2C. Usa un protocolo de tres hilos propio:
- RST (o CE): se pone en alto mientras dura una comunicación, para «activar» el chip.
- CLK: la ESP32 da pulsos de reloj. A cada pulso, viaja un bit.
- DAT (o I/O): los bits viajan por aquí, en los dos sentidos: la ESP32 envía la orden y el chip contesta por el mismo hilo.
Una comunicación son 16 pulsos: 8 para la orden (qué registro quiero leer o escribir) y 8 para el dato. Los registros del chip guardan los números en BCD (decimal codificado en binario): cada cifra decimal ocupa 4 bits. Por eso los segundos «59» se guardan como 0x59 y no como 89. Puedes leer más sobre el BCD.
En el registro de segundos, el bit 7 es especial: si vale 1, el reloj está parado. Pasa con una pila nueva o si se ha quedado sin ella.
El programa
Este programa no usa librerías: habla con el chip bit a bit, con las funciones leerRegistro y escribirRegistro. Así se ve cómo funciona el protocolo. Pégalo en el Arduino IDE, elige la placa ESP32 Dev Module, el puerto correcto y abre el monitor serie a 115200.
// Chisme 142 - Prueba del reloj DS1302 con la ESP32 Plus de Acebott
// Sin librerias: hablamos con el chip "a mano" (protocolo de 3 hilos).
// Placa en Arduino IDE: ESP32 Dev Module. Monitor serie a 115200.
const int PIN_CLK = 14; // CLK (reloj de la comunicacion)
const int PIN_DAT = 13; // DAT / I/O (datos, entra y sale por aqui)
const int PIN_RST = 25; // RST / CE (activa el chip)
// Pon true SOLO la primera vez: ajusta la hora del chip con la hora del ordenador
// en el momento de compilar. Despues ponlo en false y vuelve a subir el programa:
// el chip mantiene la hora gracias a su pila.
const bool PONER_HORA = true;
byte aBCD(int v) { return ((v / 10) << 4) | (v % 10); }
int deBCD(byte b) { return ((b >> 4) * 10) + (b & 0x0F); }
byte leerRegistro(byte reg) {
byte cmd = 0x81 | (reg << 1); // orden de LECTURA del registro
byte v = 0;
digitalWrite(PIN_RST, HIGH); delayMicroseconds(4);
pinMode(PIN_DAT, OUTPUT);
for (int i = 0; i < 8; i++) { // enviamos la orden, bit a bit (el bit 0 primero)
digitalWrite(PIN_DAT, (cmd >> i) & 1);
digitalWrite(PIN_CLK, HIGH); delayMicroseconds(2);
if (i == 7) pinMode(PIN_DAT, INPUT); // ahora el chip es quien habla
digitalWrite(PIN_CLK, LOW); delayMicroseconds(2);
}
for (int i = 0; i < 8; i++) { // recibimos el dato, bit a bit
if (digitalRead(PIN_DAT)) v |= (1 << i);
digitalWrite(PIN_CLK, HIGH); delayMicroseconds(2);
digitalWrite(PIN_CLK, LOW); delayMicroseconds(2);
}
digitalWrite(PIN_RST, LOW); delayMicroseconds(4);
return v;
}
void escribirRegistro(byte reg, byte valor) {
byte cmd = 0x80 | (reg << 1); // orden de ESCRITURA del registro
digitalWrite(PIN_RST, HIGH); delayMicroseconds(4);
pinMode(PIN_DAT, OUTPUT);
for (int i = 0; i < 8; i++) {
digitalWrite(PIN_DAT, (cmd >> i) & 1);
digitalWrite(PIN_CLK, HIGH); delayMicroseconds(2);
digitalWrite(PIN_CLK, LOW); delayMicroseconds(2);
}
for (int i = 0; i < 8; i++) {
digitalWrite(PIN_DAT, (valor >> i) & 1);
digitalWrite(PIN_CLK, HIGH); delayMicroseconds(2);
digitalWrite(PIN_CLK, LOW); delayMicroseconds(2);
}
digitalWrite(PIN_RST, LOW); delayMicroseconds(4);
}
void ponerHoraDelOrdenador() {
// __TIME__ es "HH:MM:SS" y __DATE__ es "Oct 22 2026" (el momento de compilar)
int h = (__TIME__[0] - '0') * 10 + (__TIME__[1] - '0');
int mi = (__TIME__[3] - '0') * 10 + (__TIME__[4] - '0');
int s = (__TIME__[6] - '0') * 10 + (__TIME__[7] - '0');
char mm[4] = { __DATE__[0], __DATE__[1], __DATE__[2], 0 };
const char* meses = "JanFebMarAprMayJunJulAugSepOctNovDec";
int mes = (strstr(meses, mm) - meses) / 3 + 1;
int dia = (__DATE__[4] == ' ' ? 0 : __DATE__[4] - '0') * 10 + (__DATE__[5] - '0');
int anio = (__DATE__[9] - '0') * 10 + (__DATE__[10] - '0'); // solo las dos ultimas cifras
escribirRegistro(7, 0x00); // quitamos la proteccion contra escritura
escribirRegistro(1, aBCD(mi));
escribirRegistro(2, aBCD(h)); // formato de 24 horas
escribirRegistro(3, aBCD(dia));
escribirRegistro(4, aBCD(mes));
escribirRegistro(5, 1); // dia de la semana (no lo usamos)
escribirRegistro(6, aBCD(anio));
escribirRegistro(0, aBCD(s)); // segundos al final: pone el reloj en marcha
}
void setup() {
Serial.begin(115200);
pinMode(PIN_CLK, OUTPUT); digitalWrite(PIN_CLK, LOW);
pinMode(PIN_RST, OUTPUT); digitalWrite(PIN_RST, LOW);
pinMode(PIN_DAT, INPUT);
delay(500);
if (PONER_HORA) {
ponerHoraDelOrdenador();
Serial.println("Hora ajustada con la del ordenador");
}
}
void loop() {
byte rs = leerRegistro(0); // segundos (el bit 7 = reloj parado)
byte seg = deBCD(rs & 0x7F);
byte mi = deBCD(leerRegistro(1));
byte h = deBCD(leerRegistro(2) & 0x3F);
byte dia = deBCD(leerRegistro(3));
byte mes = deBCD(leerRegistro(4));
byte an = deBCD(leerRegistro(6));
Serial.print("H:");
if (h < 10) Serial.print('0'); Serial.print(h); Serial.print(':');
if (mi < 10) Serial.print('0'); Serial.print(mi); Serial.print(':');
if (seg < 10) Serial.print('0'); Serial.print(seg);
Serial.print(" F:");
Serial.print(dia); Serial.print('/'); Serial.print(mes); Serial.print("/20"); Serial.print(an);
Serial.print(" segundos(raw)=0x"); Serial.print(rs, HEX);
if (rs & 0x80) Serial.print(" RELOJ PARADO");
Serial.println();
delay(1000);
}
Fíjate en tres cosas:
byte cmd = 0x81 | (reg << 1);construye la orden de lectura: el bit 0 a 1 significa «leer».deBCDpasa de BCD a número normal: las decenas están en los 4 bits de arriba y las unidades en los 4 de abajo.rs & 0x7Fquita el bit 7 antes de convertir los segundos, para que «reloj parado» no estropee la cuenta.
Cómo probarlo
- Sube el programa con
PONER_HORA = true. El chip se ajusta con la hora del ordenador en el momento de compilar. - Abre el monitor serie. Debe salir una línea por segundo, como
H:17:45:12 F:22/10/2026. - Cambia
PONER_HORAafalsey vuelve a subirlo. Así comprobamos que el chip mantiene la hora y no la vuelve a ajustar. - Desconecta el USB un minuto y vuelve a conectarlo. La hora debe seguir siendo la correcta.
Si algo falla, el programa imprime también el valor crudo de los segundos:
- RELOJ PARADO: el chip tiene el reloj detenido. Con
PONER_HORA = truese pone en marcha. - Todo a 255 o valores absurdos: casi seguro es un cable mal puesto o un pin cambiado.
- Todo a 0: revisa la alimentación y GND.
La deriva: ningún reloj es perfecto
El cristal de un módulo barato no vibra exactamente 32768 veces por segundo. Si el error es de 20 ppm (20 partes por millón), el reloj se desvía unos 1,7 segundos al día y unos 52 segundos al mes. Un cristal peor puede desviarse más, y además cambia con la temperatura. Este número es un ejemplo: la deriva de tu módulo tendrás que medirla tú.
Por eso un reloj que va bien un día puede ir unos minutos adelantado al cabo de unos meses. No es un fallo del programa: es la naturaleza de un cristal real. La solución es volver a ajustarlo de vez en cuando con una referencia mejor, que es exactamente lo que hará el reloj maestro del traje con las demás piezas.
Qué estamos midiendo realmente
El módulo da la hora con precisión de segundos, no de milisegundos. Sirve muy bien para registros de aula (qué hora era cuando se midió algo) y mal para medir fenómenos rápidos. Además, la hora que guarda es la que tú le pones: si la ajustas mal o con retraso (el ordenador compila unos segundos antes de que el programa llegue a la placa), el reloj arrastra ese error.
Esto conecta con una idea clave de la ciencia de datos: un dato sin su fecha y hora vale mucho menos. Es la base de la ciencia ciudadana: sensor → dato con marca de tiempo → conjunto de datos → análisis → conclusión. Con un reloj en la placa, cada medida puede llevar su momento, como en el registrador del Chisme 135 o en la estación del Chisme 125.
Para el aula
- Predice: ¿cuánto se desviará el reloj en una semana? Anótalo y compara con lo que mida.
- Mide la deriva: ajusta la hora con una referencia fiable (el móvil o una web de hora oficial), apunta el desvío cada día durante una semana y calcula cuántos segundos al día se desvía. ¿Coincide con los 20 ppm?
- Haz la gráfica: desvío acumulado frente a días. ¿Es una recta? ¿Qué pendiente tiene?
- Prueba sin pila: quita la pila, corta el USB y vuelve a conectar. ¿Qué hora marca? ¿Qué dice el bit 7?
- Convierte a mano: si el registro de segundos vale
0x47, ¿cuántos segundos son? ¿Y0x59? - Cambia una variable: ¿afecta el calor al reloj? Acerca el módulo con cuidado a una fuente de calor suave y mide.
- Debate: si tienes varias piezas con su propio reloj, ¿cómo las sincronizarías? ¿Cada cuánto?
Retos
- Reto 1: haz que funcione y mira la hora en el monitor serie.
- Reto 2: comprueba que mantiene la hora al desconectar el USB.
- Reto 3: añade un LED o un zumbador que avise cada minuto en punto.
- Reto 4: muestra la hora en la pantalla OLED que usaste en los chismes anteriores.
- Reto 5: haz una alarma: que suene a una hora que tú elijas.
- Reto 6: guarda las lecturas de otro sensor con su hora, usando el reloj, y dibuja la gráfica.
- Reto 7: mide la deriva durante dos semanas y calcula los ppm de tu módulo.
- Reto 8: convierte el proyecto en una pequeña investigación: ¿depende la deriva de la temperatura?
Qué hemos aprendido
Has conectado un reloj de tiempo real a la ESP32 Plus, has hablado con él con un protocolo de tres hilos y has leído sus registros en BCD. Has visto que un RTC mantiene la hora gracias a su pila, que el reloj se desvía poco a poco por culpa de su cristal y que, sin una hora de referencia común, las piezas de un sistema no pueden coordinarse.
La Gata Montesa miró la hora del casco, la comparó con su reloj de bolsillo y asintió.
—Diecisiete cuarenta. En punto.
—¿Y las alas? —preguntó el Lince.
—Todavía no existen. Y el aerodeslizador, tampoco.
—Eso —dijo el Lince— son detalles de los próximos chismes. Lo importante es que, cuando existan, sabrán qué hora es.

Etiqueta:acebott, AIDARAC, Arduino IDE, Computación y Robótica, deriva, ds1302, esp32, ies monterroso, montesteam, reloj rtc, sincronización, tiempo

