Matias Rodriguez
/
TP1-EJERCICIO3
TRABAJO PRACTICO - EJERCICIO 3 - TERMINADO
main.cpp
- Committer:
- matirodriguez
- Date:
- 2019-06-10
- Revision:
- 1:ad8aebd0e5c7
- Parent:
- 0:ec6eb1da0a1c
File content as of revision 1:ad8aebd0e5c7:
#include "mbed.h" #include "tsi_sensor.h" #define ELEC0 9 #define ELEC1 10 // Funcion enum que utilizo para usar palabras como valores (para mas claridad en el codigo) enum { HABILITADO, CABLE1, CABLE2, CABLE3, CABLE4, DISPONIBLE, USADO, DESHABILITADO, CORRECTO, VICTORIA, DERROTA }; // Funciones enum que indican el estado de las maquinas de estados enum { ESPERO_INICIO, CAMBIO_DISPLAY, RESTO_DISPLAY }; enum { PAUSA, ESPERO_CABLE, COMPARO }; enum { NADA, PULSADO }; enum { ESPERO, PRENDO, APAGO }; TSIAnalogSlider tsi(ELEC0, ELEC1, 40); // Prototipos de funciones de maquinas de estados void MAQ_cuentareg(); //Prototipo funcion de la cuenta regresiva void MAQ_bomba(); // Prototipo funcion general del juego void MAQ_parpadeo(); //Prototipo funcion para parpadear display y led void MAQ_lecturaTSI(); //Prototipo funcion para solo leer 1 vez que se presiona el TSI void LEER_TSI(); //Prototipo funcion para guardar el valor analogico del TSI en todo momento void pulsacion_TSI(); //Prototipo funcion para leer 1 solo valor del TSI cada 2.5mseg void segundos(); //Funcion para realizar cambiar el display cada 1 segundo void parpadeo1(); void parpadeo2(); void genero_secuencia(); // Funcion que utilizo para generar la secuencia aleatoria. //Variables que indican el estado de las maquinas (empiezo en estado de reset) int estado_maq_tsi = NADA; int estado_maq_display = ESPERO_INICIO; int estado_maq_bomba = PAUSA; int estado_maq_parpadeo = ESPERO; //Variables que habilitan maquinas de estados int hab_display = DESHABILITADO; //Variables que me indican el fin de una maquina de estados int fin_display = DESHABILITADO; int fin_juego = NADA; //Variables que acumulan datos int var_pulsacion = 25; // Variable para contar los 2.5mseg de la funcion pulsacion_TSI() int teclado = NADA; // Variable que contiene el valor analogico del TSI en todo momento int ingreso = NADA; // Variable que contiene si se presionó el TSI, que se lee y luego se borra int segundo = 100; // Variable que cuenta desde 100 hasta 0 para contar 1 segundo int tiempo = 60; // Variable que utilizo para establecer cuanto tiempo contar int secuencia[4]; // Variable que contiene la secuencia aleatoria int memoria1 = DESHABILITADO; int memoria2 = DESHABILITADO; Ticker lectura; // Ticker lectura del TSI Ticker pulsacion; // Ticker para usar la funcion pulsacion_TSI() Ticker cuenta; //Ticker para realizar la cuenta regresiva Timeout blink1; Timeout blink2; // DEFINO SALIDAS DigitalOut ledrojo(LED_RED); DigitalOut ledverde(LED_GREEN); BusOut decenas(PTA4,PTA5,PTC8,PTC9); // Salidas para el display de las decenas BusOut unidades(PTC7, PTC0, PTC3, PTC4); // Salidas para el display de las unidades // DEFINO ENTRADAS BusIn entradas(PTC12,PTC13,PTC16,PTC17); // Entradas donde estarán los cables a desconectar AnalogIn noise(PTB0); // Entrada que usaré para generar la secuencia aleatoria con el ruido que me genere int main(void) { entradas.mode(PullUp); // Coloco las entradas con un pullup interno // Uno las funciones con el ticker correspondiente lectura.attach(&LEER_TSI,0.1); pulsacion.attach(&pulsacion_TSI,0.001); cuenta.attach(&segundos,0.01); // Apago los leds al iniciar ledrojo = 1; ledverde= 1; // Pongo los displays en 0 (Se tienen que negar las salidas) decenas = 0 ^ 0xF; unidades = 0 ^ 0xF; while (true) { // Constantemente uso las maquinas de estados MAQ_lecturaTSI(); MAQ_cuentareg(); MAQ_bomba(); MAQ_parpadeo(); } } void MAQ_parpadeo() { int auxiliar; switch(estado_maq_parpadeo) { case ESPERO: if(fin_juego != NADA) { // Si el juego terminó, habilito la maquina de estados estado_maq_parpadeo = APAGO; blink1.attach(&parpadeo1,0.25); // Uso un Timeout para cambiar de estado una vez pasaron 0.25 segundos } break; case APAGO: unidades = 0; // Apago los displays decenas = 0; ledverde=0; // Prendo el led verde if(fin_juego == DERROTA) { ledrojo = 0; ledverde=1; } break; case PRENDO: auxiliar = tiempo / 10; decenas = auxiliar ^ (0xF); // Como utilizo salidas que se prenden con 0, invierto el numero. unidades = (tiempo - auxiliar * 10) ^ (0xF); if(fin_juego == DERROTA) { ledrojo = 1; } break; } } void parpadeo1() //Funcion que vinculo al timeout para cambiar de estado cada 0.25 segundos { if(fin_juego != NADA) { estado_maq_parpadeo = PRENDO; blink2.attach(&parpadeo2,0.25); } else { estado_maq_parpadeo = ESPERO; } } void parpadeo2() //Funcion que vinculo al timeout para cambiar de estado cada 0.25 segundos { if(fin_juego != NADA) { estado_maq_parpadeo = APAGO; blink1.attach(&parpadeo1,0.25); } else { estado_maq_parpadeo = ESPERO; } } void MAQ_bomba() { static int aux; static int nivel; static int diferencia; static int correctos[]= {NADA,NADA,NADA,NADA,NADA}; // Nada, C1, C2, C3, C4 switch(estado_maq_bomba) { case PAUSA: if(ingreso == PULSADO) { //Reseteo las variables ingreso = NADA; fin_juego = NADA; estado_maq_parpadeo = ESPERO; correctos[CABLE1] = NADA; correctos[CABLE2] = NADA; correctos[CABLE3] = NADA; correctos[CABLE4] = NADA; ledrojo = 1; //Apago los leds ledverde = 1; genero_secuencia(); //Genero la secuencia aleatoria nivel = 0; hab_display = HABILITADO; aux = entradas; estado_maq_bomba = ESPERO_CABLE; estado_maq_display = ESPERO_INICIO; } break; case ESPERO_CABLE: if(aux != entradas) { // Si se detecta una diferencia con respecto a un valor anterior en la entrada estado_maq_bomba = COMPARO; diferencia = (aux) ^ (entradas); // Guardo dicha diferencia en una variable } if(fin_display == HABILITADO) { // Si se termina el tiempo: fin_display = DESHABILITADO; ledrojo = 0; estado_maq_bomba = PAUSA; fin_juego = DERROTA; tiempo = 0; } break; case COMPARO: estado_maq_bomba = ESPERO_CABLE; switch(diferencia) { // Uso un switch para variar entre los casos de los cables que se sacaron //Uso una memoria para ver si el cable ya se retiro y no tenerlo mas en cuenta //Si el valor no corresponde, el jugador pierde case 0b0001: if(correctos[CABLE1]==NADA) { correctos[CABLE1]=CORRECTO; if(secuencia[nivel]!=CABLE1) { estado_maq_bomba = PAUSA; ledrojo = 0; estado_maq_display = ESPERO_INICIO; fin_juego = DERROTA; } else { nivel++; estado_maq_bomba = ESPERO_CABLE; aux = entradas; } } break; case 0b0010: if(correctos[CABLE2]==NADA) { correctos[CABLE2]=CORRECTO; if(secuencia[nivel]!=CABLE2) { estado_maq_bomba = PAUSA; ledrojo = 0; estado_maq_display = ESPERO_INICIO; fin_juego = DERROTA; } else { nivel++; estado_maq_bomba = ESPERO_CABLE; aux = entradas; } } break; case 0b0100: if(correctos[CABLE3]==NADA) { correctos[CABLE3]=CORRECTO; if(secuencia[nivel]!=CABLE3) { estado_maq_bomba = PAUSA; ledrojo = 0; estado_maq_display = ESPERO_INICIO; fin_juego = DERROTA; } else { nivel++; estado_maq_bomba = ESPERO_CABLE; aux = entradas; } } break; case 0b1000: if(correctos[CABLE4]==NADA) { correctos[CABLE4]=CORRECTO; if(secuencia[nivel]!=CABLE4) { estado_maq_bomba = PAUSA; ledrojo = 0; estado_maq_display = ESPERO_INICIO; fin_juego = DERROTA; } else { nivel++; estado_maq_bomba = ESPERO_CABLE; aux = entradas; } } break; } printf("%i\n",nivel); // Si nivel es 4 significa que el jugador ganó if(nivel == 4) { estado_maq_bomba = PAUSA; estado_maq_display = ESPERO_INICIO; fin_juego = VICTORIA; } if(fin_display == HABILITADO) {// Si el tiempo llego al final: ledrojo = 0; tiempo = 0; estado_maq_bomba = PAUSA; fin_display = DESHABILITADO; fin_juego = DERROTA; } break; } } void MAQ_cuentareg() { int auxiliar; switch(estado_maq_display) { case ESPERO_INICIO: if(hab_display == HABILITADO) { // Si se habilita, pongo el tiempo al maximo y cuento 60 segundos hab_display = DESHABILITADO; estado_maq_display = CAMBIO_DISPLAY; tiempo = 60; segundo=100; } break; case CAMBIO_DISPLAY: // Cambio el valor de los displays por el que corresponde al tiempo auxiliar = tiempo / 10; decenas = auxiliar ^ (0xF); unidades = (tiempo - auxiliar * 10) ^ (0xF); if(segundo == 0) { estado_maq_display = RESTO_DISPLAY; } break; case RESTO_DISPLAY: // Cada 1 segundo resto 1 valor al tiempo // Si el tiempo es menor a 0, marco como que se terminó la cuenta tiempo--; if(tiempo < 0) { estado_maq_display = ESPERO_INICIO; fin_display = HABILITADO; } else { estado_maq_display = CAMBIO_DISPLAY; segundo=100; } break; } } void segundos() { segundo--; } void LEER_TSI() { float auxiliar = 0; auxiliar = tsi.readPercentage(); //Guardo de manera auxiliar el valor entre 0 y 1 del TSI // Asocio el valor del tsi numerico con un color, dividiendo en 4 valores posibles (0, <0.33, <0.66, <1) if(auxiliar >= 0) { teclado = NADA; } if((auxiliar > 0.05)&&(auxiliar <= 1)) { teclado = PULSADO; } } void pulsacion_TSI() { if(var_pulsacion > 0) { var_pulsacion--; } } void MAQ_lecturaTSI() { if(var_pulsacion < 1) { // Si se llegaron a los 2.5ms: var_pulsacion = 25; // Vuelvo a establecer 2.5ms para el proximo ciclo switch(estado_maq_tsi) { case NADA: ingreso = NADA; // La variable ingreso, salvo en el caso especifico, siempre se encontrará en NADA if(teclado==PULSADO) { estado_maq_tsi = PULSADO; ingreso = PULSADO; // El valor del TSI lo cambio en la transicion entre estados para asegurarme que solo se pueda leer 1 vez } break; case PULSADO: if(teclado == NADA) { estado_maq_tsi = NADA; } break; } } } void genero_secuencia() { int auxiliar; // Variable que voy a usar para contener un numero aleatorio // Variables que uso para saber si el cable que intento establecer en la secuencia ya se usó anteriormente int cable1 = DISPONIBLE; int cable2 = DISPONIBLE; int cable3 = DISPONIBLE; int cable4 = DISPONIBLE; srand(int (noise * 10000)); // Cambio la semilla de la funcion rand usando un valor de ruido en una entrada analogica al aire for(int i = 0; i <=3 ; i++) { // Creo un for para recorreR las 4 posiciones de memoria del vector "secuencia[]" auxiliar = rand(); //Genero un valor aleatorio y lo guardo en mi variable auxiliar // Dependiendo de cuanto resto me de al dividir por 4, asignare ese valor aleatorio con un cable distinto // Si el cable que intento establecer en la secuencia se encuentra usado, resto un valor de "i" para volver a intentar // con otro valor aleatorio. // Este procedimiento se repite hasta que pueda llenar los 4 valores de la secuencia if((auxiliar % 4) == 0) { if(cable1 == DISPONIBLE) { secuencia[i] = CABLE1; cable1 = USADO; } else { i--; } } if((auxiliar % 4 ) == 1) { if(cable2 == DISPONIBLE) { secuencia[i] = CABLE2; cable2 = USADO; } else { i--; } } if((auxiliar % 4 ) == 2) { if(cable3 == DISPONIBLE) { secuencia[i] = CABLE3; cable3 = USADO; } else { i--; } } if((auxiliar % 4 ) == 3) { if(cable4 == DISPONIBLE) { secuencia[i] = CABLE4; cable4 = USADO; } else { i--; } } } // Muestro la secuencia en el puerto serie for(int i = 0; i<4; i++) { printf("%i",secuencia[i]); } printf("\n"); }