Simón dice con Arduino

Introducción

«Simón Dice» es un juego de memoria clásico. El dispositivo crea una secuencia de luces y sonidos que el jugador debe repetir en el orden correcto. Cada vez que aciertas, la secuencia se hace un poco más larga. Este proyecto es más avanzado e involucra la gestión de arrays, la generación de números aleatorios y la lectura de múltiples entradas.

Materiales Necesarios

  • Placa Arduino UNO
  • 4 LEDs (Rojo, Verde, Azul, Amarillo) y sus resistencias de 220Ω
  • 4 Pulsadores y sus resistencias de 10kΩ (pull-down)
  • Zumbador (Buzzer) piezoeléctrico
  • Protoboard y muchos Cables Jumper

Esquema de Montaje

El módulo de sonido tiene 4 pines, pero solo usaremos 3: VCC, GND y D0 (Salida Digital). La salida D0 se pone en estado BAJO cuando el sonido supera el umbral fijado con el potenciómetro del módulo.

Gemini_Generated_Image_k0q1i6k0q1i6k0q1 (4) (2)

Conexiones:

  • LED Rojo → Pin digital 2 del Arduino (con resistencia de 220Ω en serie).
  • LED Verde → Pin digital 3 del Arduino (con resistencia de 220Ω en serie).
  • LED Azul → Pin digital 4 del Arduino (con resistencia de 220Ω en serie).
  • LED Amarillo → Pin digital 5 del Arduino (con resistencia de 220Ω en serie).
  • Pulsador Rojo → Pin digital 6 del Arduino, con una resistencia de 10kΩ a GND. El otro lado del pulsador a 5V.
  • Pulsador Verde → Pin digital 7 del Arduino, con una resistencia de 10kΩ a GND. El otro lado del pulsador a 5V.
  • Pulsador Azul → Pin digital 8 del Arduino, con una resistencia de 10kΩ a GND. El otro lado del pulsador a 5V.
  • Pulsador Amarillo → Pin digital 9 del Arduino, con una resistencia de 10kΩ a GND. El otro lado del pulsador a 5V.
  • Zumbador (Buzzer) → Pin digital 10 del Arduino y el otro pin a GND.
  • Protoboard (+ rail) → 5V del Arduino.
  • Protoboard (- rail) → GND del Arduino.

Código Arduino

#define MAX_LEVEL 25

// Pins para los LEDs y pulsadores
int buttonPins[] = {2, 3, 4, 5};
int ledPins[] = {8, 9, 10, 11};
int buzzerPin = 12;

// Frecuencias para las notas de cada color
int tones[] = {262, 330, 392, 494}; // C, E, G, B

// Array para guardar la secuencia del juego
int gameSequence[MAX_LEVEL];
int currentLevel = 0;

void setup() {
  for (int i = 0; i < 4; i++) {
    pinMode(ledPins[i], OUTPUT);
    pinMode(buttonPins[i], INPUT);
  }
  pinMode(buzzerPin, OUTPUT);
  Serial.begin(9600);
  // Inicializa el generador de números aleatorios
  randomSeed(analogRead(A0)); 
}

void loop() {
  if (currentLevel == 0) {
    newGame();
  }
  
  showSequence();
  
  if (getPlayerInput()) {
    // Si el jugador acierta, pasa al siguiente nivel
    currentLevel++;
    if(currentLevel >= MAX_LEVEL) {
        // ¡Ganaste!
        victoryDance();
        currentLevel = 0;
    }
    delay(1000);
  } else {
    // Si falla, fin del juego
    gameOver();
    currentLevel = 0; // Reinicia el juego
  }
}

void newGame() {
    Serial.println("Nuevo Juego!");
    currentLevel = 1;
    // Genera la primera secuencia
    for(int i = 0; i < MAX_LEVEL; i++) {
        gameSequence[i] = random(0, 4);
    }
}

void showSequence() {
  for (int i = 0; i < currentLevel; i++) {
    int color = gameSequence[i];
    digitalWrite(ledPins[color], HIGH);
    tone(buzzerPin, tones[color]);
    delay(500);
    digitalWrite(ledPins[color], LOW);
    noTone(buzzerPin);
    delay(200);
  }
}

bool getPlayerInput() {
  for (int i = 0; i < currentLevel; i++) {
    int expectedButton = gameSequence[i];
    int pressedButton = -1;
    
    // Espera a que el jugador presione un botón
    while(pressedButton == -1) {
      for(int j = 0; j < 4; j++) {
        if(digitalRead(buttonPins[j]) == HIGH) {
          pressedButton = j;
          break;
        }
      }
    }
    
    // Muestra la elección del jugador
    digitalWrite(ledPins[pressedButton], HIGH);
    tone(buzzerPin, tones[pressedButton]);
    // Espera a que suelte el botón
    while(digitalRead(buttonPins[pressedButton]) == HIGH);
    delay(100); // Debounce
    digitalWrite(ledPins[pressedButton], LOW);
    noTone(buzzerPin);
    
    // Comprueba si es correcto
    if (pressedButton != expectedButton) {
      return false; // Error, fin del juego
    }
  }
  return true; // Secuencia correcta
}

void gameOver() {
  Serial.println("Game Over");
  tone(buzzerPin, 150, 1500); // Tono de error
  delay(1500);
  noTone(buzzerPin);
}

void victoryDance() {
    for(int i=0; i < 4; i++){
        digitalWrite(ledPins[i], HIGH);
    }
    delay(2000);
    for(int i=0; i < 4; i++){
        digitalWrite(ledPins[i], LOW);
    }
}

Cómo Funciona

El Módulo Sensor de Sonido

«Simón Dice» es un juego de memoria clásico que pone a prueba la capacidad del jugador para recordar y repetir secuencias. El sistema funciona mediante una interacción entre la placa Arduino, LEDs para la señal visual, pulsadores para la entrada del jugador y un zumbador para las señales auditivas.

Generación y Presentación de Secuencias

La placa Arduino genera una secuencia aleatoria de colores/sonidos. Cada LED se enciende en un orden específico y, simultáneamente, el zumbador emite un tono asociado a ese color. La longitud de esta secuencia aumenta progresivamente con cada ronda correcta.

Entrada del Jugador y Verificación

El jugador debe observar y memorizar la secuencia presentada. Luego, utiliza los cuatro pulsadores, cada uno asociado a un LED y un color, para replicar la secuencia. El Arduino lee la entrada de los pulsadores y compara la secuencia del jugador con la secuencia generada. Si coinciden, el juego avanza a una nueva ronda con una secuencia más larga; de lo contrario, la partida termina.

Gestión de Múltiples Entradas y Arrays

Este proyecto es más avanzado porque requiere que el Arduino no solo encienda y apague LEDs y el zumbador, sino que también lea simultáneamente el estado de múltiples pulsadores. Además, el programa debe gestionar arrays para almacenar las secuencias de colores/sonidos generadas y la secuencia de entrada del jugador, comparándolas en tiempo real.