De protoboard a PCB: Construye un juego Simon Says – Parte 1
Componentes y suministros
| Componente | Cantidad | Notas |
|---|---|---|
| Arduino UNO | 1 | |
| Protoboard sin soldar tamaño completo | 1 | |
| LED (genérico) | 4 | |
| Pulsador 12mm SparkFun | 4 | |
| Zumbador | 1 | |
| Cables jumper (genéricos) | 12 | |
| Resistencia 10k ohm | 4 | |
| Resistencia 330 ohm | 4 | |
| Cable USB-A a B | 1 |
Aplicaciones y servicios online
- Arduino IDE
Sobre este proyecto
Introducción
Todos conocemos el clásico Simon Says: repetir una secuencia de luces pulsando los botones correspondientes. Para Hackster Live mostramos una herramienta de diseño PCB llamada Upverter. Proyecto divertido y simple para crear y convertir en PCB. Abajo está el proyecto base con hardware y código.
Serie de 3 partes
- Parte 1: Crear el juego Simon Says (este artículo)
- Parte 2: Diseñar PCB basada en el juego usando Upverter
- Parte 3: Fresar tu propia PCB desde el diseño de Upverter con CNC
Qué aprenderás
- Montar proyecto básico en protoboard
- Diseñar PCB en Upverter
- Fresar tu propia PCB con CNC
Software
Si no tienes Arduino IDE, descarga la última versión para tu SO aquí.
Montaje del hardware
Me inspiré en el ejemplo del Kit Inventor de Sparkfun y lo ajusté ligeramente. Revisa el diagrama Fritzing abajo.


