Adivinador con Arduino UNO

Adivinador con Arduino UNO

En esta ocación les traigo un proyecto simple con leds y switches (botones de contacto), el Adivinador con Arduino UNO. Este proyecto es muy simple y la idea es comenzar a brindar formas de combinar componentes simples de manera de hacer algo util y/o divertido. En este caso se trata de un circuito simple que consta de 3 botones y 3 leds, y el objetivo del proyecto es que su Arduino intentará adivinar que boton presionará usted.

Componentes necesarios

Para armar nuestro proyecto necesitaremos los siguiente componentes que conseguirá en cualquier casa de electrónica:

  • 3 leds (en lo posible de distinto color, yo usé rojo, verde y amarillo)
  • 3 switches de superficie (los mios venian con el boton para colocar arriba de colores tambien)

  • 3 resistencias de 1k
  • 7 cables de interconexión macho-macho
  • 3 cables tipo jumpers para breadboard/protoboard (yo uso cable rígido telefónico monofilar)
  • Un breadboard o protoboard
  • Un Arduino UNO (o MEGA) con su cable USB para conectarlo a la PC

Conexiones de nuestro Adivinador con Arduino

Les dejo al final una imagen con las conexiones pero por las dudas las detallo a continuación ya que el dibujo no es muy claro:

  • Leds: cada led debe estar conectado a GND en su pata más corta y a una resistencia de 1k en la otra pata (la mas larga)
  • Resistencias: una pata al led como dice arriba, y la otra al pin del Arduino que corresponde. Yo usé: 4 para el rojo, 3 para el verde y 2 para el amarillo (ya que cada resistencia corresponde con un led)
  • Switches: van conectados a GND en una pata, y la otra al pin del Arduino que corresponde. Yo usé: 12 para el rojo, 11 para el verde y 10 para el amarillo (recuerden que mis switches tienen boton de plastico de colores que igualé a mis leds)

Esquema de conexión del Adivinador con Arduino UNO

Algunas observaciones si no encuentra los materiales exactos pero se aproxima:

  • En lugar de colores puede usar los 3 leds iguales, y trate de referenciarlos como primero, segundo y tercero (puede asignarle un colo ejemplo rojo = primero, etc.)
  • Si los switches no tienen boton de plastico no importa. Tambien puede referenciarlos como primero, segundo y tercero.
  • Los switches suelen tener 4 patas, pero vienen conectadas internamente de a pares asi que revisenlas antes de conectarlo con un tester o multímetro.
  • Conecten todo primero y luego conecten el Arduino. No recomiendo trabajar con voltaje ya que un cortocircuito puede arruinar su Arduino

El Sketch

Les dejo el Sketch que deben cargar en su Arduino pero con la consigna de que traten de entenderlo y luego se animen a probar cambios:

// Definimos los pines a donde estan conectados los leds
#define LED_ROJO_PIN 4
#define LED_VERDE_PIN 3
#define LED_AMARILLO_PIN 2

// Definimos los pines donde estan conectados los switches
#define SW_ROJO_PIN 12
#define SW_VERDE_PIN 11
#define SW_AMARILLO_PIN 10

// Definimos un array con los leds y otro con los switches
unsigned int led[] = {LED_ROJO_PIN, LED_VERDE_PIN, LED_AMARILLO_PIN};
unsigned int sw[] = {SW_ROJO_PIN, SW_VERDE_PIN, SW_AMARILLO_PIN};

// Variables para llevar las estadisticas del juego
unsigned long intentos = 0;
unsigned long aciertos = 0;

