Gonzalo Martinez
/
TPBombaAguaDisplays
4 Cables con pulsadores y pull-up con 2 Displays en paralelo
main.cpp
- Committer:
- gonzaloMS
- Date:
- 2019-06-23
- Revision:
- 2:e7e06ee2d6b0
- Parent:
- 1:2f8c5940c425
File content as of revision 2:e7e06ee2d6b0:
//Tenemos 2 displays en paralelo, y manejamos cada uno por separado a través de sus habilitaciones (con transistores al corte y saturación) #include "mbed.h" //Creo los Estados para las Máquinas de Estados enum{INICIO,GENERA1,GENERA2,GENERA3,FIN,BEGINNING,CHECK1,CHECK2,CHECK3,ENDGAME,WINGAME}; // |----------------------------------|----------------------------------------------| // GENERACIÓN CHEQUEO DigitalIn E1r(PTC12); DigitalIn E2r(PTC13); // 0 1 2 3 (Entradas reales/físicas) DigitalIn E3r(PTC3); // E1r E2r E3r E4r DigitalIn E4r(PTC4); DigitalIn pulsadorReset(PTE29); //Pulsador externo para hacer reset, normalmente 1 DigitalOut ledWin(LED2); //Configuro Led RGB en verde para cuando ganás el juego DigitalOut ledLost(LED1); //Configuro Led RGB en rojo para cuando perdés el juego BusOut Displays(D2,D3,D4,D5,A3,A2,A1,A0,D8); //Salidas en este orden: HAB.2 (UNIDADES) - HAB.1 (DECENAS) - G - F - E - D - C - B - A respectivamente // int E1=0; int E2=0; //Variables donde se van a guardar los estados de las entradas reales (Ej.: E1r en E1) int E3=0; int E4=0; //Cada número del 0 al 9 en binario dentro de un vector, para después asignarlo al BusOut (El menos significativo acá es el más significativo del BusOut) int numerosD[]={0b111111010,0b011000010,0b110110110,0b111100110,0b011001110,0b101101110,0b101111110,0b111000010,0b111111110,0b111001110}; //0-9 Decenas int numerosU[]={0b111111001,0b011000001,0b110110101,0b111100101,0b011001101,0b101101101,0b101111101,0b111000001,0b111111101,0b111001101}; //0-9 Unidades //Inicializo Tickers que ejecutan una función cada cierto tiempo en segundos Ticker Tempo; Ticker Display; Ticker parpadeoTicker; //Funciones de cada Ticker respectivamente void descuentaTiempo(); //Cada 1 seg le resta 1 a una variable que lleva el tiempo. Al llegar a 0, indica a través de una variable que el jugador perdió void visualizacionDisplays(); //Genera Unidades y Decenas en base al tiempo. Maneja el BusOut que va a las patas de los displays para mostrar el tiempo void parpadeoFuncion(); //Hace que parpadee el led rojo cuando perdés y que parpadeen los segmentos de los displays cuando termine el juego //Funciones de las Máquinas de estados void generacion(); //Genera secuencia void chequeo(); //Chequea si el estado de las entradas concuerda con la secuencia generada //Funciones extra void winReaccion(); //Prende el led verde si ganás (desconectas todos los cables en el orden correcto) void reset(); //Si presionás el botón reset reinicia las variables necesarias, hace que las máquinas de estados vuelvan a empezar por su estado default y apaga los leds //Varible que se encarga de decidir cuándo mostrar las decenas y cuándo las unidades int switcheo=0; //Variables relacionadas con el tiempo que se muestra en los displays int tiempo=60; //Guarda el tiempo en segundos int Decenas; //Guarda solamente la unidad del tiempo int Unidades; //Guarda solamente la decena del tiempo //Variables en las que se guarda el estado de las máquinas de estados int secuencia; //Para la máquina de estados de generación de secuencia int check; //Para la máquina de estados de chequeo de las entradas //Variables que guardan cuántas de las entradas concuerdan con la secuencia generada int cantIgual=0; //Para cuando se corta un cable (1 entrada en 1, las otras 3 en 0) int cantIgual2=0; //Para cuando se corta el segundo cable (2 entradas en 1, las otras 2 en 0) int cantIgual3=0; //Para cuando se corta el tercer cable (3 entradas en 1, la otra en 0) //Variables donde se guardan valores random que van a determinar cómo queda la secuencia int genSec1; //primer cable a cortar int genSec2; //segundo cable a cortar int genSec3; //tercer cable a cortar //Vectores que guardan cada parte de la secuencia (que empieza en 0000 y termina en 1111) int vecSec[]={0,0,0,0}; //Primer cable a cortar int vecSec2[]={0,0,0,0}; //Segundo cable a cortar int vecSec3[]={0,0,0,0}; //Tercer cable a cortar int vecSec4[]={0,0,0,0}; //Cuarto cable a cortar //Vector que guarda el estado de las entradas para compararlo con los vectores que guardan la secuencia int vecChq[]={0,0,0,0}; //Variable que se queda en 0 si no tiene que parpadear el display y que alterna entre 1 y 0 constantemente en el caso contrario (0 muestra el tiempo y 1 apaga el display) int parpadeoDisplay=0; //Variables que informan si el jugador perdió o ganó el juego int fin=0; int win=0; //Variables para los "for" del programa int i; int y; int k; int main() { //Apago los Leds ledWin=1; ledLost=1; //Configuro modo de PullUp interno para las 4 entradas (los cuatro cables) y el botón de Reset E1r.mode(PullUp); E2r.mode(PullUp); E3r.mode(PullUp); E4r.mode(PullUp); pulsadorReset.mode(PullUp); //Asingo las funciones a los Tickers Tempo.attach(&descuentaTiempo,1); //La funcion descuentaTiempo se va a ejecutar cada 1 segundo Display.attach(&visualizacionDisplays,0.005); //La funcion visualizacionDisplays se va a ejecutar cada 5 milisegundos parpadeoTicker.attach(&parpadeoFuncion,0.5); //La funcion parpadeoFuncion se va a ejecutar cada 0,5 segundos while(1) { //Llamo a las funciones generacion(); chequeo(); winReaccion(); reset(); //Pongo los estados de las entradas en las variables E1=E1r; E2=E2r; E3=E3r; E4=E4r; } } void reset() { if(pulsadorReset==0) { //si se presiona el pulsador resetea todas las variables, los vectores (vuelven a empezar en 0000) y las máq. de estados empiezan por su estado default ledWin=1; ledLost=1; switcheo=0; cantIgual=0; cantIgual2=0; cantIgual3=0; vecSec[0]=0; vecSec[1]=0; vecSec[2]=0; vecSec[3]=0; vecSec2[0]=0; vecSec2[1]=0; vecSec2[2]=0; vecSec2[3]=0; vecSec3[0]=0; vecSec3[1]=0; vecSec3[2]=0; vecSec3[3]=0; vecSec4[0]=0; vecSec4[1]=0; vecSec4[2]=0; vecSec4[3]=0; vecChq[0]=0; vecChq[1]=0; vecChq[2]=0; vecChq[3]=0; parpadeoDisplay=0; tiempo=60; win=0; fin=0; secuencia=INICIO; check=BEGINNING; } } void winReaccion() { //Si el jugador ganó, se prende el led verde y se apaga el rojo if(win==1) { ledWin=0; ledLost=1; } } void parpadeoFuncion() { //Si el jugador perdió, cada 0,5 segundos que entra en la funcion cambia el estado del led rojo de 0 a 1 if(fin==1) { ledLost=!ledLost; } //Si el jugador perdió o ganó, cada 0,5 segundos que entra en la funcion va a cambiar entre 0 y 1 la variable que indica si se tiene que mostrar el tiempo o apagar los displays if(fin==1 || win==1) { parpadeoDisplay=!parpadeoDisplay; } } void descuentaTiempo() { //Si el juego no terminó, cada 1 segundo le resta 1 a la variable tiempo, que empieza en 60, hasta que llega a 0 e indica que el jugador perdió. //También cada 1 segundo muestra el estado de las variables importantes para el jugador para facilitar la depuración if(fin==0 && win==0) { if(tiempo>0) { tiempo--; } else { fin=1; } printf("A lograr: \n"); printf("%d %d %d %d \n",*vecSec,*(vecSec+1),*(vecSec+2),*(vecSec+3)); printf("%d %d %d %d \n",*vecSec2,*(vecSec2+1),*(vecSec2+2),*(vecSec2+3)); printf("%d %d %d %d \n",*vecSec3,*(vecSec3+1),*(vecSec3+2),*(vecSec3+3)); printf("%d %d %d %d \n",*vecSec4,*(vecSec4+1),*(vecSec4+2),*(vecSec4+3)); printf("Entradas: %d %d %d %d \n", E1,E2,E3,E4); printf("Tiempo (en segundos): %d \n \n",tiempo); } } void visualizacionDisplays() { //Consigo el numero perteneciente a las decenas del tiempo y lo guardo en la variable. Lo mismo para las unidades del tiempo Decenas=tiempo/10; Unidades=tiempo-((tiempo/10)*10); //Si no tiene que parpadear el display, va cambiar entre mostrar las decenas y unidades cada 5 milisegundos que entra a la funcion //Si tiene que parpadear, parpadeoDisplay cambia entre 0 y 1, mostrando el tiempo en un momento y apagando los displays en otro if(parpadeoDisplay==0) { //Si switcheo es par, muestra decenas, y si es impar, muestra unidades. La posicion 0 del vector corresponde al numero 0, y así hasta el 9 if(switcheo%2==0) { Displays=numerosD[Decenas]; } else { Displays=numerosU[Unidades]; } } else { Displays=0; } //Como no importa el número en sí, para que no se haga muy grande para en 200 y vuelve a 0 if(switcheo==200) { switcheo=0; } //switcheo aumenta en 1 cada vez que se entra a la funcion switcheo++; } void generacion(){ switch(secuencia) { default: case INICIO: //Se reinician las variables que se encargan de generar la secuencia genSec1=0; genSec2=0; genSec3=0; //Pasa directamente al estado GENERA1 secuencia=GENERA1; break; case GENERA1: //Se le asigna un valor random entre 1 y 4 a la variable genSec1 genSec1=rand()%4+1; //Dependiendo del valor, se le suma 1 a 1 de las 4 posiciones del vector if(genSec1==1) { vecSec[0]++; } else if(genSec1==2) { vecSec[1]++; } else if(genSec1==3) { vecSec[2]++; } else if(genSec1==4) { vecSec[3]++; } //Pasa directamente al estado GENERA2 secuencia=GENERA2; break; case GENERA2: //Se le asigna un valor random entre 1 y 4 a la variable genSec2 genSec2=rand()%4+1; //Se copia el contenido del vector de la primera parte de la secuencia al del vector de la segunda parte de la secuencia vecSec2[0]=vecSec[0]; vecSec2[1]=vecSec[1]; vecSec2[2]=vecSec[2]; vecSec2[3]=vecSec[3]; //Dependiendo del valor, se le suma 1 a 1 de las 4 posiciones del vector, excepto que la posicion a la que busca sumar 1 ya sea 1 de la generacion anterior //Si la posicion ya era 1 de antes, se vuelve a hacer el proceso (que incluye volver a generar un número random) if(genSec2==1) { if(vecSec2[0]==1) { secuencia=GENERA2; } else { vecSec2[0]++; } } else if(genSec2==2) { if(vecSec2[1]==1) { secuencia=GENERA2; } else { vecSec2[1]++; } } else if(genSec2==3) { if(vecSec2[2]==1) { secuencia=GENERA2; } else { vecSec2[2]++; } } else if(genSec2==4) { if(vecSec2[3]==1) { secuencia=GENERA2; } else { vecSec2[3]++; } } //Se busca verificar que el vector de la segunda parte de la secuencia contenga dos posiciones en 1. En ese caso, pasa al estado GENERA3 //Sino vuelve a hacer el proceso if((vecSec2[0]+vecSec2[1]+vecSec2[2]+vecSec2[3]) == 2) { secuencia=GENERA3; } else { secuencia=GENERA2; } break; case GENERA3: //Se le asigna un valor random entre 1 y 4 a la variable genSec3 genSec3=rand()%4+1; //Se copia el contenido del vector de la segunda parte de la secuencia al del vector de la tercera parte de la secuencia vecSec3[0]=vecSec2[0]; vecSec3[1]=vecSec2[1]; vecSec3[2]=vecSec2[2]; vecSec3[3]=vecSec2[3]; //Dependiendo del valor, se le suma 1 a 1 de las 4 posiciones del vector, excepto que la posicion a la que busca sumar 1 ya sea 1 de la generacion anterior //Si la posicion ya era 1 de antes, se vuelve a hacer el proceso (que incluye volver a generar un número random) if(genSec3==1) { if(vecSec3[0]==1) { secuencia=GENERA3; } else { vecSec3[0]++; } } else if(genSec3==2) { if(vecSec3[1]==1) { secuencia=GENERA3; } else { vecSec3[1]++; } } else if(genSec3==3) { if(vecSec3[2]==1) { secuencia=GENERA3; } else { vecSec3[2]++; } } else if(genSec3==4) { if(vecSec3[3]==1) { secuencia=GENERA3; } else { vecSec3[3]++; } } //Se busca verificar que el vector de la tercera parte de la secuencia contenga tres posiciones en 1. En ese caso, pasa al estado FIN //Sino vuelve a hacer el proceso if((vecSec3[0]+vecSec3[1]+vecSec3[2]+vecSec3[3]) == 3) { secuencia=FIN; } else { secuencia=GENERA3; } break; case FIN: //Termina con todas las posiciones en 1. Se mantiene en este estado hasta que se presione el botón de reset vecSec4[0]=1; vecSec4[1]=1; vecSec4[2]=1; vecSec4[3]=1; secuencia=FIN; break; } } void chequeo(){ switch(check) { default: case BEGINNING: //Si todas las entradas están conectadas (ningún cable sin cortar), se queda en este estado, sino cambia a CHECK1 if(E1!=0 || E2!=0 || E3!=0 || E4!=0) { check=CHECK1; } else { check=BEGINNING; } break; case CHECK1: //El estado de las entradas al "desconectar" una se guarda en los vectores vecChq[0]=E1; vecChq[1]=E2; vecChq[2]=E3; vecChq[3]=E4; //Se fija si el estado de las 4 entradas corresponde con la secuencia al desconectar solo una de las entradas for(i=0;i<4;i++) { if(vecSec[i]==vecChq[i]) { cantIgual++; } } //Si solo se desconectó una y era la que debía ser según la secuencia, se vuelve a hacer el proceso. Si era una incorrecta, perdiste el juego if((vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==1) { if(cantIgual!=4) { check=ENDGAME; } else { cantIgual=0; check=CHECK1; } } //Si la primera que se había desconectado era la correcta y se desconecta otra más, pasa al estado CHECK2 else if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==2) { check=CHECK2; } break; case CHECK2: //El estado de las entradas al desconectar la segunda se guarda en los vectores vecChq[0]=E1; vecChq[1]=E2; vecChq[2]=E3; vecChq[3]=E4; //Se fija si el estado de las 4 entradas corresponde con a la secuencia al desconectar la segunda entrada for(y=0;y<4;y++) { if(vecSec2[y]==vecChq[y]) { cantIgual2++; } } //Si al desconectar la segunda entrada era la que debía ser según la secuencia, se vuelve a hacer el proceso. Si era una incorrecta, perdiste el juego if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==2) { if(cantIgual2!=4) { check=ENDGAME; } if(cantIgual==4) { check=CHECK2; } } //Si la segunda que se había desconectado era la correcta y se desconecta otra más, pasa al estado CHECK3 else if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==3) { check=CHECK3; } break; case CHECK3: //El estado de las entradas al desconectar la tercera se guarda en los vectores vecChq[0]=E1; vecChq[1]=E2; vecChq[2]=E3; vecChq[3]=E4; //Se fija si el estado de las 4 entradas corresponde con a la secuencia al desconectar la tercera entrada for(k=0;k<4;k++) { if(vecSec3[k]==vecChq[k]) { cantIgual3++; } } //Si al desconectar la tercera entrada era la que debía ser según la secuencia, se vuelve a hacer el proceso. Si era una incorrecta, perdiste el juego if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==3) { if(cantIgual3!=4) { check=ENDGAME; } if(cantIgual3==4) { check=CHECK3; } } //Si la tercera que se había desconectado era la correcta y se desconecta la última, evidentemente es la correcta y ganaste el juego else if(vecChq[0]+vecChq[1]+vecChq[2]+vecChq[3])==4) { check=WINGAME; } break; case ENDGAME: //Indica que se perdió el juego fin=1; check=ENDGAME; break; case WINGAME: //Indica que se ganó el juego win=1; check=WINGAME; break; } }