Código
Lo divertido es que hay muchas variaciones. Usé el hardware de Sparkfun como base y escribí el código desde cero. Si no quieres programar, usa el mío, el de Sparkfun con ajustes, o busca otros códigos compatibles.
Incluí comentarios detallados y prints de depuración en Serie para ver qué pasa mientras juega. ¡Mira el video del juego en acción!
Video del juego Simon Says
Nota: En el video puse 5 luces seguidas para ganar. Cambiable para más dificultad, pero quería video corto :).
Ahora estás listo para pasar tu protoboard a PCB. Aprende cómo en Parte 2: Diseñando PCB con Upverter.
Código
Código Arduino Simon Says
int ledArray[] = {12, 9, 5, 2}; // 0=verde, 1=rojo, 2=amarillo, 3=azul
int buttonArray[] = {13, 10, 6, 3}; // mismo orden
int pinCount = 4;
int buzzer = 8;
int ledState = 0;
int gameState = 0;
#define NUMBERTOWIN 5 // Luces a acertar para ganar (cambiar para dificultad)
int gameValues[NUMBERTOWIN];
int roundNum = 0;
unsigned long previousMillis = 0; // para pre-game sin delay
unsigned long interval1 = 500; // tiempo entre parpadeos
void setLed(int ledNum);
void displayClue(int roundNum);
boolean waitForInput(int buttonNum);
void setup() {
Serial.begin(9600);
Serial.println("setup");
for (int Pin = 0; Pin < pinCount; Pin++) pinMode(ledArray[Pin], OUTPUT);
for (int Pin = 0; Pin < pinCount; Pin++) pinMode(buttonArray[Pin], INPUT_PULLUP);
randomSeed(analogRead(0)); // semilla aleatoria por ruido analógico
}
void loop() {
if (gameState == 0) {
int button0 = digitalRead(buttonArray[0]);
int button1 = digitalRead(buttonArray[1]);
int button2 = digitalRead(buttonArray[2]);
int button3 = digitalRead(buttonArray[3]);
if (button0 && button1 && button2 && button3) pre_game();
else {
Serial.println("button Pressed");
setLed(-1); roundNum = 0; delay(1000); gameState = 1;
}
}
if (gameState == 1) gamePlay();
if (gameState == 2) { // Ganaste
delay(500); winning_sound(); winDisplay(); winDisplay(); winDisplay(); loseDisplay();
Serial.println("winDisplay"); delay(1000); gameState = 0;
}
if (gameState == 3) { // Perdiste
delay(500); losing_sound(); loseDisplay(); loseDisplay(); loseDisplay();
Serial.println("loseDisplay"); delay(1000); gameState = 0;
}
}
void pre_game() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis > interval1) {
if (ledState == 0) { Serial.println("pre green"); setLed(0); ledState = 1; }
else if (ledState == 1) { Serial.println("pre red"); setLed(1); ledState = 2; }
else if (ledState == 2) { Serial.println("pre yellow"); setLed(2); ledState = 3; }
else if (ledState == 3) { Serial.println("pre blue"); setLed(3); ledState = 0; }
previousMillis = currentMillis;
}
}
void gamePlay() {
Serial.println("gamePlay");
for (int i = 0; i < NUMBERTOWIN; i++) gameValues[i] = floor(random(0, 4));
for (int i = 0; i < NUMBERTOWIN; i++) Serial.println(gameValues[i], DEC);
Serial.print("Starting Round "); Serial.println(roundNum, DEC);
for (int r = 0; r < NUMBERTOWIN; r++) {
displayClue(roundNum);
for (int i = 0; i <= roundNum; i++) {
Serial.print("Waiting for input "); Serial.print(i+1, DEC);
Serial.print(" of "); Serial.print(roundNum+1, DEC); Serial.println();
if (waitForInput(gameValues[i])) {
if (i == roundNum) {
Serial.println("Correct");
if (roundNum == NUMBERTOWIN-1) { Serial.println("You Win!"); gameState = 2; return; }
else Serial.println("Continue");
}
} else { Serial.println("You Lose!"); gameState = 3; return; }
}
roundNum++; delay(1000);
}
}
void setLed(int ledNum) {
if (ledNum < 0) {
for (int i = 0; i < pinCount; i++) digitalWrite(ledArray[i], LOW);
} else {
for (int i = 0; i < pinCount; i++) {
digitalWrite(ledArray[i], (i == ledNum) ? HIGH : LOW);
}
}
}
void displayClue(int roundNum) {
setLed(-1);
for (int i = 0; i <= roundNum; i++) {
setLed(gameValues[i]); delay(750); setLed(-1); delay(250);
}
}
boolean waitForInput(int buttonNum) {
while (true) {
int button0 = digitalRead(buttonArray[0]);
int button1 = digitalRead(buttonArray[1]);
int button2 = digitalRead(buttonArray[2]);
int button3 = digitalRead(buttonArray[3]);
if (!button0 || !button1 || !button2 || !button3) {
delay(250); // anti-rebote
if (buttonNum == 0) { digitalWrite(ledArray[0], HIGH); delay(250); digitalWrite(ledArray[0], LOW); }
else if (buttonNum == 1) { digitalWrite(ledArray[1], HIGH); delay(250); digitalWrite(ledArray[1], LOW); }
else if (buttonNum == 2) { digitalWrite(ledArray[2], HIGH); delay(250); digitalWrite(ledArray[2], LOW); }
else if (buttonNum == 3) { digitalWrite(ledArray[3], HIGH); delay(250); digitalWrite(ledArray[3], LOW); }
if (buttonNum == 0 && button0 == 0) { Serial.println("0 Pressed"); return true; }
else if (buttonNum == 1 && button1 == 0) { Serial.println("1 Pressed"); return true; }
else if (buttonNum == 2 && button2 == 0) { Serial.println("2 Pressed"); return true; }
else if (buttonNum == 3 && button3 == 0) { Serial.println("3 Pressed"); return true; }
else return false;
}
}
}
void winDisplay() {
for (int i = 0; i < 4; i++) { digitalWrite(ledArray[i], HIGH); delay(75); digitalWrite(ledArray[i], LOW); delay(75); }
for (int i = 2; i >= 0; i--) { digitalWrite(ledArray[i], HIGH); delay(75); digitalWrite(ledArray[i], LOW); delay(75); }
}
void winning_sound() {
Serial.println("buzzer1");
tone(buzzer, 294, 250); delay(200);
tone(buzzer, 294, 250); delay(200);
tone(buzzer, 294, 250); delay(200);
tone(buzzer, 392, 500); delay(500);
tone(buzzer, 392, 250); delay(200);
tone(buzzer, 440, 250); delay(200);
tone(buzzer, 392, 250); delay(200);
tone(buzzer, 440, 250); delay(200);
tone(buzzer, 494, 500);
}
void loseDisplay() {
for (int i = 0; i < 4; i++) digitalWrite(ledArray[i], HIGH);
delay(200);
for (int i = 0; i < 4; i++) digitalWrite(ledArray[i], LOW);
delay(200);
}
void losing_sound() {
Serial.println("losing_sound");
tone(buzzer, 98, 250); delay(250);
tone(buzzer, 93, 250); delay(250);
tone(buzzer, 87, 250); delay(250);
}
Esquemáticos
simon_says_fritzing_Yb8EdKPqD4.fzz
Proceso de manufactura
- Construye un Juego Giroscópico en Tiempo Real con Arduino Nano y Sensor MPU-6050
- Proyecto Dados Digitales Arduino: Construye tu Propio Generador de Números Aleatorios con LCD
- Construye tu Propio Juego de Ruleta de 37 LEDs con Arduino Nano
- Mando USB para juegos DIY con Arduino – Construye tu propio gamepad de alto rendimiento
- Juego interactivo con joystick analógico y LEDs en Arduino
- Detector de Rango Portátil – Kit DIY Arduino Nano con HC-SR04, Batería 18650 y Carcasa Impresa en 3D
- Pixel Chaser: Juego LED Interactivo de Un Toque con Arduino Nano
- Proyecto de electroplacado de cobre: Construye un sistema inteligente con Arduino UNO
- Pong Neón en Matriz NeoPixel con Arduino Nano
- Fabricación aeroespacial para talleres pequeños: Guía práctica
- Guía completa de fabricación de PCB de 4 capas: Proceso paso a paso