El desarrollo de sistemas electrónicos interactivos y portátiles es un pilar fundamental en la electrónica moderna. Este proyecto se centra en la creación de un dado electrónico digital utilizando la plataforma Arduino UNO como cerebro, una compacta pantalla OLED de 128×32 píxeles con protocolo I2C para la visualización, y un simple botón pulsador como mecanismo de activación. Este proyecto no solo sirve como una herramienta lúdica, sino que también es una excelente introducción a conceptos clave como la generación de números pseudoaleatorios, el manejo de interrupciones y la comunicación de bus serial (I2C).
🔩Funcionamiento
El Cerebro del Sistema: Arduino UNO
El Arduino UNO utiliza el microcontrolador ATmega328P de Atmel (ahora Microchip). Este chip opera típicamente a 16 MHz y ofrece una arquitectura sencilla pero potente con 32 KB de memoria Flash para el código.
- Interrupciones: Para lograr que el dado responda instantáneamente al presionar el botón, se utiliza una Interrupción Externa. En el Arduino UNO, los pines digitales 2 y 3 están asignados para estas interrupciones. La interrupción permite que el microcontrolador suspenda temporalmente su tarea actual (el bucle
loop()) para atender la solicitud crítica del botón, garantizando que ninguna pulsación se pierda debido al tiempo de ejecución del código principal.
La Comunicación I2C y la Pantalla OLED
La pantalla OLED (Organic Light-Emitting Diode) es ideal por su alto contraste, bajo consumo de energía y tamaño compacto. La mayoría de los módulos de 128 x 32 píxeles utilizan el chip controlador SSD1306 y se comunican a través del bus I2C.
- Protocolo de Dos Hilos: I2C es un bus de comunicación serial que, de manera inteligente, requiere solo dos líneas para transferir datos entre el maestro (Arduino) y los esclavos (la pantalla):
- SDA (Serial Data Line): Línea de datos.
- SCL (Serial Clock Line): Línea de sincronización del reloj.
PINES del OLED 128×32(I2C)
| Pin OLED 128×32(I2C) | Protocolo | Notas Importantes |
|---|---|---|
| VCC | Alimentación | Uso de 5V. |
| GND | Tierra | Conexión de referencia. |
| SCL | I2C | Línea de Reloj Serial. |
| SDA | I2C | Línea de Datos Serial. |
🔨Componentes
| Componente | Cantidad | Especificación | Función |
|---|---|---|---|
| Placa Arduino | 1 | Arduino Uno, Nano, etc. | Control de componentes(cerebro) |
| Pantalla OLED | 1 | 128×32 (I2C) | Mostrar información |
| Botón | 1 | Push | Activar el dado |
| Resistencia | 1 | 10kΩ | Pull-down para el botón |
| Cables de conexión | n | Unir los componentes |
🔌Conexiones
Conexión OLED 128×32
| OLED 128×32(I2C) Pin | Arduino Pin |
|---|---|
| GND | GND |
| VCC | 5V |
| SCL | A5 |
| SDA | A4 |
Conexión del botón(Configuración Pull-Down):
| Arduino Pin | Arduino Pin |
|---|---|
| 5v | Pin 2 (con resistencia de 10kΩ a GND) |
0️⃣Código
El código se divide en secciones claras para la gestión de las librerías, la lógica del dado (incluyendo la simulación del “revolteo”) y la respuesta por interrupción.
Asegúrate de instalar las librerías necesarias desde el Gestor de Librerías del IDE de Arduino:
- Adafruit GFX Library (librería gráfica principal)
- Adafruit SSD1306 (driver específico para la pantalla)
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 | #include <Arduino.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> // ------------------------------------------------------------- // DEFINICIÓN DE PINES Y PARÁMETROS DE PANTALLA // ------------------------------------------------------------- // Definición de las dimensiones de la pantalla OLED #define PANTALLA_ANCHO 128 #define PANTALLA_ALTO 32 // Definición del pin donde está conectado el botón const int PIN_BOTON = 2; // Variable de estado para el botón volatile bool botonPulsado = false; // Objeto de la pantalla. Usamos 0x3C como dirección I2C común Adafruit_SSD1306 display(PANTALLA_ANCHO, PANTALLA_ALTO, &Wire, -1); // ------------------------------------------------------------- // FUNCIÓN DE GESTIÓN DE INTERRUPCIÓN // ------------------------------------------------------------- // Esta función se ejecuta inmediatamente cuando el botón es presionado void activarTirada() { botonPulsado = true; } // ------------------------------------------------------------- // FUNCIÓN PARA DIBUJAR LOS PUNTOS DEL DADO // ------------------------------------------------------------- void dibujarDado(int valor) { // Coordenadas centrales del dado (40, 16) y radio de los puntos int centroX = PANTALLA_ANCHO / 2; // 64 int centroY = PANTALLA_ALTO / 2; // 16 int radioPunto = 3; int margen = 12; // Margen para los puntos de las esquinas display.clearDisplay(); display.drawRect(centroX - 28, centroY - 16, 56, 32, SSD1306_WHITE); // Dibuja el contorno cuadrado del dado (opcional) // Función interna para dibujar un punto auto dibujarPunto = [&](int x, int y) { display.fillCircle(x, y, radioPunto, SSD1306_WHITE); }; // Posiciones predefinidas para los 7 puntos (Centro, Esquinas) int p[7][2] = { {centroX, centroY}, // Punto central (0) {centroX - margen - 10, centroY - margen}, // Superior Izquierda (1) {centroX + margen + 10, centroY - margen}, // Superior Derecha (2) {centroX - margen - 10, centroY + margen}, // Inferior Izquierda (3) {centroX + margen + 10, centroY + margen}, // Inferior Derecha (4) {centroX - margen - 10, centroY}, // Centro Izquierda (5) {centroX + margen + 10, centroY} // Centro Derecha (6) }; // Lógica para dibujar puntos según el valor del dado (1 a 6) switch (valor) { case 1: dibujarPunto(p[0][0], p[0][1]); // Centro break; case 2: dibujarPunto(p[1][0], p[1][1]); // Superior Izquierda dibujarPunto(p[4][0], p[4][1]); // Inferior Derecha break; case 3: dibujarPunto(p[0][0], p[0][1]); // Centro dibujarPunto(p[1][0], p[1][1]); // Superior Izquierda dibujarPunto(p[4][0], p[4][1]); // Inferior Derecha break; case 4: dibujarPunto(p[1][0], p[1][1]); // Superior Izquierda dibujarPunto(p[2][0], p[2][1]); // Superior Derecha dibujarPunto(p[3][0], p[3][1]); // Inferior Izquierda dibujarPunto(p[4][0], p[4][1]); // Inferior Derecha break; case 5: dibujarPunto(p[0][0], p[0][1]); // Centro dibujarPunto(p[1][0], p[1][1]); // Superior Izquierda dibujarPunto(p[2][0], p[2][1]); // Superior Derecha dibujarPunto(p[3][0], p[3][1]); // Inferior Izquierda dibujarPunto(p[4][0], p[4][1]); // Inferior Derecha break; case 6: dibujarPunto(p[1][0], p[1][1]); // Superior Izquierda dibujarPunto(p[2][0], p[2][1]); // Superior Derecha dibujarPunto(p[3][0], p[3][1]); // Inferior Izquierda dibujarPunto(p[4][0], p[4][1]); // Inferior Derecha dibujarPunto(p[5][0], p[5][1]); // Centro Izquierda dibujarPunto(p[6][0], p[6][1]); // Centro Derecha break; default: // En caso de un error o valor inicial no válido display.setTextSize(2); display.setTextColor(SSD1306_WHITE); display.setCursor(40, 10); display.print("ERROR"); break; } display.display(); } // ------------------------------------------------------------- // FUNCIÓN SETUP (CONFIGURACIÓN INICIAL) // ------------------------------------------------------------- void setup() { // 1. Inicialización de la Comunicación Serial (para depuración, opcional) Serial.begin(9600); Serial.println("Dado Electronico - Iniciando..."); // 2. Configuración del Pin del Botón pinMode(PIN_BOTON, INPUT); // 3. Configuración de Interrupción Externa // Asocia la función 'activarTirada' al Pin 2, detectando flancos de BAJO a ALTO (RISING) // Esto es para la configuración pull-down (al presionar pasa de 0V a 5V) attachInterrupt(digitalPinToInterrupt(PIN_BOTON), activarTirada, RISING); // 4. Inicialización de la Pantalla OLED if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Dirección 0x3C para la mayoría de los módulos Serial.println(F("Error: No se encontró la pantalla OLED.")); for (;;); // Detiene el programa } // 5. Sembrado del Generador de Aleatorios (Anti-patrón) // Lee el ruido eléctrico del pin A0 para una semilla impredecible. randomSeed(analogRead(A0)); Serial.print("Semilla Aleatoria: "); Serial.println(analogRead(A0)); // 6. Mensaje de Bienvenida display.clearDisplay(); display.setTextSize(1); display.setTextColor(SSD1306_WHITE); display.setCursor(10, 5); display.println("Dado Electronico"); display.setCursor(10, 20); display.println("Presione el Boton..."); display.display(); } // ------------------------------------------------------------- // FUNCIÓN LOOP (BUCLE PRINCIPAL) // ------------------------------------------------------------- void loop() { // La variable 'botonPulsado' es cambiada por la Interrupción if (botonPulsado) { // ** SIMULACIÓN DE LA TIRADA DEL DADO (EL 'REVOLTEO') ** for (int i = 0; i < 15; i++) { // 15 "revolcones" int valorTemp = random(1, 7); // Genera un número temporal entre 1 y 6 dibujarDado(valorTemp); // Dibuja el número temporal delay(50 + i * 5); // El retardo se incrementa para simular que el dado se detiene } // ** RESULTADO FINAL ** int resultado = random(1, 7); // Genera el resultado final (1 a 6) dibujarDado(resultado); Serial.print("Resultado: "); Serial.println(resultado); // Pequeño retardo para evitar rebotes o lecturas múltiples delay(500); // Reinicia el estado para esperar la próxima pulsación botonPulsado = false; } // No hay más código aquí para ahorrar ciclos del CPU, la interrupción es la que activa la lógica. } |
🖌️Diseños

