Proyecto Simón:

Anuncio
Proyecto Simón:
DISEÑO SISTEMAS MÓVILES Y EMPOTRADOS
DSEM
Ángel Castillo
Sergi Martínez
Héctor Ortiz
Toni Torronteras
1
ÍNDICE
1.
2.
INTRODUCCIÓN ......................................................................................................... 3
DISEÑO ANALÓGICO.................................................................................................. 4
2.1. Pulsadores .......................................................................................................... 5
2.2. Caja..................................................................................................................... 7
3. Placa Wiring............................................................................................................... 8
4. Código...................................................................................................................... 10
4.1. Funcionamiento del programa ........................................................................ 11
4.2. Modo 1 player .................................................................................................. 11
4.3. Modo 2 player .................................................................................................. 12
5. Presupuesto............................................................................................................. 15
6. Conclusiones............................................................................................................ 15
7. Anexo código placa esclavo..................................................................................... 16
8. Anexo código placa maestro ................................................................................... 22
2
1. INTRODUCCIÓN
DSEM (Diseño de Sistemas Móviles y Empotrados) es una de las optativas de la
ingeniería técnica de telecomunicaciones, en la cual hemos aprendido a desarrollar
aplicaciones para PDA’s, teléfonos móviles y además a programar en un nuevo
lenguaje para nosotros, Processing. Es un lenguaje basado en Java, pero de mucho mas
alto nivel, es decir, mucho mas entendible para el usuario, ya que no utiliza un código
demasiado complejo. Este lenguaje nació precisamente para que gente poco
habituada a la programación pudiera realizar proyectos de un cierto grado de
complejidad. A partir de haber descubierto esta nuevo tipo de lenguaje y su facilidad
para la programación, habiendo realizado una serie de pruebas, estudio de librerías y
diferentes tipos de programas realizados por variedad de programadores, conocimos
la programación Wiring, muy similar a Processing, pero con un dispositivo hardware
por en medio. Este dispositivo hardware consta principalmente de una placa donde
tenemos una BIOS donde cargamos el código del programa, puertos de entrada/salida,
entrada USB, para conectar con el ordenador y una entrada para la alimentación
después de aprender el funcionamiento de Wiring se decidió realizar un proyecto final
de asignatura basado en este lenguaje.
Para ello y tras una selección de diferentes propuestas de proyectos, decidimos
elaborar el proyecto sobre un juego tradicional, “Simón Dice”. Este juego trata de
seguir la secuencia de colores, pulsando el botón adecuado a cada color, en el que
además incluye la opción de dos jugadores. A priori, parece que no tiene gran
complejidad, pero como veremos mas adelante, tiene mas de la que parece. Para
hacer este proyecto mas atractivo, y como el mismo nombre de la asignatura indica,
decidimos realizar todo el montaje del proyecto, es decir, tanto la parte de
programación como mecánica, la construcción física del aparato a partir de la placa
Wiring.
3
2. DISEÑO ANALÓGICO
Antes de empezar a elaborar todo el proyecto, empezamos a tomar ideas para realizar
el diseño del aparato en cuestión que el usuario debería tener para poder jugar.
El diseño en estaría basado en una caja de metraquilato donde colocaríamos la placa
Wiring y toda la electrónica que necesitáramos. Esta caja debe tener unas dimensiones
adecuadas para que dentro de ella cupiera la placa, circuitería interna, una pequeña
fuente de alimentación en forma de pila. En un principio la caja no debía ser cerrada,
ya que los pulsadores deberían estar por fuera y necesitábamos tener la cara de arriba
libre, pero tras la adquisición de la caja cerrada, con la posibilidad de abrirla por la
parte superior, decidimos que sería una mejor opción hacer los agujeros en la tapa
para la colocación de los pulsadores. La caja en cuestión tiene las siguientes medidas
160mm de largo, 100mm de ancho y 50mm de alto.
Para el montaje de los pulsadores desde el principio teníamos en mente soldar cuatro
botones en las esquinas de una placa de baquelita de unos 35cmx35cm, con suficiente
espacio para poder pegarla en la parte superior de la caja de metraquilato de
exactamente 35cm. y colocar 4 led’s en el centro de la placa como muestra la figura 1,
haciendo así que la cabeza del led saliera dos milímetros por encima de la placa de
baquelita, y las dos patas por cada led por debajo, que quedarían dentro de la caja de
metraquilto. Una vez hecho esto, pensamos en una primera instancia sacar dos cables
por cada botón, pero al final fue una idea descartada, ya que era inviable la idea de
sacar 8 cables de los 4 botones mas las 8 patas de los led’s, por cada pulsador por falta
de espacio dentro de la caja, por lo tanto, decidimos unir las pistas de la placa de
metraquilato, uniendo así los cuatro botones en paralelo y sacar únicamente 3 cables
por cada pulsador mas las dos patas de cada led.
FIG. 1 Esquema pulsador
Una vez definido el esquema de este pulsador, decidimos colocar encima de los cuatro
botones, una placa de metraquilato de cada color y la uniríamos con pegamento.
Con lo que quedaría un prototipo como el de ver Fig. 2.
4
FIG. 2 Vista aérea del prototipo
Una vez realizado esto, teníamos que decidir como colocar de manera visible el nivel
de la partida elegida y el jugador activo en ese momento, para ello colocamos en
nuestro diseño, tres led`s indicando la dificultad. Un led encendido significa nivel fácil,
dos led’s encendidos, nivel medio, tres led`s encendidos significa nivel difícil. El jugador
que esta activo lo mostraría mediante un siete segmentos.
Fig. 3 Vista aérea del prototipo versión 2.
2.1.
Pulsadores
Empezamos cortando la placa de baquelita para realizar los pulsadores. Aquí tuvimos
el primer problema, ya que si cortábamos mal, la placa se rompería fácilmente, por lo
tanto no era posible cortar esta placa con tijeras, ni con cutex, así que al final optamos
por utilizar una Dremel, herramienta óptima para cortar, perforar este tipo de
material, de una manera limpia y segura.
Empezamos serrando cuadrados de baquelita de 30x 30, un total de 8. Una vez
cortados, tuvimos que realizar cuatro perforaciones por cada cuadrado de baquelita,
para introducir los led’s. Continuamos soldando los botones en las esquinas como
mostraba la Fig. 1, acto seguido, usando estaño creamos las pistas necesarias para
poder colocar los botones en paralelo y finalmente enganchamos los leds. En resumen,
de cada placa de baquelita nos salen 2 cables por led, un cable común para todos los
pulsadores y 2 cables que se unirán para el otro polo de los pulsadores.
5
Fig. 4 Esquema electrónico pulsador.
En la FIG. 4, se muestran en rojo las conexiones a los cables de salida. Estas 4 placas de
baquelita van pegadas con loctite a la caja del juego.
En la siguiente FIG. 5, se muestra el modo en el que van conectados los pulsadores en
la placa. De este modo conseguimos un ‘0’ o un ‘1’ lógico evitando el estado de alta
impedancia.
Fig. 5 Esquema electrónico pulsador individual.
Los 4 leds deben estar conectados en paralelo con una resistencia de valor resistivo
bajo y en serie.
Fig. 6 Esquema electrónico leds boton.
El resultado final se puede observar en la siguiente imagen (ver FIG. 7) :
6
Fig. 7 Fotografía pulsador final.
2.2. Caja
El montaje de la caja tiene menor complejidad que los pulsadores, ya que la caja de
metraquilatro ya estaba fabricada a medida, como hemos dicho anteriormente,
aprovechábamos la tapa de la caja para insertar los pulsadores, para ello perforamos la
caja con una Dremel en las cuatro posiciones indicadas en la Fig. 2 para marcarlas y
posteriormente hacer un agujero mucho mayor con una corona, con unas dimensiones
adecuadas inferior a los 30x30, para que la placa de baquelita no caiga dentro de la
perforación.
Una vez perforamos realizado este paso, queda enganchar los pulsadores y el
resultado es el siguiente (ver FIG. 8) :
Fig. 8 Fotografía montage botones.
7
Una vez realizados estos pasos, hicimos tres perforaciones para indicar el grado de
dificultad de la partida; Dos más para indicar cuál de los dos jugadores tiene el turno y
además un 7 segmentos para indicar las vidas restantes. En la misma caja, incluimos
un botón especial para seleccionar estos parámetros del juego.
3. Placa Wiring
El corazón de la placa lo integra un microcontrolador modelo ATMEGA128 del
fabricante ATMEL. Hemos extraido las características del datasheet que proporciona
este fabricante y son las siguientes:
Fig. 9 caracteristicas atmel128, 8-Bit microcontroller with 128KBytes In-System Programmable Flash.
8
La placa Wiring esta adaptada a este microcontrolador mediante un esquema
electrónico con las conexiones I/O realizadas mediante agrupaciones de pines, es
decir, PUERTOS. Tambien incluye una conexión USB para facilitar la conexión al PC y
con ello su programación, un led de power, un botón de reset, etc.
Fig. 10 Placa Wiring.