void setup() {
  int x;
  
  // Inicializamos el Monitor Serial y nos presentamos!
  Serial.begin(9600);
  Serial.println("Adivinador listo!");
  Serial.println("");
 
  // Envia instrucciones por el Monitor Serial
  Serial.println("Instrucciones:");
  Serial.println("");
  Serial.println("- Cada led corresponde con un switch");
  Serial.println("- El Adivinador tratara de adivinar cual switch va a presionar");
  Serial.println("- Presione cualquiera de los 3 switch");
  Serial.println("- Luego el adivinador encendera la luz del switch que penso");
  Serial.println("- Finalmente el Adivinador mostrará estadistica de aciertos");
  Serial.println("");
  Serial.println("Ahora encenderemos los leds uno a la vez...");
  Serial.println("");
  
  // Esto es solo para apagar el led interno del Arduino (que no usaremos)
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  for (x=0; x<3; x++) {
    // Inicializamos los pines de los leds y los apagamos inicialmente
    pinMode(led[x], OUTPUT);
    digitalWrite(led[x], LOW);
    
    // Tambien inicializamos los pines de los switches
    pinMode(sw[x], INPUT_PULLUP);
  }
  
  // Demora para dar tiempo al jugador
  delay(2000);
  
  // Rutina para probar los leds (prende uno a la vez por 1 segundo)
  for (x=0; x<3; x++) {
    digitalWrite(led[x], HIGH);
    delay(1000);
    digitalWrite(led[x], LOW);
  }
  
  // Rutina para probar que los 3 switches andan antes de empezar
  for (x=0; x<3; x++) {
    Serial.println(String("Ahora presione el switch ") + (x+1) + " para continuar...");
    while (digitalRead(sw[x]) == HIGH);
  }
  
  Serial.println("Todo bien! Estamos listos para empezar!");
  Serial.println("");
  
  // Pausa para evitar un falto intento al principio
  delay(1000);
}

void loop() {
  int x;
  int swApretado = -1;
  int seleccion = predecirNumero();
  
  Serial.print("Ya se que switch va a presionar, presione uno ahora: ");

  while (swApretado == -1) {
    for (x=0; x<3; x++) {
      if (digitalRead(sw[x]) == LOW) {
        swApretado = x;
        break;
      }
    }
  }

  // Prendo el led que elegi por 1 segundo
  digitalWrite(led[seleccion], HIGH);
  delay(1000);
  digitalWrite(led[seleccion], LOW);
  
  // Mensaje segun el resultado
  if (swApretado == seleccion) {
    Serial.println("Acerte!!!");
    // Actualizo los aciertos
    aciertos++;
  }
  else {
    Serial.println("Me equivoque...");
  }
  
  // Actualizo los intentos
  intentos++;
  
  // Muestro estadisticas
  Serial.println(String("Aciertos: ") + aciertos + "/" + intentos + ", " + ((float)aciertos/(float)intentos*100) + "%");
  Serial.println("");

  // Pausa entre intentos
  delay(3000);
}

// Elijo un numero al azar entre 0 y 2
int predecirNumero() {
  return random(0, 3);
}

Por último abran el Monitor Serial y disfruten del Adivinador con Arduino!

Adivinador con Arduino Mejorado

Les dejo una versión mejorada del Adivinador con Arduino, que usa estadísticas para predecir en lugar de un numero aleatorio.

// Definimos los pines a donde estan conectados los leds
#define LED_ROJO_PIN 4
#define LED_VERDE_PIN 3
#define LED_AMARILLO_PIN 2

// Definimos los pines donde estan conectados los switches
#define SW_ROJO_PIN 12
#define SW_VERDE_PIN 11
#define SW_AMARILLO_PIN 10

// Definimos un array con los leds y otro con los switches
unsigned int led[] = {LED_ROJO_PIN, LED_VERDE_PIN, LED_AMARILLO_PIN};
unsigned int sw[] = {SW_ROJO_PIN, SW_VERDE_PIN, SW_AMARILLO_PIN};

// Variables para llevar las estadisticas del juego
unsigned long intentos = 0;
unsigned long aciertos = 0;
unsigned long aciertosAzar = 0;

// Mejoramos eficacia llevando algo de estadística de prediccion
unsigned char estadistica[3][3][3];
unsigned char unoAtras = 255;
unsigned char dosAtras = 255;

