#include <Arduino.h>
// Pines para el display de 7 segmentos (ÁNODO COMÚN)
const int segmentPins[] = {2, 3, 4, 5, 6, 7, 8}; // D2-D8 en Wokwi
#define BUTTON_PIN D9
// Patrones para ÁNODO COMÚN - 1=apagado, 0=encendido
const byte digitPatterns[10] = {
0b11000000, // 0 - ABCDEF (encendidos)
0b11111001, // 1 - BC (encendidos)
0b10100100, // 2 - ABDEG (encendidos)
0b10110000, // 3 - ABCDEG (encendidos)
0b10011001, // 4 - BCFG (encendidos)
0b10010010, // 5 - ACDFG (encendidos)
0b10000010, // 6 - ACDEFG (encendidos)
0b11111000, // 7 - ABC (encendidos)
0b10000000, // 8 - ABCDEFG (encendidos)
0b10010000 // 9 - ABCDFG (encendidos)
};
// Variables globales
char nombre[50] = "";
int numeros[50];
int totalNumeros = 0;
unsigned long semilla = 0;
bool lastButtonState = HIGH;
bool secuenciaActiva = false; // Controla si hay una secuencia de nombre en curso
void setup() {
// Configurar todos los pines del display como salida
for (int i = 0; i < 7; i++) {
pinMode(segmentPins[i], OUTPUT);
digitalWrite(segmentPins[i], HIGH); // Inicialmente apagados (ánodo común)
}
// Configurar botón
pinMode(BUTTON_PIN, INPUT_PULLUP);
// Inicializar comunicación serial
Serial.begin(115200);
// Generar semilla única para el dado
generarSemillaUnica();
// Apagar display al inicio
apagarDisplay();
}
void loop() {
// --- VERIFICAR BOTÓN (MÁXIMA PRIORIDAD) ---
bool currentButtonState = digitalRead(BUTTON_PIN);
if (lastButtonState == HIGH && currentButtonState == LOW) {
delay(50); // Debounce
// DETENER INSTANTÁNEAMENTE cualquier secuencia de nombre
if (secuenciaActiva) {
secuenciaActiva = false;
totalNumeros = 0; // Borrar completamente la secuencia
Serial.println("Secuencia interrumpida por botón");
}
// Generar y mostrar número aleatorio
int randomNumber = generarNumeroAleatorio(1, 6);
Serial.print("Número aleatorio generado: ");
Serial.println(randomNumber);
mostrarNumero(randomNumber);
// Esperar a que se suelte el botón y mantener el número
while (digitalRead(BUTTON_PIN) == LOW) {
delay(10); // Esperar manteniendo el número
}
// Mantener el número 2 segundos después de soltar
delay(2000);
apagarDisplay();
Serial.println("Listo para nuevo comando");
}
lastButtonState = currentButtonState;
// --- MODO SERIAL (NOMBRE) - SOLO SI NO HAY SECUENCIA ACTIVA ---
if (!secuenciaActiva && Serial.available() > 0) {
String input = Serial.readString();
input.trim();
if (input.length() > 0) {
input.toCharArray(nombre, sizeof(nombre));
Serial.print("Nombre ingresado: ");
Serial.println(nombre);
convertirNombreANumeros();
secuenciaActiva = true; // Activar la secuencia
}
}
// --- EJECUTAR SECUENCIA DEL NOMBRE (SI ESTÁ ACTIVA Y NO SE PRESIONA BOTÓN) ---
if (secuenciaActiva && totalNumeros > 0) {
for (int i = 0; i < totalNumeros; i++) {
// Verificar constantemente si se presiona el botón
if (digitalRead(BUTTON_PIN) == LOW) {
secuenciaActiva = false;
totalNumeros = 0;
Serial.println("Secuencia interrumpida por botón");
break;
}
// Verificar si hay nuevo comando serial
if (Serial.available() > 0) {
secuenciaActiva = false;
totalNumeros = 0;
break;
}
Serial.print("Mostrando: ");
Serial.println(numeros[i]);
mostrarNumero(numeros[i]);
// Delay con verificación constante de botón
for (int j = 0; j < 100; j++) { // 1000ms dividido en 10ms chunks
if (digitalRead(BUTTON_PIN) == LOW) {
secuenciaActiva = false;
totalNumeros = 0;
Serial.println("Secuencia interrumpida por botón");
break;
}
delay(10);
}
if (!secuenciaActiva) break; // Salir si fue interrumpido
}
// Pausa entre repeticiones (con verificación de interrupción)
if (secuenciaActiva) {
apagarDisplay();
for (int j = 0; j < 50; j++) { // 500ms dividido en 10ms chunks
if (digitalRead(BUTTON_PIN) == LOW || Serial.available() > 0) {
secuenciaActiva = false;
totalNumeros = 0;
break;
}
delay(10);
}
}
}
}
// ========== FUNCIONES DEL DADO ALEATORIO ==========
void generarSemillaUnica() {
semilla = 0;
for(int i = 0; i < 32; i++) {
semilla = (semilla << 1) | (analogRead(A0) & 0x01);
semilla ^= analogRead(A1);
delay(1);
}
semilla ^= micros();
if(semilla == 0) semilla = 1;
}
int generarNumeroAleatorio(int minVal, int maxVal) {
semilla = (semilla * 1103515245 + 12345) & 0x7FFFFFFF;
int ruido = analogRead(A0) ^ analogRead(A1) ^ micros();
semilla ^= ruido;
int rango = maxVal - minVal + 1;
int resultado = minVal + (semilla % rango);
if(resultado < minVal) resultado = minVal;
if(resultado > maxVal) resultado = maxVal;
return resultado;
}
// ========== FUNCIONES DEL NOMBRE ==========
void convertirNombreANumeros() {
totalNumeros = 0;
Serial.println("Conversión:");
for (int i = 0; nombre[i] != '\0'; i++) {
char letra = toupper(nombre[i]);
int posicion = 0;
if (letra >= 'A' && letra <= 'Z') {
posicion = letra - 'A' + 1;
Serial.print(" ");
Serial.print(letra);
Serial.print(" -> ");
Serial.print(posicion);
if (posicion >= 10) {
int decenas = posicion / 10;
int unidades = posicion % 10;
numeros[totalNumeros++] = decenas;
numeros[totalNumeros++] = unidades;
Serial.print(" -> ");
Serial.print(decenas);
Serial.print(", ");
Serial.println(unidades);
} else {
numeros[totalNumeros++] = posicion;
Serial.println();
}
}
}
Serial.print("Secuencia: ");
for (int i = 0; i < totalNumeros; i++) {
Serial.print(numeros[i]);
if (i < totalNumeros - 1) Serial.print(" - ");
}
Serial.println();
Serial.println("Iniciando visualización...");
}
// ========== FUNCIONES COMUNES DEL DISPLAY ==========
void apagarDisplay() {
for (int i = 0; i < 7; i++) {
digitalWrite(segmentPins[i], HIGH);
}
}
void mostrarNumero(int numero) {
if (numero < 0 || numero > 9) {
apagarDisplay();
return;
}
// Para números del dado (1-6), usar patrones específicos
if (numero >= 1 && numero <= 6) {
apagarDisplay();
switch(numero) {
case 1:
digitalWrite(segmentPins[1], LOW); // B
digitalWrite(segmentPins[2], LOW); // C
break;
case 2:
digitalWrite(segmentPins[0], LOW); // A
digitalWrite(segmentPins[1], LOW); // B
digitalWrite(segmentPins[6], LOW); // G
digitalWrite(segmentPins[4], LOW); // E
digitalWrite(segmentPins[3], LOW); // D
break;
case 3:
digitalWrite(segmentPins[0], LOW); // A
digitalWrite(segmentPins[1], LOW); // B
digitalWrite(segmentPins[6], LOW); // G
digitalWrite(segmentPins[2], LOW); // C
digitalWrite(segmentPins[3], LOW); // D
break;
case 4:
digitalWrite(segmentPins[1], LOW); // B
digitalWrite(segmentPins[2], LOW); // C
digitalWrite(segmentPins[6], LOW); // G
digitalWrite(segmentPins[5], LOW); // F
break;
case 5:
digitalWrite(segmentPins[0], LOW); // A
digitalWrite(segmentPins[5], LOW); // F
digitalWrite(segmentPins[6], LOW); // G
digitalWrite(segmentPins[2], LOW); // C
digitalWrite(segmentPins[3], LOW); // D
break;
case 6:
digitalWrite(segmentPins[0], LOW); // A
digitalWrite(segmentPins[5], LOW); // F
digitalWrite(segmentPins[6], LOW); // G
digitalWrite(segmentPins[2], LOW); // C
digitalWrite(segmentPins[3], LOW); // D
digitalWrite(segmentPins[4], LOW); // E
break;
}
} else {
// Para números del nombre (0-9), usar tabla de patrones
byte patron = digitPatterns[numero];
for (int i = 0; i < 7; i++) {
if (patron & (1 << i)) {
digitalWrite(segmentPins[i], HIGH);
} else {
digitalWrite(segmentPins[i], LOW);
}
}
}
}