![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
TRABAJO PRACTICO - EJERCICIO 3 - TERMINADO
Revision 1:ad8aebd0e5c7, committed 2019-06-10
- Comitter:
- matirodriguez
- Date:
- Mon Jun 10 18:01:52 2019 +0000
- Parent:
- 0:ec6eb1da0a1c
- Commit message:
- EJERCICIO 3 TERMINADO
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Wed May 29 22:19:14 2019 +0000 +++ b/main.cpp Mon Jun 10 18:01:52 2019 +0000 @@ -4,84 +4,387 @@ #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_lecturaTSI(); +void MAQ_bomba(); // Prototipo funcion general del juego -void LEER_TSI(); //Prototipo funcion de lectura del TSI +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 tiempo = 0; // Variable para contar el 1 segundo para el encendido y apagado de leds int var_pulsacion = 25; // Variable para contar los 2.5mseg de la funcion pulsacion_TSI() -int teclado = NADA; // Variable que contiene el valor del TSI en todo momento -int ingreso = NADA; // Variable que contiene el color presionado en el TSI, que se lee y luego es borrado +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 temporizador; // Ticker para contar 1 segundo en los leds 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(); - if(ingreso != NADA) { - - ingreso = NADA; - if(ledverde == 0) { - - - - - - ledrojo=0; - } - if((ledverde==1)&&(ledrojo==1)) { - ledverde=0; - } - ledrojo=1; - } + 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; @@ -107,15 +410,16 @@ 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 los casos especificos, siempre se encontrará en NADA + ingreso = NADA; // La variable ingreso, salvo en el caso especifico, siempre se encontrará en NADA - // En vez de usar cadenas de if en las transiciones, utilizo un switch if(teclado==PULSADO) { estado_maq_tsi = PULSADO; - ingreso = PULSADO; + ingreso = PULSADO; // El valor del TSI lo cambio en la transicion entre estados para asegurarme que solo se pueda leer 1 vez } break; @@ -126,4 +430,65 @@ 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"); } \ No newline at end of file