void setup() {
  int x, y, z;
  
  // Inicializamos el Monitor Serial y nos presentamos!
  Serial.begin(9600);
  Serial.println("Adivinador listo!");
  Serial.println("");
 
  // Envia instrucciones por el Monitor Serial
  Serial.println("Instrucciones:");
  Serial.println("");
  Serial.println("- Cada led corresponde con un switch");
  Serial.println("- El Adivinador tratara de adivinar cual switch va a presionar");
  Serial.println("- Presione cualquiera de los 3 switch");
  Serial.println("- Luego el adivinador encendera la luz del switch que penso");
  Serial.println("- Finalmente el Adivinador mostrará estadistica de aciertos");
  Serial.println("");
  Serial.println("Ahora encenderemos los leds uno a la vez...");
  Serial.println("");
  
  // Esto es solo para apagar el led interno del Arduino (que no usaremos)
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);

  for (x=0; x<3; x++) {
    // Inicializamos los pines de los leds y los apagamos inicialmente
    pinMode(led[x], OUTPUT);
    digitalWrite(led[x], LOW);
    
    // Tambien inicializamos los pines de los switches
    pinMode(sw[x], INPUT_PULLUP);
  }
  
  // Demora para dar tiempo al jugador
  delay(2000);
  
  // Rutina para probar los leds (prende uno a la vez por 1 segundo)
  for (x=0; x<3; x++) {
    digitalWrite(led[x], HIGH);
    delay(1000);
    digitalWrite(led[x], LOW);
  }
  
  // Rutina para probar que los 3 switches andan antes de empezar
  for (x=0; x<3; x++) {
    Serial.println(String("Ahora presione el switch ") + (x+1) + " para continuar...");
    while (digitalRead(sw[x]) == HIGH);
  }
  
  Serial.println("Todo bien! Estamos listos para empezar!");
  Serial.println("");
  
  // Inicializamos las estadisticas
  for (x=0; x<3; x++) {
    for (y=0; y<3; y++) {
      for (z=0; z<3; z++) {
        estadistica[x][y][z] = 0;
      }
    }
  }

  // Pausa para evitar un falto intento al principio
  delay(1000);
}

void loop() {
  int x;
  unsigned char swApretado = 255;
  unsigned char seleccion = predecirNumero();
  unsigned char azar = predecirNumeroAzar();
  
  Serial.print("Ya se que switch va a presionar, presione uno ahora: ");

  while (swApretado == 255) {
    for (x=0; x<3; x++) {
      if (digitalRead(sw[x]) == LOW) {
        swApretado = (unsigned char)x;
        break;
      }
    }
  }

  // Prendo el led que elegi por 1 segundo
  digitalWrite(led[seleccion], HIGH);
  delay(1000);
  digitalWrite(led[seleccion], LOW);
  
  // Mensaje segun el resultado
  if (swApretado == seleccion) {
    Serial.println("Acerte!!!");
    // Actualizo los aciertos
    aciertos++;
  }
  else {
    Serial.println("Me equivoque...");
  }
  
  // Estadísticas Azar
  if (swApretado == azar) {
    aciertosAzar++;
  }
  
  // Actualizo los intentos
  intentos++;
  
  // Muestro estadisticas
  Serial.print(String("Aciertos: ") + aciertos + "/" + intentos + ", " + ((float)aciertos/(float)intentos*100) + "%, ");
  Serial.println(String("Azar: ") + aciertosAzar + "/" + intentos + ", " + ((float)aciertosAzar/(float)intentos*100) + "%");
  Serial.println("");

  // Comenzamos a guardar estadística cuando ya tenemos al menos 3 rondas ya que guardamos ocurrencias de 3 rondas consecutivas 
  if (intentos > 2) {
    estadistica[dosAtras][unoAtras][swApretado]++;
  }

  // Ajustamos estadística
  dosAtras = unoAtras;
  unoAtras = swApretado;
  
  // Muestra informacion de la estadistica de prediccion
  // debugInfo();
  
  // Pausa entre intentos
  delay(1000);
}

unsigned char predecirNumero() {
  char pick = -1;
  
  for (unsigned char x=0; x<3; x++) {
    if (estadistica[dosAtras][unoAtras][x] > pick) {
      pick = (unsigned char)x;
    }
  }
  
  return (unsigned char)pick;
}

unsigned char predecirNumeroAzar() {
  return (unsigned char)random(0, 3);
}

void debugInfo() {
  int x, y, z;
  
  Serial.println(String("dosAtras: ") + dosAtras + ", unoAtras: " + unoAtras);
  Serial.println("");
  
  for (x=0; x<3; x++) {
    switch (x) {
      case 0:
        Serial.println("Rojo:");
        break;
      case 1:
        Serial.println("Verde:");
        break;
      case 2:
        Serial.println("Amarillo:");
        break;
    }
    
    for (y=0; y<3; y++) {
      for (z=0; z<3; z++) {
        Serial.print(String(x) + " " + y + " " + z + ": ");
        Serial.print(estadistica[x][y][z], DEC);
        Serial.print(", ");
      }
      Serial.println("");
    }
  }
}

 

 

Deja un comentario