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 Erik -

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