43 Pines digitales I/O.
5 Puertos digitales (8 bits por puerto).
8 Entradas analógicas (10 bits de resolución).
6 Salidas analógicas de Pulse Width Modulation PWM.
2 Puertos series.
2 Pines Two Wire Interface, más conocido como i2c.
8 Interrupciones externas.
Conector para alimentación, fuente 7-13 V a 800mA.
El entorno de programación consiste en un software de libre descarga y diseñado para
la programación de la placa Wiring. El lenguaje de programación utilizado es C pero
con unas series de librerías (ya integradas en el software) que facilitan la tarea. No
olvidemos que esta iniciativa esta enfocada a un publico no familiarizado con la
electrónica ni con programación.
9
Fig. 11 Entorno de programación wiring.
Tal como vemos en la FIG. 11 se trata de un software bastante sencillo comparado con
otros entornos de programación (Microsoft Visual Studio, MPLAB, …). Unicamente
disponemos de 7 botones: play (compila), stop, new, save, load, upload to I/O board
(grabar en placa wiring) y serial monitor (herramienta más próxima a un debuger).
4. Código
Nuestro programa se puede dividir en cuatro partes:
1. Variables globales: aquí se declaran aquellas variables que podemos utilizar en
cualquier momento del programa. También declaramos nombres a los pines a
utilizar.
2. Funciones: en esta parte del programa, definiremos todas aquellas funciones
que necesitaremos a lo largo del programa. Estas funciones puden ser llamadas
en la parte Loop y dentro de otras funciones.
3. Setup: esta parte consiste en la configuración de la placa, es decir,
estableceremos que pines serán de salida o de entrada y activaremos la
interfaz para los pines de comunicación.
4. Loop: es el equivalente al main() de cualquier lenguaje de programación, con la
diferencia que se ejectua en modo bucle infinito.
10
4.1. Funcionamiento del programa
Nuestro proyecto consiste en emular el juego conocido por todos como SIMON tanto
para 1 jugador como para 2 jugadores.
Cuando encendemos (conectamos alimentación) la placa wiring espera 10 segundos
para introducirle el número de jugadores, esto será indicado mediante ledPlayer1 en
pin 20 y ledPlayer2 en pin 21 usando el pulsador central conectado al pin 19. Si
queremos jugar en modo multijador debemos establecer player 2 en las dos placas.
Sino cada placa funcionaran de manera independiente.
El siguiente paso consiste en elegir el modo de dificultad deseada. Hemos programa
tres niveles de dificultad para un máximo de 10 turnos. Disponemos de otros 10
segundos para elegir modo mediante el mismo pulsador central (pin19) y se visualiza
mediante tres leds conectados a los pines 16, 17, 18.
A continuación describimos las cabeceras de las funciones:
 int seleccionaplayer();
 int seleccionadificultad();
 int hazturno(int turnos, int aleatorio[],int error);
 void apagarLEDS();
 void leeentrada(int vectoruser[],int turnos);
 void muestravector(int vector[],int turnos);
 int comparavector(int vector_random[], int vector_user[], int turnos);
 void segmentos_off();
 void segmentos_on(int number);
 void receiveEvent(int howMany);
 void requestEvent();
