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 -

Coffee_Maker_Upgrade.cpp

Committer:
Tom_87
Date:
2018-06-12
Revision:
6:8cc6048e0376
Parent:
5:b8a9f4da4205

File content as of revision 6:8cc6048e0376:

#include "mbed.h"
#include "matrix.h"
#include "DS1820.h"
#include "antirrebote.h"
#include "tsi_sensor.h"
#define TIME 15000

#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.01);          //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);
        

            //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;
            med=0;
            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;
            med=0;
                    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_uni > '9'){
            minuto_uni = '0';
            minuto_dec++;
        }else if( minuto_dec > '5'){
            minuto_dec = '0';
            hora_uni++;
        }
    }
}
//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){
    P_minuto.DebTime();
    P_hora.DebTime();
    P_prog.DebTime();
    P_on.DebTime();
}
//Función de interrupción del sensado de temperatura. Sensa 1 vez cada 5 segundos
void int_sens(){
    if(time_sens>0)
        time_sens--;    
}