🎬Videos
📑Conclusión
El desarrollo del Dado Electrónico Digital sobre la plataforma Arduino UNO demuestra de manera práctica y didáctica la convergencia exitosa de la electrónica digital, la programación de sistemas empotrados y la interacción humano-máquina.
Este proyecto, aparentemente simple, constituye un modelo robusto para la implementación de funciones esenciales en microcontroladores:
- Respuesta Instantánea con Interrupciones: La implementación del botón pulsador mediante una interrupción externa (en el Pin 2) optimizó la eficiencia del sistema. Esto garantizó una respuesta inmediata a la acción del usuario, evitando el uso ineficiente del método de polling y demostrando una programación reactiva.
- Comunicación Serial Eficiente (I2C): Se estableció una comunicación fluida y de bajo cableado con la pantalla OLED 128 x 32 a través del protocolo I2C (pines A4 y A5), que es estándar en proyectos compactos. Las librerías de Adafruit permitieron una abstracción gráfica sencilla para dibujar los puntos del dado en lugar de solo texto.
- Experiencia de Usuario: Se añadió un valor estético significativo a través del efecto de desaceleración en la animación de la tirada, proporcionando una experiencia visual convincente que simula el movimiento real de un dado.
En resumen, el Dado Electrónico es más que una herramienta lúdica; es una excelente puerta de entrada al mundo del hardware y software integrado, sirviendo como una base sólida para futuros proyectos que requieran entradas de usuario de alta respuesta y salidas visuales compactas y claras.