4.2. Modo 1 player
. . .
if(prueva==0)
{
player=seleccionaplayer();
}
if (player==1)
{
for(i=0;i<30;i++)
{
aleatorio[i]=random(8,12);
}
dificultad=seleccionadificultad();
for(turnos=1;turnos<10*dificultad;turnos++)
{
aux=hazturno(turnos*dificultad,aleatorio,aux);
if (aux==1)
turnos=0;
}
}
. . .
Fig. 12 Extracto de código modo 1player.
Este extracto de código es para el modo 1 jugador y pertenece a la parte “void loop()”.
Primero llamamos a la función “int seleccionplayer()” que nos devuelve el resultado de
11
elegir player 1. Segundo generamos el vector “int aleatorio*30+” y mediante la función
“random(8,12)”. Recordemos que el ledAzul corresponde al pin 8, el ledVerde al pin 9,
el ledRojo al pin 10 y el ledAmarillo al pin11.
El tercer paso consiste en llamar a la función “int seleccionadificultad()” que nos
devuelve el nivel de dificultad elegido.
Una vez elegido el player 1 y el nivel de dificultad comienza el juego. El turno lo
controlamos mediante un bucle “for(turnos=1;turnos<10*dificultad;turnos++)”, la
función “int hazturno(int turnos, int aleatorio*+,int aux)” es la que se encarga de
realizar el juego: muestra el vector aleatorio, recoge el botón pulsado, muestra la
secuencia pulsada por el player y comprueba si es correcto sino lo es devuelve un
auxiliar y parpadean los 4 leds tres veces consecutivas. Por supuesto el juego se
reinicia.
A continuación mostramos el código de la función “hazturno(,,,)” ya que es la principal:
int hazturno(int turnos, int aleatorio[],int error)
{
int n;
int vectoruser[30];
muestravector(aleatorio,turnos);
leeentrada(vectoruser,turnos);
muestravector(vectoruser,turnos);
error=comparavector(aleatorio,vectoruser,turnos);
if(error==1)
{
for(n=0;n<3;n++)
{
digitalWrite(ledAZUL,HIGH);
digitalWrite(ledVERDE,HIGH);
digitalWrite(ledROJO,HIGH);
digitalWrite(ledAMARILLO,HIGH);
delay(200);
digitalWrite(ledAZUL,LOW);
digitalWrite(ledVERDE,LOW);
digitalWrite(ledROJO,LOW);
digitalWrite(ledAMARILLO,LOW);
delay(200);
}
}
return(error);
}
Fig. 13 Extracto del código de la función “int hazturno(int turnos, in t aleatorio[],int error)
4.3. Modo 2 player
Esta ha sido la parte mas conflictiva del proyecto. Las placas wiring disponen de 2
puertos tipo serie para comunicarse con hardware externo (PC junto a processing),
estos puertos se configuran en la parte “vodi setup()” del siguiente modo (ver FIG. 14):
12
Void setup()
{
Serial.begin(9600); //puerto serie USB o pines 37 y 36
Serial1.begin(9600);// puerto serie pins 3 (Rx) y 4 (Tx)
. . .
}
Void loop()
{
. . .
Int val = Serial1.read();//para Rx
Serial1.print(val);//para Tx
. . .
}
Fig. 14 Código puerto serie.
En un primera versión se intento el puerto serie descrito en la FIG. 14 pero no fue
posible enviar y recibir debido a una falta de sincronismo entre las dos placas. Este
módo está más indicado para enviar info al PC y mediante software Procesing capturar
estos datos para un procesado en PC.
Una vez descartada esta posibilidad, la otra librería que nos proporciona el entorno
Wiring para comunicación entre placas es el interfaz llamado TWI (Two Wire Interface)
que usa el nombre Wire y los pines 0 (SCL) y 1 (SDA). Este interfaz es conocido por los
electrónicos como i2c. Se establece un dispositivo como master y los demás
dispositivos (pueden ser varios) como esclavos. Como contrapartida, hay que aclarar
que los códigos de cada placa son diferentes (una para la placa maestra ver Fig. 16 y
otra esclava ver FIG. 15).
Void setup()
{
Wire.begin(2); //dispositivo esclavo con identificador 2
Wire.onRequest(requestEvent); // evento petición tx esclavomaster
Wire.onReceive(receiveEvent); // evento comunicación masteresclavo
. . .
}
Void loop()
{
. . .
if(player==2)
{
if(prueva==0)
{
dificultad=seleccionadificultad();
prueva=1;
}
if(aviso==1)
{
int turnosaux=0;
turnos++;
turnosaux=turnos*dificultad;
error=hazturno(turnosaux,aleatorio,error);
delay(500);
turnos++;
aviso=0;
digitalWrite(pinslave,HIGH);//pin para indicar a master que has
terminado turno, y le toca a el.
}
}
}
void receiveEvent(int howMany)
{
int i=0;
int error=0;
if(primero==0)
{
13
while(1<Wire.available())
{
aleatorio[i] = Wire.receive();// recibe vector aleatorio de master.
i++;
}
}
}
void requestEvent()
{
aviso=1;
digitalWrite(pinslave,LOW); //pin para indicar a master que estas
haciendo el turno (esclavo).
Wire.send(error); // responde al master con el envio variable error.
}
Fig. 15 Exctracto código TWI dispositivo esclavo.
Void setup()
{
Wire.begin();//dispositivo como maestro.
. . .
}
Void loop()
{
. . .
if(player==2)
{
int error=0;
dificultad=seleccionadificultad();
Wire.beginTransmission(2);//comenzamos transmisión al dispositivo 2.
for(i=0;i<30;i++)
{
Wire.send(aleatorio[i]);//enviamos aleatorio al esclavo
}
Wire.endTransmission();//cerramos la conexión
while(turnos<10)
{
if(aviso==0)
{
error=hazturno(turnos*dificultad,aleatorio,error);
Wire.requestFrom(2,2);//solicitamos envio del esclavo.
error=Wire.receive();
aviso=1;
turnos=turnos+2;
}
else
{
if(digitalRead(pinslave)==HIGH)//si es cierto le toca turno a master
aviso=0;
}
}
}
}
FIG. 16 Extracto código TWI dispositivo maestro.
Hemos tenido que utilizar la ayuda de un pin auxiliar llamado pinslave y conectado al
pin 7. En modo INPUT en código maestro y OUTPUT en en código esclavo. Con este pin
hemos establecido un sistema de turnos mediante la variable “int aviso”.
Cuando queremos enviar info desde el master al esclavo utilizamos la función
“Wire.send(aleatorio*i+)”, se genera un evento en la placa esclavo con nombre “void
receiveEvent(int howMany)” que se encarga de rellenar el vector aleatorio generado
en placa master.
Para solictar info desde el esclavo al master utilizamos la función
“Wire.requestFrom(2,2)” donde el primer 2 indica el dispositivo al que pedimos la info
14
y el segundo 2 indica el tamaño en bytes que esperamos recibir. En el código esclavo
se atiende al evento con “void requestEvent()” activamos pinslave a valor HIGH cuando
finaliza el turno en esclavo.
Para dicha comunicación vamos a utilizar tres pines, el pin 0, el pin 1 y el pin 7.
Los códigos completos se pueden consultar en el anexo, al final de este documento.
5. Presupuesto
Componentes
2 Bolsas 36 Pins conexion
Pila Alcalina 9v
Clip portapilas 9v
Pulsador grande start
Resistencias, Leds, Condensadores,
Pulsadores,…
Caja metraquilato con tapa 160x1
Placas metraquilato redondas o cuadradas
(4 unidades de 4)
Conectores alimentación
1 Placa de baquelita
1 metro cable rectil
TOTAL:
Precio un simon
2.28€
4.59€
0.16€
0.68€
GRATIS
Precio dos simon
4.56€
9.18€
0.32€
1.36€
GRATIS
16€
3.7€
32€
7.40€
0.14€
4.75€
1.30€
0.28€
9.5€
2.60€
23.28€
47.7€
Tabla 1 Presupuesto proyecto.
El coste total para realizar un simon es de 23.28€ y el doble 47.7€ en el caso de
implementar los dos simon.
Lo más caro del presupuesto es la caja de metraquilato donde vamos a alojar las placas
Wiring con un precio de 16€ la unidad. Existen toda una serie de componentes que no
son necesarios comprar, ya que como estudiantes de Ing. Telecos disponemos de
resistencias, leds, condensadores, cables, pulsadores,… de asignaturas anteriores.
Tienda consultada: Diotronic.
La caja de metraquilato es de color transparente y dispone de una tapa en la parte
superior facilitando la manipulación del contenido. Tienda consultada: Servei Estació.
6. Conclusiones
Es la primera vez que nos enfrentamos a un proyecto que incluya software y hardware.
El entorno Wiring nos ha proporcionado el conocimiento de un nuevo lenguaje
bastante intuitivo (poco complejo) y de muy alto nivel, ya que se basa en el uso de
librerías proporcionadas por Wiring.
El diseño analógico no ha sido nada trivial, ya que hemos tenido que realizar diversas
pruebas desde cero (variación del esquema electrónico inicial).
Realizar el hardware en cajas de metraquilato con la ayuda de una dremel ha sido un
proceso muy laborioso y costos en términos de horas.
15
Como conclusión destacar que es un proyecto para realizar en grupo de cuatro
personas, como mínimo. Y es necesario una cordinación entre miembros P2P.
Eso sí, nos hemos divertido, hemos disfrutado y hemos alcanzado la mitad de objetivos
propuestos: una caja de metraquilato y placa protoboard, modo un jugador y modo
dos jugadores. Nos ha faltado tiempo para añadirle el BCD 7 segmentos para indicar
turnos y sonido a cada botón.
7. Anexo código placa esclavo
int prueva=0;
int aviso=0;
int error=0;
int player = 1;
int dificultad=1;
int turnos=1;//variable global para el numero de turnos (maximos 10 turnos)
int ledAZUL=8;//8
int ledVERDE=9;//9
int ledROJO=10;//10
int ledAMARILLO=11;//11
int botonAZUL=12;//12
int botonVERDE=13;//13
int botonROJO=14;//14
int botonAMARILLO=15;//15
int ledSTART=23;
int ledplayer1=20;
int ledplayer2=21;
//int vectoruser[30]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int aleatorio[30]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ledDificultad1=16;
int ledDificultad2=17;
int ledDificultad3=18;
int botonDificultad=19;
int pinslave=7;
int primero=0;
//int ruido=0;
void receiveEvent(int howMany)
{
int i=0;
int error=0;
if(primero==0)
{
while(1<Wire.available())
{
aleatorio[i] = Wire.receive();
// receive byte as an integer
//Serial.print(aleatorio[i]);
i++;
}
}
}
void requestEvent()
{
aviso=1;
digitalWrite(pinslave,LOW);
Wire.send(error); // respond with message of 6 bytes
}
int seleccionaplayer()
{
int dif=0;//variable para leds dificultad
int aux=1;//variable para nivel dificultad.
int time1=(int)(millis());//variable milisegundos tiempo de la aplicación
ejecutada
int time=time1;
digitalWrite(ledplayer1,HIGH);
16
while(time<time1+10000)//10 segundos para elegir modo de dificultad.
{
if(digitalRead(botonDificultad)==HIGH)
{
delay(500);
if(digitalRead(botonDificultad)==LOW)
{
dif++;
if(dif==1)//dificultad facil, se avanza de uno en uno.
{
digitalWrite(ledplayer1,HIGH);
digitalWrite(ledplayer2,LOW);
aux=1;
}
if(dif==2)//difultad dificil, se avanza de tres en tres.
{
digitalWrite(ledplayer2,HIGH);
dif=0;
aux=2;
}
}
}
time=(int)millis();
}
return(aux);
}
int seleccionadificultad()
{
int dif=0;//variable para leds dificultad
int aux=1;//variable para nivel dificultad.
int time1=(int)(millis());//variable milisegundos tiempo de la aplicación
ejecutada
int time=time1;
digitalWrite(ledDificultad1,HIGH);
while(time<time1+10000)//10 segundos para elegir modo de dificultad.
{
if(digitalRead(botonDificultad)==HIGH)
{
delay(500);
if(digitalRead(botonDificultad)==LOW)
{
dif++;
if(dif==1)//dificultad facil, se avanza de uno en uno.
{
digitalWrite(ledDificultad1,HIGH);
digitalWrite(ledDificultad2,LOW);
digitalWrite(ledDificultad3,LOW);
aux=1;
}
if(dif==2)//difucltad media, se avanza de dos en dos.
{
digitalWrite(ledDificultad2,HIGH);
digitalWrite(ledDificultad3,LOW);
aux=2;
}
if(dif==3)//difultad dificil, se avanza de tres en tres.
{
digitalWrite(ledDificultad3,HIGH);
dif=0;
aux=3;
}
}
}
time=(int)millis();
}
17
return(aux);
}
int hazturno(int turnos, int aleatorio[],int error)
{
int n;
int vectoruser[30];
Serial.println("ANTES");
muestravector(aleatorio,turnos);
Serial.println(aleatorio[0]);
leeentrada(vectoruser,turnos);
muestravector(vectoruser,turnos);
error=comparavector(aleatorio,vectoruser,turnos);
if(error==1)
{
for(n=0;n<3;n++)
{
digitalWrite(ledAZUL,HIGH);
digitalWrite(ledVERDE,HIGH);
digitalWrite(ledROJO,HIGH);
digitalWrite(ledAMARILLO,HIGH);
delay(200);
digitalWrite(ledAZUL,LOW);
digitalWrite(ledVERDE,LOW);
digitalWrite(ledROJO,LOW);
digitalWrite(ledAMARILLO,LOW);
delay(200);
}
}
return(error);
}
void apagarLEDS()
{
digitalWrite(ledAZUL,LOW);
digitalWrite(ledVERDE,LOW);
digitalWrite(ledROJO,LOW),
digitalWrite(ledAMARILLO,LOW);
}
void leeentrada(int vectoruser[],int turnos)
{
int i;
for ( i=0;i<turnos;i++)
{
if( digitalRead(botonAZUL)==HIGH )
{
delay(50);
if(digitalRead(botonAZUL)==LOW)
{
vectoruser[i]=8;
continue;
}
}
if( digitalRead(botonVERDE)==HIGH )
{
delay(50);
if(digitalRead(botonVERDE)==LOW)
{
vectoruser[i]=9;
continue;
}
}
if( digitalRead(botonROJO)==HIGH )
{
delay(50);
if(digitalRead(botonROJO)==LOW)
18
{
vectoruser[i]=10;
continue;
}
}
if( digitalRead(botonAMARILLO)==HIGH )
{
delay(50);
if(digitalRead(botonAMARILLO)==LOW)
{
vectoruser[i]=11;
continue;
}
}
i--;
}
}
void muestravector(int vector[],int turnos)
{
int i;
int t=(int)millis();
for(i=0;i<turnos;i++)
{
digitalWrite(vector[i],HIGH);
delay(500);
digitalWrite(vector[i],LOW);
delay(500);
}
}
int comparavector(int vector_random[], int vector_user[], int turnos)
{
int n;
int a=0;
for(n=0;n<turnos;n++)
{
if(vector_random[n]!=vector_user[n])
a=1;
}
return a;
}
void segmentos_off()//funcion q apaga el 7segmentos
{
for(int i=0; i<8; i++)
{
digitalWrite(i, HIGH);
}
}
void segmentos_on(int number)//funcion para el 7segmentos
{
if(number==0)
{
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(0, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==1)
{
digitalWrite(5, LOW);
digitalWrite(3, LOW);
}
if(number==2)
19
{
digitalWrite(7,
digitalWrite(4,
digitalWrite(6,
digitalWrite(0,
digitalWrite(1,
HIGH);
HIGH);
HIGH);
HIGH);
HIGH);
}
if(number==3)
{
digitalWrite(4, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==4)
{
digitalWrite(5, HIGH);
digitalWrite(4, HIGH);
digitalWrite(7, HIGH);
digitalWrite(2, HIGH);
}
if(number==5)
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(7, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==6)
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(0, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==7)
{
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(2, HIGH);
}
if(number==8)
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(0, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==9)
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
delay(1000); // waits for 1000 milli seconds
//number = number + 1; // increments the variable to show
if(number > 9) { // check for the range, if greater then 9 goes back to 0s
number = 0;
20
}
}
void setup()
{
Serial.begin(9600);
//Serial1.begin(9600);
Wire.begin(2);
Wire.onRequest(requestEvent);
Wire.onReceive(receiveEvent);
pinMode(ledAZUL,OUTPUT);
pinMode(ledVERDE,OUTPUT);
pinMode(ledROJO,OUTPUT);
pinMode(ledAMARILLO,OUTPUT);
pinMode(botonAZUL,INPUT);
pinMode(botonVERDE,INPUT);
pinMode(botonROJO,INPUT);
pinMode(botonAMARILLO,INPUT);
pinMode(ledDificultad1,OUTPUT);
pinMode(ledDificultad2,OUTPUT);
pinMode(ledDificultad3,OUTPUT);
pinMode(botonDificultad,INPUT);
pinMode(ledSTART,OUTPUT);
pinMode(ledplayer1,OUTPUT);
pinMode(ledplayer2,OUTPUT);
pinMode(pinslave,OUTPUT);
//pinMode(ruido,OUTPUT);
}
void loop()
{
int i=0;
int n=0;
int aux=0;
int a;
int sound;
digitalWrite(ledSTART,HIGH);
//int prueva[10]={8,9,10,11,8,9,10,11,8,8};
if(prueva==0)
{player=seleccionaplayer();
Serial.println(player);
}
if (player==1)
{
for(i=0;i<30;i++)
{
aleatorio[i]=random(8,12);
}
dificultad=seleccionadificultad();
for(turnos=1;turnos<10*dificultad;turnos++)
{
aux=hazturno(turnos*dificultad,aleatorio,aux);
if (aux==1)
turnos=0;
}
}
if(player==2)
{
if(prueva==0)
{
dificultad=seleccionadificultad();
prueva=1;
21
}
if(aviso==1)
{
int turnosaux=0;
turnos++;
turnosaux=turnos*dificultad;
Serial.println(turnosaux);
error=hazturno(turnosaux,aleatorio,error);
delay(500);
turnos++;
aviso=0;
digitalWrite(pinslave,HIGH);
}
}
}
Fig. 17 Código completo placa wiring esclavo.
8. Anexo código placa maestro
int player = 1;
int aviso=0;
int dificultad=1;
int turnos=1;//variable global para el numero de turnos (maximos 10 turnos)
int ledAZUL=8;//8
int ledVERDE=9;//9
int ledROJO=10;//10
int ledAMARILLO=11;//11
int botonAZUL=12;//12
int botonVERDE=13;//13
int botonROJO=14;//14
int botonAMARILLO=15;//15
int ledSTART=23;
int ledplayer1=20;
int ledplayer2=21;
//int vectoruser[30]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int aleatorio[30]={0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
int ledDificultad1=16;
int ledDificultad2=17;
int ledDificultad3=18;
int botonDificultad=19;
int pinslave=7;
//int ruido=0;
int seleccionaplayer()
{
int dif=0;//variable para leds dificultad
int aux=1;//variable para nivel dificultad.
int time1=(int)(millis());//variable milisegundos tiempo de la aplicación
ejecutada
int time=time1;
digitalWrite(ledplayer1,HIGH);
while(time<time1+10000)//10 segundos para elegir modo de dificultad.
{
if(digitalRead(botonDificultad)==HIGH)
{
delay(500);
if(digitalRead(botonDificultad)==LOW)
{
dif++;
if(dif==1)//dificultad facil, se avanza de uno en uno.
{
digitalWrite(ledplayer1,HIGH);
digitalWrite(ledplayer2,LOW);
aux=1;
}
if(dif==2)//difultad dificil, se avanza de tres en tres.
{
22
digitalWrite(ledplayer2,HIGH);
dif=0;
aux=2;
}
}
}
time=(int)millis();
}
return(aux);
}
int seleccionadificultad()
{
int dif=0;//variable para leds dificultad
int aux=1;//variable para nivel dificultad.
int time1=(int)(millis());//variable milisegundos tiempo de la aplicación ejecutada
int time=time1;
digitalWrite(ledDificultad1,HIGH);
while(time<time1+10000)//10 segundos para elegir modo de dificultad.
{
if(digitalRead(botonDificultad)==HIGH)
{
delay(500);
if(digitalRead(botonDificultad)==LOW)
{
dif++;
if(dif==1)//dificultad facil, se avanza de uno en uno.
{
digitalWrite(ledDificultad1,HIGH);
digitalWrite(ledDificultad2,LOW);
digitalWrite(ledDificultad3,LOW);
aux=1;
}
if(dif==2)//difucltad media, se avanza de dos en dos.
{
digitalWrite(ledDificultad2,HIGH);
digitalWrite(ledDificultad3,LOW);
aux=2;
}
if(dif==3)//difultad dificil, se avanza de tres en tres.
{
digitalWrite(ledDificultad3,HIGH);
dif=0;
aux=3;
}
}
}
time=(int)millis();
}
return(aux);
}
int hazturno(int turnos, int aleatorio[],int error)
{
int n;
int vectoruser[30];
muestravector(aleatorio,turnos);
leeentrada(vectoruser,turnos);
muestravector(vectoruser,turnos);
error=comparavector(aleatorio,vectoruser,turnos);
if(error==1)
{
for(n=0;n<3;n++)
{
digitalWrite(ledAZUL,HIGH);
digitalWrite(ledVERDE,HIGH);
23
digitalWrite(ledROJO,HIGH);
digitalWrite(ledAMARILLO,HIGH);
delay(200);
digitalWrite(ledAZUL,LOW);
digitalWrite(ledVERDE,LOW);
digitalWrite(ledROJO,LOW);
digitalWrite(ledAMARILLO,LOW);
delay(200);
}
}
return(error);
}
void apagarLEDS()
{
digitalWrite(ledAZUL,LOW);
digitalWrite(ledVERDE,LOW);
digitalWrite(ledROJO,LOW),
digitalWrite(ledAMARILLO,LOW);
}
void leeentrada(int vectoruser[],int turnos)
{
int i;
for ( i=0;i<turnos;i++)
{
if( digitalRead(botonAZUL)==HIGH )
{
delay(50);
if(digitalRead(botonAZUL)==LOW)
{
vectoruser[i]=8;
continue;
}
}
if( digitalRead(botonVERDE)==HIGH )
{
delay(50);
if(digitalRead(botonVERDE)==LOW)
{
vectoruser[i]=9;
continue;
}
}
if( digitalRead(botonROJO)==HIGH )
{
delay(50);
if(digitalRead(botonROJO)==LOW)
{
vectoruser[i]=10;
continue;
}
}
if( digitalRead(botonAMARILLO)==HIGH )
{
delay(50);
if(digitalRead(botonAMARILLO)==LOW)
{
vectoruser[i]=11;
continue;
}
}
i--;
}
}
void muestravector(int vector[],int turnos)
{
24
int i;
for(i=0;i<turnos;i++)
{
digitalWrite(vector[i],HIGH);
delay(500);
digitalWrite(vector[i],LOW);
delay(500);
}
}
int comparavector(int vector_random[], int vector_user[], int turnos)
{
int n;
int a=0;
for(n=0;n<turnos;n++)
{
if(vector_random[n]!=vector_user[n])
a=1;
}
return a;
}
void segmentos_off()//funcion q apaga el 7segmentos
{
for(int i=0; i<8; i++)
{
digitalWrite(i, HIGH);
}
}
void segmentos_on(int number)//funcion para el 7segmentos
{
if(number==0)
{
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(0, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==1)
{
digitalWrite(5, LOW);
digitalWrite(3, LOW);
}
if(number==2)
{
digitalWrite(7, HIGH);
digitalWrite(4, HIGH);
digitalWrite(6, HIGH);
digitalWrite(0, HIGH);
digitalWrite(1, HIGH);
}
if(number==3)
{
digitalWrite(4, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==4)
{
digitalWrite(5, HIGH);
digitalWrite(4, HIGH);
digitalWrite(7, HIGH);
digitalWrite(2, HIGH);
25
}
if(number==5)
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(7, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==6)
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(0, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==7)
{
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(2, HIGH);
}
if(number==8)
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(0, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
if(number==9)
{
digitalWrite(4, HIGH);
digitalWrite(5, HIGH);
digitalWrite(6, HIGH);
digitalWrite(7, HIGH);
digitalWrite(1, HIGH);
digitalWrite(2, HIGH);
}
delay(1000); // waits for 1000 milli seconds
//number = number + 1; // increments the variable to show
if(number > 9) { // check for the range, if greater then 9 goes back to 0s
number = 0;
}
}
void setup()
{
Serial.begin(9600);
Serial1.begin(9600);
pinMode(ledAZUL,OUTPUT);
pinMode(ledVERDE,OUTPUT);
pinMode(ledROJO,OUTPUT);
pinMode(ledAMARILLO,OUTPUT);
pinMode(botonAZUL,INPUT);
pinMode(botonVERDE,INPUT);
pinMode(botonROJO,INPUT);
pinMode(botonAMARILLO,INPUT);
pinMode(ledDificultad1,OUTPUT);
pinMode(ledDificultad2,OUTPUT);
pinMode(ledDificultad3,OUTPUT);
pinMode(botonDificultad,INPUT);
pinMode(ledSTART,OUTPUT);
pinMode(ledplayer1,OUTPUT);
26
pinMode(ledplayer2,OUTPUT);
//pinMode(ruido,OUTPUT);
pinMode(pinslave,INPUT);
Wire.begin();
}
void loop()
{
int i=0;
int n=0;
int aux=0;
int a;
int sound;
digitalWrite(ledSTART,HIGH);
//int prueva[10]={8,9,10,11,8,9,10,11,8,8};
player=seleccionaplayer();
Serial.println(player);
for(i=0;i<30;i++)
{
aleatorio[i]=random(8,12);
}
if (player==1)
{
for(i=0;i<30;i++)
{
aleatorio[i]=random(8,12);
}
dificultad=seleccionadificultad();
for(turnos=1;turnos<10;turnos++)
{
aux=hazturno(turnos*dificultad,aleatorio,aux);
if (aux==1)
turnos=1;
}
}
if(player==2)
{
int error=0;
dificultad=seleccionadificultad();
Wire.beginTransmission(2);
for(i=0;i<30;i++)
{
Wire.send(aleatorio[i]);
}
Wire.endTransmission();
while(turnos<10)
{
if(aviso==0)
{
error=hazturno(turnos*dificultad,aleatorio,error);
Wire.requestFrom(2,2);
error=Wire.receive();
aviso=1;
turnos=turnos+2;
}
else
{
if(digitalRead(pinslave)==HIGH)
aviso=0;
}
//delay(3000*turnos*dificultad);
}
}
}
Fig. 18 Codigo completo placa wiring maestro.
27
Descargar