En esta página te enseñaremos a realizar tu propio reloj digital con Arduino usando displays de 7 segmentos como dispositivo de visualización. Hemos decidido incluir en este proyecto un segundero para hacerlo más vistoso pero también podrías omitir esta parte y realizar una versión más compacta.
Nuestro proyecto utilizará 6 displays de cátodo común para visualizar la hora (horas, minutos y segundos) o la fecha (mes, día, año). La fecha y la hora podrá ajustarse utilizando dos botones tipo push. Para llevar el conteo del tiempo incluso con la alimentación desconectada usaremos un módulo RTC DS3231.
Este es un proyecto de nivel intermedio en el que podremos aplicar temas como comunicación I2C, interrupciones, uso de librerías, manejo de fechas y horas, botones, etc. Además requerirá buen manejo del protoboard debido al número de conexiones que deben realizarse entre los displays.
Si deseas algo un poco más sencillo de realizar desde el punto de vista del armado quizá quieras intentar el reloj digital con Arduino y pantalla LCD 20×4 con dígitos grandes.
¿Cómo hacer un reloj digital con Arduino y displays de 7 segmentos?
Para realizar el reloj digital con Arduino y displays de 7 segmentos deberás tener la capacidad de manejar con soltura el protoboard, pues se trata de un proyecto algo demandante en cuanto a su armado.
También puedes considerar armarlo en una placa fenólica perforada para volverlo un poco más robusto si piensas dejarlo armado de forma permanente.
El procedimiento para realizar un reloj digital con Arduino es el siguiente:
- Adquirir los materiales necesarios
- Armar el circuito electrónico que se muestra en el diagrama a continuación, ya sea en el protoboard o en tarjeta perforada.
- Descargar el código que se muestra en esta página y cargarlo en la tarjeta Arduino Nano
- Probar el funcionamiento del circuito
- Poner a tiempo el reloj
Materiales
Para armar este proyecto se requieren los siguientes materiales que puedes encontrar en nuestra tienda de electrónica en línea:
- Arduino Nano Every
- Módulo reloj en tiempo real DS3231
- 2 x Protoboard de 830 puntos
- 6 x Displays de 7 segmentos cátodo común
- 6 x Transistores 2N2222
- 6 x Resistencias de 1K 1/4 W
- 7 x Resistencias de 120 ohms 1/4 W
- 2 x Pushbuttons
- Alambre para protoboard
Diagrama esquemático de reloj digital con Arduino
Como se puede observar en el diagrama esquemático el mayor trabajo está en cablear en paralelo todos los segmentos de los displays, esta es una tarea que requiere bastantes puentes en el protoboard. El resto del circuito es relativamente sencillo, pues estamos haciendo uso de módulos que simplifican el armado.
Hay que prestar atención a la polaridad y tipo de display (deben ser cátodo común), en los transistores también será necesario prestar atención a la polaridad y disposición de las terminales.

