DARDUINO
GRUPO 10
Formado por los integrantes:
- Álvaro Egido Fernández
- Alejandro Mayoral Gómez
- Raúl Fauste Jiménez
INTRODUCCIÓN
Darduino surge por el afán de encontrar un juego fácil de montar para aquellas reuniones sociales, donde un grupo de amigos necesita un juego con el que entretenerse y encontrar una vía de escape a sus vidas cotidianas.
COMPONENTES HARDWARE
1.PANTALLA
Se trata de una pantalla lcd 16×2. Esta pantalla está conectada a 6 pines digitales de la placa Arduino. Necesita 1 resistencia y estar conectada a la fuente de alimentación y tierra. El uso que le hemos dado es mostrar toda la información que necesita ver un usuario. Cada vez que se va a mostrar una línea de texto es necesario borrar el mensaje anterior usando “lcd.clear()”.
2. SENSOR ULTRASONIDO
El sensor de ultrasonidos funciona mandando ondas sonoras y calcula el tiempo que pasa hasta que vuelven estas ondas debido al rebote con un objeto que se encuentra delante. En función de este tiempo calcula la distancia a la que se encuentra el objeto. Hay que recalcar que este sensor no es muy preciso, ya que si hay sonido de fondo las ondas se pueden confundir. Está conectado a 2 pines digitales de la placa Arduino, a la fuente de alimentación y a tierra. La hemos usado para comprobar al inicio de la partida que el jugador se encuentra a la distancia suficiente para empezar.
3.LEDS
Los leds son un componente básico de electrónica. Hemos usado 5 leds, cada uno de ellos para identificar a una de las zonas de la diana. Cada uno se conecta a 1 pin digital de la placa Arduino y a tierra. Les hemos dado varios usos: se mantienen encendidos hasta que el sensor detecta que el jugador está lejos, en uno de los modos se enciende uno de ellos para indicar a qué zona hay que lanzar la bola, en el otro modo de juego se mantienen apagados hasta que detecta un impacto en una de las zonas.
4.BOTONES
Hemos usado 2 botones. Cada uno necesita 1 resistencia y se conectan a 1 pin digital de la placa Arduino, a la fuente de alimentación y a tierra. Los hemos usado para cambiar de modo de juego y el número de jugadores y para confirmar las elecciones.
5.RESISTENCIAS
Hemos usado varias resistencias para proteger algunos de los componentes. Hemos usado resistencias de 220 Ohmios y 330 Ohmios.
6.PROTOBOARDS
Se han usado estas placas base para gestionar todos los elementos del proyecto. Hemos usado 3 placas grandes para la mayoría de los componentes y 1 pequeña para los botones.
7.ARDUINO MEGA
Hemos optado por usar una plaza Arduino más grande ya que no teníamos suficientes pines digitales con la placa Arduino normal (13 pines en la normal y 54 pines en la Mega). Este componente es el principal del proyecto, ya que es el encargado de gestionar todo el código software y mandar las señales necesarias al resto de componentes.
8.SENSORES DE IMPACTO
Son sensores de impacto KY031. Consisten en un alambre muy fino de material conductor dentro de un muelle, por lo que al recibir un impacto el alambre del centro se mueve y hace contacto con el muelle, cerrando el circuito. Son uno de los principales componentes, ya que el proyecto se basa en detectar los impactos de unas bolas en diferentes zonas.
9.CABLES
Hemos optado por usar cables macho-macho, hembra-hembra y mixtos, ya que de esta forma conseguimos conectar los componentes que van por fuera (leds, botones y sensores) al resto del circuito, en lugar de tener que conectarlos directamente a las protoboard.
10.OTROS
Para montar la caja en la que va todo el circuito y dejar fijados los componentes hemos usado tornillos, topes, cinta, madera y cartón. Además, hemos usado un sistema con bisagras y cierre para poder acceder al circuito de manera fácil.
COSTES
COMPONENTES | PRECIO |
Pantalla LCD 16×2 | – |
Sensor Ultrasonido | – |
LED x5 | – |
Botones x2 | – |
Resistencias x8 | – |
Protoboard x3 | – |
Arduino MEGA | 20€ |
Sensores de Impacto KY031 x5 | 9€ |
Cables | 9€ |
Contrachapado | 37€ |
Otros (topes, tornillos,…) | – |
TOTAL | 75€ |
CIRCUITO
Hay que tener en cuenta que hemos metido sólo una componente de cada,, para no sobrecargar el circuito.
SOFTWARE
#include <LiquidCrystal.h>
// SENSOR DISTANCIA
int trigger = 10;
int echo = 9;
// BOTONES
int buttonOn = 6;
int buttonMode = 7;
int buttonOnState;
int buttonModeState;
// LEDS
int led1 = 49;
int led2 = 50;
int led3 = 51;
int led4 = 52;
int led5 = 53;
// SENSORES IMPACTO
int impacto1 = A0;
int impacto2 = A1;
int impacto3 = A2;
int impacto4 = A3;
int impacto5 = A15;
int impacto1State;
int impacto2State;
int impacto3State;
int impacto4State;
int impacto5State;
// PANTALLA
LiquidCrystal lcd(12,11,5,4,3,2);
// RANDOM
int umbral;
// GENERAL
int rondas;
void setup() {
//Definir las dimensiones del LCD (16x2)
lcd.begin(16,2);
//Seleccionamos en que columna y en que linea empieza a mostrar el texto
lcd.setCursor(0,0);
//Mostramos el texto deseado
lcd.setCursor(0,1);
//Mostramos el texto deseado
lcd.print("DARDUINO");
// SENSOR DISTANCIA
pinMode(trigger, OUTPUT);
pinMode(echo, INPUT);
digitalWrite(trigger, LOW);
// BOTONES
pinMode(buttonOn, INPUT);
pinMode(buttonMode, INPUT);
// LEDS
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
pinMode(led3, OUTPUT);
pinMode(led4, OUTPUT);
pinMode(led5, OUTPUT);
// SENSORES IMPACTO
pinMode(impacto1, INPUT);
pinMode(impacto2, INPUT);
pinMode(impacto3, INPUT);
pinMode(impacto4, INPUT);
pinMode(impacto5, INPUT);
// GENERAL
rondas = 10;
}
int aleatorio() {
randomSeed(analogRead(A4));
return random(1,6);
}
void encenderLed(int diana) {
if(diana==1) {
digitalWrite(led1, HIGH);
}
else if(diana==2) {
digitalWrite(led2, HIGH);
}
else if(diana==3) {
digitalWrite(led3, HIGH);
}
else if(diana==4) {
digitalWrite(led4, HIGH);
}
else {
digitalWrite(led5, HIGH);
}
}
void apagarLed(int diana) {
if(diana==1) {
digitalWrite(led1, LOW);
}
else if(diana==2) {
digitalWrite(led2, LOW);
}
else if(diana==3) {
digitalWrite(led3, LOW);
}
else if(diana==4) {
digitalWrite(led4, LOW);
}
else {
digitalWrite(led5, LOW);
}
}
int leerImpacto(int diana) {
if(diana==1) {
return analogRead(impacto1);
}
else if(diana==2) {
return analogRead(impacto2);
}
else if(diana==3) {
return analogRead(impacto3);
}
else if(diana==4) {
return analogRead(impacto4);
}
else {
return analogRead(impacto5);
}
}
void comprobarDistancia() {
long t; //timepo que demora en llegar el eco
long d = 0;
lcd.clear();
lcd.print("Alejate");
digitalWrite(led1, HIGH);
digitalWrite(led2, HIGH);
digitalWrite(led3, HIGH);
digitalWrite(led4, HIGH);
digitalWrite(led5, HIGH);
while(d<100) {
digitalWrite(trigger, HIGH);
delayMicroseconds(10); //Enviamos un pulso de 10us
digitalWrite(trigger, LOW);
t = pulseIn(echo, HIGH); //obtenemos el ancho del pulso
d = t/59; //escalamos el tiempo a una distancia en cm
String s = "D: " + String(d) + "cm"; //lcd.print("Distancia ");
Serial.println(s);
delay(400);
}
lcd.clear();
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
digitalWrite(led3, LOW);
digitalWrite(led4, LOW);
digitalWrite(led5, LOW);
}
void loop() {
int modo = 0;
int jugadores = 0;
delay(1000);
lcd.clear();
lcd.print("Elige modo:");
delay(2000);
lcd.clear();
lcd.print("Punteria");
buttonOnState = LOW;
// ELECCION MODO
while(buttonOnState==LOW) {
buttonModeState = LOW;
buttonModeState = digitalRead(buttonMode);
buttonOnState = LOW;
buttonOnState = digitalRead(buttonOn);
if(buttonModeState!=LOW) {
modo = (modo+1)%2;
lcd.clear();
if(modo==0) {
lcd.print("Punteria");
}
else {
lcd.print("Batalla");
}
}
delay(200);
}
delay(500);
// ELECCION JUGADORES
lcd.clear();
lcd.print("Un jugador");
buttonOnState=LOW;
while(buttonOnState==LOW) {
buttonModeState = LOW;
buttonModeState = digitalRead(buttonMode);
buttonOnState = LOW;
buttonOnState = digitalRead(buttonOn);
if(buttonModeState!=LOW) {
jugadores = (jugadores+1)%2;
lcd.clear();
if(jugadores==0) {
lcd.print("Un jugador");
}
else {
lcd.print("Dos jugadores");
}
}
delay(200);
}
delay(500);
lcd.clear();
comprobarDistancia();
// PUNTERIA
if(modo==0) {
for(int i=0; i<rondas; i++) {
for(int j=0; j<=jugadores; j++) {
lcd.clear();
if(j==0) {
lcd.print("Jugador uno");
}
else {
lcd.print("Jugador dos");
}
int diana = aleatorio();
encenderLed(diana);
int impState = leerImpacto(diana);
while(impState>100) {
impState = leerImpacto(diana);
}
apagarLed(diana);
lcd.clear();
lcd.print("Bien hecho");
delay(2000);
}
}
}
// BATALLA
else {
int suma1 = 0;
int suma2 = 0;
for(int i=0; i<rondas; i++) {
for(int j=0; j<=jugadores; j++) {
boolean bucle = true;
lcd.clear();
if(j==0) {
lcd.print("Jugador uno");
}
else {
lcd.print("Jugador dos");
}
while(bucle) {
impacto1State = analogRead(impacto1);
impacto2State = analogRead(impacto2);
impacto3State = analogRead(impacto3);
impacto4State = analogRead(impacto4);
impacto5State = analogRead(impacto5);
if(impacto1State<100) {
if(j==0) {
suma1 = suma1 + 30;
}
else {
suma2 = suma2 + 30;
}
bucle = false;
digitalWrite(led1, HIGH);
delay(500);
digitalWrite(led1, LOW);
delay(500);
}
else if(impacto2State<100) {
if(j==0) {
suma1 = suma1 + 20;
}
else {
suma2 = suma2 + 20;
}
bucle = false;
digitalWrite(led2, HIGH);
delay(500);
digitalWrite(led2, LOW);
delay(500);
}
else if(impacto3State<100) {
if(j==0) {
suma1 = suma1 + 10;
}
else {
suma2 = suma2 + 10;
}
bucle = false;
digitalWrite(led3, HIGH);
delay(500);
digitalWrite(led3, LOW);
delay(500);
}
else if(impacto4State<100) {
if(j==0) {
suma1 = suma1 + 30;
}
else {
suma2 = suma2 + 30;
}
bucle = false;
digitalWrite(led4, HIGH);
delay(500);
digitalWrite(led4, LOW);
delay(500);
}
else if(impacto5State<100) {
if(j==0) {
suma1 = suma1 + 20;
}
else {
suma2 = suma2 + 20;
}
bucle = false;
digitalWrite(led5, HIGH);
delay(500);
digitalWrite(led5, LOW);
delay(500);
}
}
}
}
if(jugadores==0) {
lcd.clear();
lcd.print("Score ");
lcd.print(suma1);
}
else {
lcd.clear();
//String s = "Score uno " + String(suma1);
lcd.print("Score uno ");
lcd.print(suma1);
delay(2000);
lcd.clear();
//String s2 = "Score uno " + String(suma2);
lcd.print("Score dos ");
lcd.print(suma2);
delay(2000);
if(suma1>suma2) {
lcd.clear();
lcd.print("Ganador jug uno");
}
else if(suma1==suma2) {
lcd.clear();
lcd.print("Empate");
}
else {
lcd.clear();
lcd.print("Ganador jug dos");
}
}
}
}
PROCESO
El proceso para lograr construir desde cero siguió una la filosofía de menos a más.
1º Comenzamos realizando los circuitos de las siguientes componentes por separado:
- Pantalla LCD
- LEDs
- Sensor Ultrasonido
- Sensores de Impacto
- Botones
2º Comenzamos acoplando los distintos circuitos a uno solo, comprobando en cada paso que todo funcionara según lo previsto.
3º Tomamos medidas para el montaje de la caja y fuimos a comprar el material necesario.
4º Realizamos el montaje de la caja, junto con los agujeros necesarios para el sensor de ultrasonido y la pantalla.
5º Fijamos las protoboard a la caja y montamos el circuito final en la caja, teniendo cuidado y separando los cables mediante celo para separar así y obtener un circuito final más limpio.
6º Realizamos las superficies de contacto para el sensor de impacto, que consisten en cartón que golpea al sensor.
7º Finalmente, se decoró con colores la caja.
FUNCIONAMIENTO (Casos de Uso)
A continuación vamos a explicar brevemente el funcionamiento, detallando los casos de uso más relevantes:
1. Cambiar de Jugador:
Darduino está pensado tanto para ser un juego solitario (un único jugador) como para ser un juego multijugador (dos jugadores), el cambio del número de jugadores se hará con los botones, uno para cambiar de opciones y otro para confirmar.
2. Cambiar Modo de Juego
Darduino está diseñado de forma que tenga dos modos de juego disponible, uno llamado Puntería y otro llamado Batalla. La forma de cambiar de modo se realiza de forma análoga a cambiar de jugador con los botones, con uno se cambia de opción y con otro se confirma.
3. Detectar Distancia
Darduino tiene un sensor de ultrasonido con el que comprueba si estamos a una distancia prudente antes de empezar a jugar. Para ello, una vez seleccionado el modo de juego y el número de jugadores, se mide la distancia a la que está el sujeto. Si esta distancia es aceptable se apagan los LEDs, sirviendo como la señal para empezar a jugar.
4. Modo de Juego Batalla
El modo Batalla esta pensado principalmente para jugar entre dos jugadores. En modo funciona como es fácil de imaginar, dos jugadores tiran un número determinado de rondas, uno cada vez y aquel que más puntos obtenga es el ganador. También se puede jugar un sólo jugador, al final se le pondrá la puntuación que obtiene tras las rondas.
Hay que resaltar que en cada lanzamiento, donde detectamos impacto, se enciende el LED para avisar de que se ha impactado en esa zona.
5. Modo de Juego Puntería
El modo Puntería, está pensado para entrenar. Este modo funciona de la siguiente manera, cada vez se enciende un LED correspondiente a una zona, y se tiene que dar con la bola lanzada a la zona iluminada. El LED seguirá encendido hasta que consigamos detectar el impacto. Esto se realiza durante el número de rondas predeterminado.
Si dos jugadores juegan a este modo, el funcionamiento es el mismo, pero un jugador cada vez.
PROBLEMAS
-Problema con los pines digitales en Arduino:
En el proceso de adaptar todos los circuitos que habíamos hecho por separado en uno solo, nos dimos cuenta de que el número de pines digitales que habíamos usado era superior a los trece que nos ofrece Arduino. Además, también nos dimos cuenta de que los pines 0 y 1 los usa la placa como transmisión y receptor de datos, luego no funcionaban de la misma forma que el resto. (6 pines de la pantalla, más 5 de cada led, 5 de los sensores de impacto, 2 de botones y 2 del sensor de ultrasonidos, eso hacía un total de 20 pines).
Primero, intentamos usar un registro de desplazamiento, pero nos encontramos con el problema de que no puede usar dispositivos de entrada/salida a la vez. Después, utilizamos un multiplexor, pero nos encontramos con el error de que no puede detectar más de una salida a la vez y que los hacían muy mal contacto con la placa, luego o había que tirar de ellos o había que soldarlos. Al final, la solución óptima y rápida que encontramos fue adquirir un Arduino MEGA, que nos solucionaba todos los problemas del tirón.
Finalmente, también aprendimos que los sensores de impacto podían funcionar de manera analógica. Eso nos reducía el número de digitales a 15, luego no podíamos librarnos del MEGA igualmente.
-Concurrencia con los sensores de impacto:
En el modo de juego de Batalla, todos los sensores de impacto se deben de escuchar a la vez, por lo tanto, como ya hemos visto, el bucle debe de leer cada sensor de impacto en cada iteración del bucle. Esto ocasiona problemas de concurrencia, ya que puede dar la casualidad de que justo le des a un sensor de impacto cuando se está leyendo otro. Creemos que este error es mínimo, ya que estamos hablando de milisegundos, pero es una explicación coherente a que en muy determinadas ocasiones el sensor de impacto no detecte nada.
FOTOS Y VÍDEO RESULTADO FINAL
CONCLUSION
Tras finalizar el proyecto, nos hemos dado cuenta que el mundo de arduino es mucho más extenso de lo que podíamos imaginar en un primer momento. La posibilidad de realizar cualquier cosa está al alcance de la mano.
Hemos aprendido mucho acerca de nuevos componentes y hemos repaso algunos conceptos que teníamos medio olvidados acerca de electrónica. Nos ha servido mucho para entender mejor como funcionan numerosos circuitos que vemos en nuestro día a día.
Y finalmente, nos lo hemos pasado en grande diseñando y montando el circuito, ha sido una experiencia enriquecedora.