#define NUM_LEDS 8
#define NUM_BOTONES 3
// *** PINES ACTUALIZADOS PARA WOKWI ***
const int botones[NUM_BOTONES] = {13, 12, 14}; // Botones (Bit 0, 1, 2)
const int leds[NUM_LEDS] = {25, 26, 27, 32, 33, 15, 4, 2}; // LEDs 1-8 (pines válidos en Wokwi)
// Variables
int modoActual = 0;
unsigned long milisegundosAnteriores = 0;
int estadoLed = 0;
int contador = 0;
int fib1 = 0, fib2 = 1;
int numeroCollatz = 16; // Número inicial interesante para Collatz
int posicion = 0;
bool direccionDerecha = true;
void setup() {
Serial.begin(115200);
// Inicializar LEDs
for (int i = 0; i < NUM_LEDS; i++) {
pinMode(leds[i], OUTPUT);
digitalWrite(leds[i], LOW); // Apagar todos al inicio
}
// Inicializar botones con pull-down interno
for (int i = 0; i < NUM_BOTONES; i++) {
pinMode(botones[i], INPUT_PULLDOWN);
}
Serial.println("Sistema iniciado. Listo para usar.");
}
void loop() {
// *** LECTURA DE BOTONES CON ANTI-REBOTE (DEBOUNCE) ***
static unsigned long ultimoCambio = 0;
static int ultimoModo = modoActual;
if (millis() - ultimoCambio > 200) { // Esperar 200ms para evitar rebotes
int nuevoModo = 0;
for (int i = 0; i < NUM_BOTONES; i++) {
nuevoModo += digitalRead(botones[i]) << i; // Leer en binario (0-7)
}
if (nuevoModo != ultimoModo) {
ultimoModo = nuevoModo;
ultimoCambio = millis();
}
if (nuevoModo != modoActual) {
modoActual = nuevoModo;
reiniciarModo();
Serial.print("Modo cambiado a: ");
Serial.println(modoActual);
}
}
// *** EJECUTAR MODO ACTUAL ***
switch (modoActual) {
case 0: apagarTodosLosLeds(); break; // Modo 0: Apagar todo
case 1: lucesNavidenas(); break; // Modo 1: Luces navideñas
case 2: ojoDeKit(); break; // Modo 2: Ojo de Kit
case 3: corrimiento(); break; // Modo 3: Desplazamiento
case 4: contadorBinario(); break; // Modo 4: Contador binario
case 5: fibonacci(); break; // Modo 5: Fibonacci
case 6: collatz(); break; // Modo 6: Conjetura de Collatz
case 7: sorpresa(); break; // Modo 7: Sorpresa
default: apagarTodosLosLeds(); break; // Por defecto, apagar
}
}
// ==============================================
// ** FUNCIONES AUXILIARES **
// ==============================================
void reiniciarModo() {
apagarTodosLosLeds();
milisegundosAnteriores = millis();
estadoLed = 0;
contador = 0;
fib1 = 0;
fib2 = 1;
numeroCollatz = 16; // Reiniciar Collatz con número interesante
posicion = 0;
direccionDerecha = true;
Serial.println("Modo reiniciado.");
}
void apagarTodosLosLeds() {
for (int i = 0; i < NUM_LEDS; i++) {
digitalWrite(leds[i], LOW);
}
}
void establecerLedsDesdeBinario(int valor) {
for (int i = 0; i < NUM_LEDS; i++) {
digitalWrite(leds[i], (valor >> i) & 1); // Encender según bits
}
}
// ==============================================
// ** EFECTOS DE LEDS **
// ==============================================
// Modo 1: Luces navideñas (alterna pares/impares)
void lucesNavidenas() {
if (millis() - milisegundosAnteriores >= 500) {
milisegundosAnteriores = millis();
estadoLed = !estadoLed;
for (int i = 0; i < NUM_LEDS; i++) {
digitalWrite(leds[i], (i % 2 == 0) ? estadoLed : !estadoLed);
}
}
}
// Modo 2: Ojo de Kit (expansión/contracción)
void ojoDeKit() {
if (millis() - milisegundosAnteriores >= 300) {
milisegundosAnteriores = millis();
apagarTodosLosLeds();
if (direccionDerecha) {
digitalWrite(leds[3 + posicion], HIGH);
digitalWrite(leds[4 - posicion], HIGH);
posicion++;
if (posicion > 3) direccionDerecha = false;
} else {
posicion--;
digitalWrite(leds[3 + posicion], HIGH);
digitalWrite(leds[4 - posicion], HIGH);
if (posicion <= 0) direccionDerecha = true;
}
}
}
// Modo 3: Corrimiento (LED que se desplaza)
void corrimiento() {
if (millis() - milisegundosAnteriores >= 200) {
milisegundosAnteriores = millis();
apagarTodosLosLeds();
digitalWrite(leds[posicion], HIGH);
posicion = (posicion + 1) % NUM_LEDS; // Circular
}
}
// Modo 4: Contador binario (0-255)
void contadorBinario() {
if (millis() - milisegundosAnteriores >= 1000) {
milisegundosAnteriores = millis();
establecerLedsDesdeBinario(contador);
contador = (contador + 1) % 256; // Reiniciar en 255
}
}
// Modo 5: Secuencia de Fibonacci
void fibonacci() {
if (millis() - milisegundosAnteriores >= 1000) {
milisegundosAnteriores = millis();
int siguiente = fib1 + fib2;
fib1 = fib2;
fib2 = (siguiente > 255) ? 1 : siguiente; // Reiniciar si excede 255
establecerLedsDesdeBinario(fib1);
}
}
// Modo 6: Conjetura de Collatz
void collatz() {
if (millis() - milisegundosAnteriores >= 1000) {
milisegundosAnteriores = millis();
establecerLedsDesdeBinario(numeroCollatz);
numeroCollatz = (numeroCollatz % 2 == 0) ?
numeroCollatz / 2 :
numeroCollatz * 3 + 1;
if (numeroCollatz > 255 || numeroCollatz == 1) {
numeroCollatz = random(1, 50); // Nuevo número aleatorio
}
}
}
// Modo 7: Efecto sorpresa (barrido progresivo)
void sorpresa() {
if (millis() - milisegundosAnteriores >= 150) {
milisegundosAnteriores = millis();
apagarTodosLosLeds();
for (int i = 0; i <= estadoLed && i < NUM_LEDS; i++) {
digitalWrite(leds[i], HIGH);
}
estadoLed = (estadoLed + 1) % (NUM_LEDS * 2 + 1);
}
}