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
Coffee_Maker_Upgrade.cpp
- Committer:
- Tom_87
- Date:
- 2018-05-23
- Revision:
- 5:b8a9f4da4205
- Child:
- 6:8cc6048e0376
File content as of revision 5:b8a9f4da4205:
#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--; }