21.- Servo Jugando a sumar

Publicado el 08 diciembre 2013 por Practicandoarduino @PracticaArduino

Bienvenidos a otro tutorial de Practicando Arduino, esta vez vamos a jugar, si habeis oido bien, vamos a hacer un juego usando servos. El juego consistirá en un módulo LKM1638 en el que apareceran en los displays más a la izquierda 2 número que generaremos de forma aleatoria y en los 4 displays de la derecha tendremos que introducir la suma de esos números, mientras nuestro servo nos marcará un tiempo límite que tenemos para introducir el resultado, si tardamos más sonará una alarma con un zumbador y nos mostrará las palabras game over en los displays, si acertamos nos muestra otro número.

¿Que necesitamos?:

1 Placa Arduino Uno
1 Protoboard
1 Resistencia de 100Ω (opcional)
1 Zumbador
1 Servo
1 Módulo LKM1638 (podeis usar displays 7 segmentos y pulsadores pero de esta forma es más cómodo)
Cables para realizar las conexiones

Primero conectamos los pins GND y 5V a la protoboard, la resistencia la conectamos a GND de la protoboard, el terminal negativo del buzzer a la resistencia y el terminal positivo al pin 10. El servo tiene 3 terminales, rojo para 5V, negro para GND y blanco para el pin 6.
Ahora conectamos el módulo LKM1638 de la siguiente forma:
Tenemos que conectarlo a nuestra placa Arduino de la siguiente manera:

PIN 1 del módulo a 5V.
PIN 2 del módulo a GND.
PIN 3 del módulo a pin de Arduino 9.
PIN 4 del módulo a pin de Arduino 8.
PIN 5 del módulo a pin de Arduino 7.


No incluyo esto en el sketch básicamente porque no se como se crea un componente en Fritzing. Así que la parte del módulo LKM1638 no aparece.

Codigo fuente:

#include 
#include 
#include  //Librerias necesarias
#include 
#include 
#include 
#include  
 
TM1638 module(8, 9, 7); //Pins para el módulo
Servo miServo;
int giro=1;
int i=0, y=0;
int a,b;
byte pulsacion, oldpulsacion;
int tabla[8]={0,0,0,0,0,0,0,0}; //tabla con los valores a mostrar
byte gameOver[8]={125,119,84,121,63,62,121,80}; //game over
long previousMillis = 0;
unsigned long currentMillis;
long intervalo=100; //pausa entre movimiento del servo
int duracion=250; //Duración del sonido
int fMin=2000; //Frecuencia más baja que queremos emitir
int fMax=4000; //Frecuencia más alta que queremos emitir
 
void setup(){
 miServo.attach(6); //vinculamos el servo
 miServo.write(0); //posición inicial
 pinMode (10, OUTPUT); //pin para el buzzer
 module.setDisplayToDecNumber(0,0); //Ponemos el display a 0
 a=TrueRandom.random(0,100); //núemro aleatorio
 b=TrueRandom.random(0,100); //número aleatorio
 //guardamos los números en la tabla para mostrarlos
 tabla[7]=a/10;
 tabla[6]=a%10;
 tabla[5]=b/10;
 tabla[4]=b%10;
}
 
void loop(){
 
  mostrar(tabla); //mostramos en los displays
  pulsacion=module.getButtons(); //guardamos la pulsación
  module.setLEDs(pulsacion); //encendemos el correspondiente led
  if (pulsacion != oldpulsacion){
    y=(pulsacion^oldpulsacion)&pulsacion; //guardamos los botones pulsados
     i=0;
     while (i<4){//comprobamos que boton/es de los 4 que vamos a usar
        if (y & 0x80)
          tabla[i]++; //incrementamos el dígito
          if (tabla[i]>9)
           tabla[i]=0;
         y= y << 1; //desplazamiento a la izquierda
         i++; //incrementamos contador
     }
    mostrar(tabla);
    oldpulsacion=pulsacion; //actualizamos la pulsación
    comprobar(); //comprobamos si la suma es correcta
  }
  girarServo(); //giramos el servo
}
 
void mostrar(int miTabla[]){//muestra la tabla en el display
  for (i=0;i<8;i++)
      module.setDisplayDigit(miTabla[7-i],i,0); //mostramos los dos dígitos con los que vamos a operar
}
 
void comprobar(){ //comprueba si la suma es correcta
  if (tabla[3]==0 & ((tabla[2]*100 + tabla[1]*10 + tabla[0])==a+b))
    reset();
}
 
void reset(){ //resetea valores
  module.setDisplayToDecNumber(0,0); //Ponemos el display a 0
  for (i=0;<4;i++) //reseteamos a 0 la tabla
     tabla[i]=0;
   a=TrueRandom.random(0,100); //dos nuevos números aleatorios
   b=TrueRandom.random(0,100);
   tabla[7]=a/10; //volvemos a guardarlos
   tabla[6]=a%10;
   tabla[5]=b/10;
   tabla[4]=b%10;
   miServo.write(0); //servo a su posición inical
   giro=1; //reseteamos al ángulo de giro
 }
void girarServo(){
   currentMillis = millis();
   if (currentMillis - previousMillis > intervalo){ //si han pasado 100 milisegundos actuamos
    previousMillis = currentMillis;
 
    if (!(giro>180)){ //si el valor es menor que 180 giramos
      miServo.write(giro);
      giro++;
    }else{//si no se nos ha acabado el tiempo
      module.setDisplay(gameOver); //mostramos game over en los displays
      sirena(); //hacemos sonar la sirena de alarma
      reset(); //reseteamos
    }
  }
}
 
void sirena(){
  int j=0;
  for (j=0;j<5;j++){ //la sirena suena 5 veces
    for (i=fMin;i<=fMax; i++) 
      tone(10, i, duracion);
     //sonido más grave
     for (i=fMax;i>=fMin; i--)
      tone(10, i, duracion); 
  }
}

Lo primero que hacemos en incluir las librerías necesarias, la librería TrueRandom la tenemos que descargar de aquí y después las variables que usaremos,.
En el void setup() vinculamos el servo a un pin y lo colocamos en la posición incial, configuramos el pin del buzzer, ponemos el display a 0 le damos valor a las variables para la suma de forma aleatoria y guardamos las variables en la tabla.
En el void loop() mostramos la tabla en el display, leemos el botón pulsado y encendemos el led correspondiente, tras esto vemos que botón hemos pulsado, si es de los 4 de la derecha incrementamos el valor correspondiente si no no hacemos nada, si nos pasamos de 9 lo ponemos a 0, ya que no podemos mostrar en decimal un número mayor que 9 con un display 7 segmentos. Ahora mostramos los valores, actualizamos el valor de pulsacion y comprobamos si la suma es correcta. Si la suma es correcta reseteamos y volvemos a empezar. En cada iteración se llama a la función encargada de hacer girar al servo, allí le marcamos un intervalo de 100 milisegundos, teniendo en cuenta que un servo gira de 0 a 180 grados y nosotros vamos a incrementar el valor de giro en 1 cada 100 milisegundos, tenemos 18 segundos hasta que el servo llegue a su tope. Cuando esto ocurre, mostramos en los displays 7 segmentos la frase game over (hay que hecharle imaginación), hacemos sonar la sirena y reseteamos para volver a empezar.

P.D. El folio con las marcas de tiempo es cutre pero cumple su función.



style="display:inline-block;width:728px;height:15px"
data-ad-client="ca-pub-3868159888315364"
data-ad-slot="7639712738">

PracticandoArduino