Este es el Ejercicio 3 del TP Nº1 de Sistemas Embebidos. El objetivo del programa es mejorar el funcionamiento de una cafetera "ATMA CA8180"
Dependencies: DS1820 antirrebote matriz mbed tsi_sensor
Fork of DS1820_HelloWorld by
Diff: Coffee_Maker_Upgrade.cpp
- Revision:
- 5:b8a9f4da4205
- Child:
- 6:8cc6048e0376
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Coffee_Maker_Upgrade.cpp Wed May 23 00:03:56 2018 +0000 @@ -0,0 +1,511 @@ +#include "mbed.h" +#include "matrix.h" +#include "DS1820.h" +#include "antirrebote.h" +#include "tsi_sensor.h" +#define TIME 10000 + +#if defined (TARGET_KL25Z) || defined (TARGET_KL46Z) + #define ELEC0 9 + #define ELEC1 10 +#elif defined (TARGET_KL05Z) + #define ELEC0 9 + #define ELEC1 8 +#else + #error TARGET NOT DEFINED +#endif + +//Declaraciones de valores de estados +enum {OFF = 0, + LED_ON = 0, + ON = 1, + LED_OFF = 1, + COMPLETE = 0, + TEMP_IDEAL = 40, + T_BOMBA = 60, + HORA,MINUTO}; + +enum{s_start, + s_set_time, + s_set_auto, + s_go, + s_off = 0, + s_auto_on, + s_run}; + + +//Salidas +DigitalOut LED_ROJO(LED1); +DigitalOut LED_VERDE(LED2); +DigitalOut LED_AZUL(LED3); + +DigitalOut Bomba_out(PTC5); +DigitalOut R_Cal(PTC6); + +DigitalOut RST(PTB8); +DigitalOut DATA(PTB9); +DigitalOut CLK(PTB10); + +//Buses creados para el manejo de las matrices +BusOut Columnas1_15(PTC1, PTC2, PTB3, PTB2); +BusOut Columnas16_30(PTE30, PTE29, PTE23, PTE22); + +TSIAnalogSlider tsi(ELEC0, ELEC1, 40); //Seteo del Slider + +DS1820 probe(PTC10); //Seteo del sensor + +//Objetos +//Seteo de los nombres del objeto tipo "Ticker" +Ticker timer_func; //Bomba de agua +Ticker timer; //Para el reloj +Ticker timer_puls; //Para los pulsadors +Ticker timer_sens; //Para el sensord de temperatura + +//Seteo de los nombres del objeto tipo "AntReb" ==> Librería de antirrebote +AntReb P_minuto; //Pulsador para setear los minutos +AntReb P_hora; //Pulsador para setear las horas +AntReb P_prog; //Pulsador para seleccionar el modo +AntReb P_on; //Pulsador de encendido + +//Prototipos de funciones +int iniciacion(char Puls_prog,char Puls_hora,char Puls_minuto); +int funcionamiento(char Puls_on); +void RealTime_Clock(void); +void Minuto(void); +int matriz(void); +void interrupt_time_func(void); +int Slider(char Ho_Mi); +void int_puls(); +void int_sens(); + +//Seteo de variables globales +char M[6] = {'C','O','N','F','I','G'}; +char Alarma[4]; + +char hora_dec = '0', + hora_uni = '0', + minuto_dec = '0', + minuto_uni = '0', + stateI = s_start, + stateF = s_off; + +char hab_func = OFF, + t_bomba = T_BOMBA, + Puls_on, + Bomba, + hora, + t_puls, + sl = 0, + med = 0, + time_sens; + +char num_matriz = 0, + Fila, + colum_A = 0, + colum_B = 0, + ColumnaA = 0, + ColumnaB, + estado_d; +int t; + +float Sens_value; + +int main(void){ + + char PULSO_prog, PULSO_hora ,PULSO_minuto ,PULSO_on; //Variables que guardarán el estado de los pulsadores + + timer_func.attach(&interrupt_time_func,1); //Llamará a la función "interrupt_time_func" cada 1s + timer.attach(&RealTime_Clock,0.1); //Llamará a la función "RealTime_Clock" cada 0.1s (100ms) + timer_puls.attach(&int_puls,0.001); //Llamará a la función "int_puls" cada 0.001s (1ms) + timer_sens.attach(&int_sens,0.1); //Llamará a la función "int_sens" cada 0.1s (100ms) + //Estados iniciales de los LEDs + LED_ROJO = LED_OFF; + LED_VERDE = LED_OFF; + LED_AZUL = LED_OFF; + + while (true) + { + if (med == 1){ + if(time_sens == 0){ //Variable que disminuye cada 100ms gracias a un "ticker" + probe.convertTemperature(true, DS1820::this_device); //Comienza la conversión de temperatura, se espera a que esté listo + Sens_value = probe.temperature(); + time_sens = 50; + } + } + //Seteo de los pines donde se conectarán los pulsadores + P_minuto.setPin(PTC0); + P_hora.setPin(PTC3); + P_prog.setPin(PTC4); + P_on.setPin(PTC7); + + if(t_puls == 0){ + t_puls = 10; + //Adquisición y guardado de los estados de los pulsadores + PULSO_prog = P_prog.antiRebote(); + PULSO_hora = P_hora.antiRebote(); + PULSO_minuto = P_minuto.antiRebote(); + PULSO_on = P_on.antiRebote(); + } + iniciacion(PULSO_prog,PULSO_hora,PULSO_minuto); //Configuración de la hora actual y del modo automático + if (hab_func == ON) //Habilita el funcionamiento cuando se termina la configuración + funcionamiento(PULSO_on); + if(hab_func == ON || sl > 0){ //Para el Modo Activo y para cuando se usa el Slider + M[0] = (hora_dec); + M[1] = (hora_uni); + M[4] = (minuto_dec); + M[5] = (minuto_uni); + } + //Llamado de función + matriz(); + } +} + +// ------------------------------------------------------------------------------------------------------- +//A partir de este comentario se realizarán las definiciones de cada función + +//Máquina de estados del inicio de la cafetera +int iniciacion(char Puls_prog,char Puls_hora,char Puls_minuto){ + switch (stateI){ + //Estado de inicio + case s_start: + hab_func = OFF; + LED_ROJO = LED_OFF; + LED_VERDE = LED_OFF; + LED_AZUL = LED_OFF; + R_Cal = OFF; + Bomba_out = OFF; + if(Puls_prog == ON){ + stateI = s_set_auto; + strcpy(M," AUTO ");//Escribe la matriz + } + break; + //Estado del Modo Automático + case s_set_auto: + if(Puls_hora == ON){ + strcpy(M," ");//Limpia la matriz + sl = 1;//Habilita el vínculo Slider/Hora + } + else if(Puls_minuto == ON){ + strcpy(M," ");//Limpia la matriz + sl = 2; //HABILITA VINCULO SLIDER-MINUTO + } + else if(Puls_prog == ON){ + stateI = s_set_time; + sl = 0; + strcpy(M," HORA "); + } + + Alarma[0] = hora_dec; + Alarma[1] = hora_uni; + Alarma[2] = minuto_dec; + Alarma[3] = minuto_uni; + if (sl == 1) + Slider(HORA); + else if (sl == 2) + Slider(MINUTO) + ; + break; + //Estado del Seteo de Tiempo + case s_set_time: + if(Puls_hora == ON) + { + strcpy(M," "); + sl = 1; + } + else if(Puls_minuto == ON){ + sl = 2; + strcpy(M," "); + } + else if(Puls_prog == ON) + { + stateI = s_go; + sl = 0; + } + if(sl == 1) + Slider(HORA); + else if(sl == 2) + Slider(MINUTO); + break; + //Estado en el que permanece hasta que desee reprogramar la hora + case s_go: + M[2] = ':'; + M[3] = ':'; + hab_func = ON; + if (Puls_prog == ON){ + stateI = s_start; + hab_func = OFF; + sl = 0; + strcpy(M," "); + strcpy(M,"CONFIG "); + } + break; + } + return 0; +} +//Máquina de estados del funcionamiento cuando se "prende" +int funcionamiento(char Puls_on){ + switch(stateF){ + default: + //Modo Apagado + case s_off: + LED_ROJO = LED_ON; + R_Cal = OFF; + Bomba_out = OFF; + if (Puls_on == ON) + { + stateF = s_auto_on; + LED_ROJO = LED_OFF; + LED_AZUL = LED_ON; + } + break; + //Modo Automático + case s_auto_on: + if (Puls_on == ON || (Alarma[0] == M[0] && Alarma[1] == M[1] && Alarma[2] == M[4] && Alarma[3] == M[5])){ + stateF = s_run; + time_sens = 50; + LED_AZUL = LED_OFF; + LED_VERDE = LED_ON; + t_bomba = T_BOMBA ; + } + break; + //Modo Encendido + case s_run: + if(t_bomba > 0 && Puls_on == OFF){ + //Con lo siguiente se desea calentar el agua a una temperatura preestablecida de fábrica + if(Sens_value < TEMP_IDEAL){ + R_Cal = ON; + med = 1; //Habilita la medición + } + if(Sens_value >= TEMP_IDEAL){ + med = 0; //Desahabilita la medición + R_Cal = OFF; + Bomba = ON; + Bomba_out = Bomba; + } + }else{ + Bomba = OFF; + Bomba_out = Bomba; + LED_VERDE = LED_OFF; + LED_ROJO = LED_ON; + Sens_value = 0; + stateF = s_off; + med = 0; + } + } + return 0; +} +//Función que controla el tiempo de funcionamiento de la bomba +void interrupt_time_func(void){ + + if(Bomba == ON){ + t_bomba--; + } +} + +void Minuto(void){ + minuto_uni++; +} +//Función que realiza el conteo del tiempo actual (real) +void RealTime_Clock(void){ + if (hab_func == ON){ + Minuto(); + if(hora_dec == '2' && hora_uni > '3'){ + hora_dec = '0'; + hora_uni = '0'; + }else if(hora_uni > '9'){ + hora_uni = '0'; + hora_dec++; + }else if( minuto_dec > '5'){ + minuto_dec = '0'; + hora_uni++; + }else if(minuto_uni > '9'){ + minuto_uni = '0'; + minuto_dec++; + } + } +} +//Función del funcionamiento de las matrices +int matriz(void){ +/* + Descripción del Funcionamiento: + + - Se usan ocho bits para controlar la matriz en forma binaria. + - Por cada pulso del clock, el valor de data de va desplazando por cada una de las filas de la columna seleccionada. + - Una vez que se pasan todos los valores de una columna, se le da un pulso al reset para limpiar data +*/ + char c; + switch(num_matriz){// Cada "case" es una matriz, son seis matrices + case 0: + ColumnaA = 0; + for(colum_A = 0;colum_A <= 4;colum_A++){ + Columnas1_15 = 0; + Columnas16_30 = 15; + for(c = 0;c <= 4;c++){ + Columnas1_15 = Columnas1_15 + ((ColumnaA & (0b0001 << c))); + } + + for (Fila = 0;Fila <= 6;Fila++){ + estado_d = ((char_data[M[num_matriz] - 32][6 - Fila]) & (0b10000 >> ColumnaA)); + DATA = (estado_d >> (4 - ColumnaA)); + CLK = 1; + CLK = 0; + } + for(t = 0;t <= TIME;t++); + RST = 0; + RST = 1; + ColumnaA++; + } + num_matriz++; + break; + + case 1: + ColumnaA = 5; + for(colum_A = 5;colum_A <= 9;colum_A++){ + Columnas1_15 = 0; + Columnas16_30 = 15; + for(c = 0;c <= 4;c++){ + Columnas1_15 = Columnas1_15 + (ColumnaA & (0b0001 << c)); + } + for(Fila = 0;Fila <= 6;Fila++){ + estado_d = ((char_data[M[num_matriz] - 32][6 - Fila]) & (0b10000 >> ColumnaA - 5)); + DATA = (estado_d >> (4 - (ColumnaA - 5))); + CLK = 1; + CLK = 0; + } + for(t = 0;t <= TIME;t++); + RST = 0; + RST = 1; + ColumnaA++; + } + num_matriz++; + break; + + case 2: + ColumnaA = 10; + for(colum_A = 10;colum_A <= 14;colum_A++){ + Columnas1_15 = 0; + Columnas16_30 = 15; + for(c = 0;c <= 4;c++){ + Columnas1_15 = Columnas1_15 + (ColumnaA & (0b0001 << c)); + } + for(Fila = 0;Fila <= 6;Fila++){ + estado_d = ((char_data[M[num_matriz] - 32][6 - Fila]) & (0b10000 >> (ColumnaA - 10))); + DATA = (estado_d >> (4 - (ColumnaA - 10))); + CLK = 1; + CLK = 0; + } + for(t = 0;t <= TIME;t++); + RST = 0; + RST = 1; + ColumnaA++; + } + num_matriz++; + break; + + case 3: + ColumnaB = 0; + for(colum_B = 0;colum_B <= 4;colum_B++){ + Columnas16_30 = 0; + Columnas1_15 = 15; + for(c = 0;c <= 4;c++){ + Columnas16_30 = Columnas16_30 + (ColumnaB & (0b0001 << c)); + } + for (Fila = 0;Fila <= 6;Fila++){ + estado_d = ((char_data[M[num_matriz] - 32][6 - Fila]) & (0b10000 >> ColumnaB)); + DATA = estado_d >> (4 - ColumnaB); + CLK = 1; + CLK = 0; + } + for(t = 0;t <= TIME;t++); + RST = 0; + RST = 1; + ColumnaB++; + } + num_matriz++; + break; + + case 4: + ColumnaB = 5; + for(colum_B = 5;colum_B <= 9;colum_B++){ + Columnas16_30 = 0; + Columnas1_15 = 15; + for(c = 0;c <= 4;c++){ + Columnas16_30 = Columnas16_30 + (ColumnaB & (0b0001 << c)); + } + for (Fila = 0;Fila <= 6;Fila++){ + estado_d = ((char_data[M[num_matriz] - 32][6 - Fila]) & (0b10000 >> (ColumnaB - 5))); + DATA = (estado_d >> (4 - (ColumnaB - 5))); + CLK = 1; + CLK = 0; + } + for(t = 0;t <= TIME;t++); + RST = 0; + RST = 1; + ColumnaB++; + } + num_matriz++; + break; + + case 5: + ColumnaB = 10; + for(colum_B = 10;colum_B <= 14;colum_B++){ + Columnas16_30 = 0; + Columnas1_15 = 15; + for(c = 0;c <= 4;c++){ + Columnas16_30 = Columnas16_30 + (ColumnaB & (0b0001 << c)); + } + for (Fila = 0;Fila <= 6;Fila++){ + estado_d = ((char_data[M[num_matriz] - 32][6 - Fila]) & (0b10000 >> (ColumnaB - 10))); + DATA = (estado_d >> (4 - (ColumnaB - 10))); + CLK = 1; + CLK = 0; + } + for(t = 0;t <= TIME;t++); + RST = 0; + RST = 1; + ColumnaB++; + } + num_matriz = 0; + break; + } + return 0; +} +//Función que realiza el vínculo Slider/Hora +int Slider(char Ho_Mi){ + switch (Ho_Mi){ + //Estado de seteo de la hora + case HORA: + hora = ((tsi.readPercentage() * 100) / 4); + if(hora > 23) + hora = 23; + //El +48 es para que el resultado se pase a ASCII y manejar más fácilmente la matriz + hora_dec = (hora / 10)+48; + hora_uni = (hora - ((hora / 10) * 10)) + 48; + break; + //Estado de seteo del minuto + case MINUTO: + hora = ((tsi.readPercentage() * 100) / 8); + hora = hora * 5; + if (hora == 60) + hora = 55; + minuto_dec = (hora / 10) + 48; + minuto_uni = (hora - ((hora / 10) * 10)) + 48; + break; + + default: + break; + } + matriz(); + return 0; +} +//Función de interrupción del objeto antirrebote +void int_puls (void){ + if(t_puls > 0){ + t_puls--; + } +} +//Función de interrupción del sensado de temperatura. Sensa 1 vez cada 5 segundos +void int_sens(){ + if(time_sens>0) + time_sens--; +} \ No newline at end of file