Puedes descargar el diagrama esquemático aquí en formato PDF para visualizarlo de forma más cómoda en tu PC.
Uso de pines
Esta es una lista de los pines usados en este proyecto y la función que desempeñan en el programa.
| Pin | Función |
| 2 | Interrupción de RTC DS3231 |
| 3 | Botón o pulsador SET |
| 4 | Botón o pulsador UP |
| 5 | Segmento A |
| 6 | Segmento B |
| 7 | Segmento C |
| 8 | Segmento D |
| 9 | Segmento E |
| 10 | Segmento F |
| 11 | Segmento G |
| 12 | Habilitación de cátodo común display 1 |
| 13 | Habilitación de cátodo común display 2 |
| A0 | Habilitación de cátodo común display 3 |
| A1 | Habilitación de cátodo común display 4 |
| A2 | Habilitación de cátodo común display 5 |
| A3 | Habilitación de cátodo común display 6 |
| A4 | Señal SDA RTC DS3231 |
| A5 | Señal SCL RTC DS3231 |
Código para reloj digital con displays de 7 segmentos
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 | /** --> PROYECTOS CON ARDUINO: RELOJ DIGITAL <-- --> MATERIAL DE APOYO <-- Potenciado por: Geek Factory - "Dale vuelo a tus proyectos" www.geekfactory.mx CONSULTA EL ARCHIVO LICENCIA.TXT PARA CONOCER MÁS SOBRE LOS DERECHOS DE DISTRIBUCIÓN DE ESTE MATERIAL O LA SIGUIENTE URL: HTTPS://WWW.GEEKFACTORY.MX/LICENCIA-CONTENIDO. PUBLICADO BAJO LICENCIA ATTRIBUTION-NONCOMMERCIAL-SHAREALIKE 4.0 INTERNATIONAL (CC BY-NC-SA 4.0). PROYECTO: Reloj digital con displays de 7 segmentos. Este código implementa un reloj con displays de 7 segmentos multiplexados. Para la base de tiempo se utiliza un módulo RTC DS3231. La fecha y hora pueden ajustarse con solo dos botones. */ /** Required libraries for this project */ #include "GFDisplay7S.h" #include "GFButton.h" #include "GFRTC.h" #include "TimerOne.h" enum clock_modes { E_CLOCK_MODE_RUN = 0, E_CLOCK_MODE_ADJ, }; enum clock_adjust { E_CLOCK_ADJUST_HOUR = 0, E_CLOCK_ADJUST_MINUTE, E_CLOCK_ADJUST_SECOND, E_CLOCK_ADJUST_DAY, E_CLOCK_ADJUST_MONTH, E_CLOCK_ADJUST_YEAR, }; /** Buttons to set time and date */ GFButton setButton(3); GFButton upButton(4); /** Multiplexed 7 segment display object configured for 6 digits */ GFDisplay7S display((const uint8_t[]){ 5, 6, 7, 8, 9, 10, 11, 0xFF }, (const uint8_t[]){ 12, 13, A0, A1, A2, A3 }, 6); /** This enumerated variable defines if the clock is running or being adjusted */ enum clock_modes mode = E_CLOCK_MODE_RUN; /** This variable defines what component of the time and date is being adjusted */ uint8_t adjvar = E_CLOCK_ADJUST_HOUR; /** Structure used to perform operations on time and date */ struct timelib_tm datetime; /** Flag set when the RTC interrupt occurs */ volatile bool rtcflag = false; /** Setup function: runs once on power on or reset */ void setup() { // initialize multiplexed 7 segments displays display.begin(); // setup timer to refresh the displays at arround 55 Hz Timer1.initialize(3000); Timer1.attachInterrupt(interrupt_display_refresh); // prepare the RTC library, display E1 error if cannot communicate with RTC chip GFRTC.begin(true); if (!GFRTC.isPresent()) { display.print("E1"); for (;;) ; } // enable sqrwave output with 1 Hz frequency from RTC module GFRTC.setIntSqwMode(E_SQRWAVE_1_HZ); // attach interrupt, this calls isrhandler function on every falling edge pinMode(2, INPUT); attachInterrupt(digitalPinToInterrupt(2), interrupt_rtc, FALLING); } /** Loop function: runs continuously as long as the board receives power */ void loop() { bool datetimedisp = false; switch (mode) { case E_CLOCK_MODE_RUN: // if we hold the set button for more than 5 seconds we enter clock adjustment mode if (setButton.wasLongPress()) { // clear press event setButton.wasPressed(); // enter adjust mode adjusting the hours variable adjvar = 0; clock_adj_blink(adjvar); // switch to ADJ mode mode = E_CLOCK_MODE_ADJ; break; } // check if we should display time or date datetimedisp = upButton.isPressed(); // check if we received interrupt signal to update the time or date on the displays if (rtcflag) { // clear flag and display time rtcflag = false; // read date and time from RTC chip if (GFRTC.read(datetime)) { // check upButton status and display time or date accordingly (datetimedisp) ? clock_show_date() : clock_show_time(); } } break; case E_CLOCK_MODE_ADJ: // adjust button long press exits clock adjustment mode if (setButton.wasLongPress()) { // save date to RTC chip GFRTC.write(datetime); // stop any blinking display.noBlink(); // switch to RUN mode mode = E_CLOCK_MODE_RUN; break; } // short press changes the variable to adjust if (setButton.wasPressed()) { if (++adjvar >= 6) adjvar = 0; // show time or date according to the selected variable (adjvar < 3) ? clock_show_time() : clock_show_date(); // blink digits of the variable we're adjusting clock_adj_blink(adjvar); } // up button changes the selected variable of datetime struct if (upButton.wasPressed()) { clock_increase_var(adjvar); (adjvar < 3) ? clock_show_time() : clock_show_date(); } break; } } /** Blinks the appropiate digits when we're in adjustment mode */ void clock_adj_blink(uint8_t var) { // disable blinking display.noBlink(); // blink the appropiate digits switch (var) { case E_CLOCK_ADJUST_HOUR: case E_CLOCK_ADJUST_DAY: display.blinkDigit(0); display.blinkDigit(1); break; case E_CLOCK_ADJUST_MINUTE: case E_CLOCK_ADJUST_MONTH: display.blinkDigit(2); display.blinkDigit(3); break; case E_CLOCK_ADJUST_SECOND: case E_CLOCK_ADJUST_YEAR: display.blinkDigit(4); display.blinkDigit(5); break; } } /** Increases the selected time or date variable and checks the limits for hour, minute, seconds,etc. */ void clock_increase_var(uint8_t var) { switch (var) { case E_CLOCK_ADJUST_HOUR: datetime.tm_hour = (datetime.tm_hour + 1 < 24) ? datetime.tm_hour + 1 : 0; break; case E_CLOCK_ADJUST_MINUTE: datetime.tm_min = (datetime.tm_min + 1 < 60) ? datetime.tm_min + 1 : 0; break; case E_CLOCK_ADJUST_SECOND: datetime.tm_sec = (datetime.tm_sec + 1 < 60) ? datetime.tm_sec + 1 : 0; break; case E_CLOCK_ADJUST_DAY: datetime.tm_mday = (datetime.tm_mday + 1 <= 31) ? datetime.tm_mday + 1 : 1; break; case E_CLOCK_ADJUST_MONTH: datetime.tm_mon = (datetime.tm_mon + 1 <= 12) ? datetime.tm_mon + 1 : 1; break; case E_CLOCK_ADJUST_YEAR: datetime.tm_year = (datetime.tm_year + 1 < 80) ? datetime.tm_year + 1 : 30; break; } } /** Show the time on the displays */ void clock_show_time() { display.home(); clock_print_2_digits(datetime.tm_hour); clock_print_2_digits(datetime.tm_min); clock_print_2_digits(datetime.tm_sec); } /** Show the date on the displays */ void clock_show_date() { display.home(); clock_print_2_digits(datetime.tm_mday); clock_print_2_digits(datetime.tm_mon); clock_print_2_digits(timelib_tm2y2k(datetime.tm_year)); } /** Helper function to print always two digits */ void clock_print_2_digits(uint8_t number) { if (number < 10) display.write('0'); display.print(number); } /** Timer interrupt takes care of updating the multiplexed 7 segment displays */ void interrupt_display_refresh() { display.process(); } /** RTC interrupt makes the microcontroller to update the time and date shown on the displays */ void interrupt_rtc() { rtcflag = true; } |
Librerías utilizadas en el programa
Para poder compilar el programa deberás tener instaladas las siguientes librerías en Arduino IDE:
Se pueden obtener directamente desde el gestor de librerías o bien descargándolas e instalándolas manualmente.
Funcionamiento y puesta a tiempo
Una vez que tengamos armado el circuito podemos conectarlo al puerto USB de la computadora y veremos que el conteo de tiempo comienza en los displays.
Para poner a tiempo el reloj digital con Arduino:
- Mantenemos pulsado el botón SET (pin 3) hasta que comiencen a parpadear los dos primeros dígitos (hora).
- Con el botón UP (pin 4) aumentamos la hora hasta llegar al número deseado.
- Oprimimos nuevamente el botón SET para cambiar al ajuste de minutos.
- Con el botón UP aumentamos los minutos hasta llegar al número deseado.
- Repetimos los pasos anteriores para ajustar segundos, mes, día y año.
- Podemos usar el botón SET para cambiar el componente de la fecha que estamos ajustando y el botón UP para modificar (incrementar) el valor.
- Para salir del modo de ajuste mantenemos pulsado el botón SET por 5 segundos. El reloj comienza a contar el tiempo nuevamente con la nueva hora y fecha que programamos.
Durante el funcionamiento normal del reloj podemos mantener pulsado el botón UP para mostrar la fecha en formato mes / día / año.
Lecturas recomendadas y enlaces externos
- DS3231 con Arduino
- Botón o push button con Arduino
- Repositorio del proyecto de reloj digital con displays y Arduino
Conclusión
- En este tutorial aprendimos cómo podemos usar la técnica de multiplexado de displays y presentamos una librería de Arduino que hemos realizado con este propósito.
- Repasamos la lectura y puesta a tiempo del RTC DS3231, también pudimos observar como utilizar el pin de SQW para generar una señal cuadrada que nos sirve para actualizar la hora en los displays.
- Utilizamos librerías de Arduino que ya teníamos desarrrolladas y vimos su aplicación en un proyecto real.
- El código nos sirve como ejemplo para manejar interrupciones externas y con el uso de un timer.








![Resistencia 1/4 de watt 5% tolerancia [1 Ohm a 10 MOhm]](https://www.geekfactory.mx/wp-content/uploads/resistencia-1-4-de-watt-5-tolerancia-300x300.jpg.webp)



Falta incluir la librería TimeLib.
Está en https://github.com/geekfactory/TimeLib
tienes un montaje con un arduino R3 estandar??
Hola, las conexiones son las mismas, es el mismo micro a final de cuentas.
Saludos!
Hola me puedes decir que transistores tengo que poner porque quiero adaptar displays de ánodo común , tienes algún esquema.
Hola, podrías probar con el 2N2907 que es el complementario al 2N2222A. Por el momento no contamos con el diagrama para transistores PNP y displays de ánodo común.
Hola la imagen, la tabla de los pines y el diagrama no coinciden en los pines de Á0, A1, Á2, Á3, 12 Y 13