Heladera Lauckner Lipari

Dependencies:   DS1820 TextLCD mbed

Fork of DS1820_HelloWorld by Erik -

Revision:
5:838bc36ed9e4
Parent:
3:f483abe4bc57
--- a/main.cpp	Fri Jan 13 18:30:37 2017 +0000
+++ b/main.cpp	Wed May 23 22:31:23 2018 +0000
@@ -1,49 +1,465 @@
-#define MULTIPLE_PROBES
-#define DATA_PIN        A0
-
-
-#ifdef MULTIPLE_PROBES
+#define CANT_SAMPLES    10  //Constante que se define por si se quiere agregar mas mediciones al promedio 
 
 #include "mbed.h"
 #include "DS1820.h"
+#include "TextLCD.h"
 
-#define MAX_PROBES      16
- 
-DS1820* probe[MAX_PROBES];
- 
-int main() {  
-    // Initialize the probe array to DS1820 objects
-    int num_devices = 0;
-    while(DS1820::unassignedProbe(DATA_PIN)) {
-        probe[num_devices] = new DS1820(DATA_PIN);
-        num_devices++;
-        if (num_devices == MAX_PROBES)
+#define MAX_PROBES      2  //Constante que se define para la cant de sensores DS1820 (Lo requiere la lib)
+
+enum {DEMORA, CONTROL,  MODO,  OFF, SET, UP, DOWN,                //Estados de la ME de Interrupciones
+      MODO_HELADERA, SET_HELADERA, MODO_FREEZER, SET_FREEZER,     //Estados de la ME de LCD
+      CERO, ESPERANDO, UNO,                                       //Estados de la ME de antirebotes
+      ADC_FRZ, SAMPLES};                                          //Estados de la ME de Mediciones del ADC
+
+Ticker timer1;  //Timer para controlar los tiempos de pulsadores  1mSeg
+Ticker timer2;  //Timer para controlar los tiempos del sensor DS1820 200mSeg
+InterruptIn modo(PTD5);   //Pin de entrada del Pulsador de Modo
+InterruptIn set(PTD0);    //Pin de entrada del Pulsador de Set
+InterruptIn up(PTD2);     //Pin de entrada del Pulsador de UP
+InterruptIn down(PTD3);   //Pin de entrada del Pulsador de DOWN
+DS1820 probe1(A0);        //Pin asociado al sensor DS1820
+AnalogIn LM35(A1);        //Pin de entrada analogico del LM35
+DigitalOut salida_frz(PTC2);  //Salida activada para enfriar el freezer
+DigitalOut salida_hel(PTC1);  //Salida activada para enfriar la heladera
+
+// I2C Communication
+I2C i2c_lcd(PTC9,PTC8); // SDA, SCL
+
+
+// LCD instantiation
+TextLCD_I2C lcd(&i2c_lcd, 0x4E, TextLCD::LCD16x2);  //Se indica que sera por I2C, la address del modulo y tipo de LCD
+
+
+unsigned char puls_modo = 0, puls_set = 0, puls_up = 0, puls_down = 0, set_hel = 8, set_frz = 16; //Variables de los pulsadores y el valor seteado
+short PULS_tic;
+
+unsigned char  ADC_CONV_state = ADC_FRZ, cuentaFrz = 0, cuentaHel = 0; //Variables usadas en las mediciones de los sensores
+float acumHel = 0, acumFrz  = 0, resHel = 0, resFrz = 0, resADC;       //Variables usadas en las mediciones de los sensores
+
+//Variables usadas en los pulsadores
+char habilitacion = 0, valor_puls_modo, valor_puls_set, valor_puls_up, valor_puls_down, anti_rebote_state, hab_antirrebote; 
+short espera_tic = 50; //Variable de tiempo
+
+
+//Prototipos 
+void ADC_CONV_Step(void);
+void ADC_CONV_TIEMPO (void);
+void timer_init(void);
+void anti_rebote_step (char hab);
+void flanco_modo (void);
+void flanco_set (void);
+void flanco_up (void);
+void flanco_down (void);
+void Interrupciones(void);
+void TIEMPOS(void);
+void LCD_init(void);
+void LCDStep(void);
+void HeladeraStep(void);
+void Activacion_frio(void);
+
+
+int main()                                                               
+{
+    probe1.convertTemperature(false, DS1820::all_devices);  //Iniciacion del sensor DS1820 (Lo requiere la lib)
+    timer_init();  //Funcion que configura los timers
+    LCD_init();    //Funcion que configura e inicia el LCD
+    while(1) {
+        ADC_CONV_Step();   //Maquina de estados de medicion del ADC
+        Interrupciones();  //Maquina de estados de interrupciones de los pulsadores
+        LCDStep();         //Maquina de estados que controla el LCD
+        Activacion_frio(); //Maquina de estados que controla la activacion de las salidas 
+    }
+
+}
+
+//Funcion que se ejecuta cada 1mSeg
+void TIEMPOS (void)                                                           
+{
+    if(PULS_tic > 0)
+        PULS_tic--;
+    if(espera_tic > 0)
+        espera_tic--;
+}
+
+
+void timer_init (void)
+{
+    timer1.attach(&TIEMPOS, 0.001);         //TIMER cada 1mSeg
+    timer2.attach(&ADC_CONV_TIEMPO, 0.2);   //TIMER cada 200mSeg (sensor DS1820)
+}
+
+//Maquina que controla las mediciones del ADC y calcula un promedio 
+void ADC_CONV_Step(void)
+{
+    switch(ADC_CONV_state) {
+        default:        //Si no se definio estado, es ADC_FRZ
+        case ADC_FRZ:   //Estado ADC_FZR
+            resADC = 3.3 * LM35.read();   //Se lee la entrada y se la multiplica segun la ganancia requerida
+            resADC = (resADC *26)/3.3;   //Se hace regla de tres para la ganancia requerida
+            acumFrz = acumFrz + resADC;  //El valor medido se le suma al acumulado para luego calcular el promedio
+            cuentaFrz++;                 //La variable que guarda la cant de mediciones aumenta 1
+
+            ADC_CONV_state = SAMPLES;    //Proximo estado
+            break;
+
+        case SAMPLES:   //Estado Samples
+            if(cuentaHel >= CANT_SAMPLES) //Si cant de mediciones es > 0 = a la cant de samples definida...
+            {
+                resHel = acumHel/ CANT_SAMPLES;  //Calcula el promedio y lo guarda en resHel
+                acumHel = 0;                     //Reinicia la variable que acumula los resultados
+                cuentaHel = 0;                   //Reinicia la variable que cuenta la cant de mediciones
+            }
+            
+            if(cuentaFrz >= CANT_SAMPLES) //Si cant de mediciones es > 0 = a la cant de samples definida... 
+            {
+                resFrz = acumFrz/ CANT_SAMPLES;  //Calcula el promedio y lo guarda en resFrz
+                acumFrz = 0;                     //Reinicia la variable que acumula los resultados
+                cuentaFrz = 0;                   //Reinicia la variable que cuenta la cant de mediciones
+            }
+                       
+            ADC_CONV_state = ADC_FRZ;  //Proximo estado
             break;
     }
-    
-    printf("Found %d device(s)\r\n\n", num_devices);
-    while(1) {
-        probe[0]->convertTemperature(true, DS1820::all_devices);         //Start temperature conversion, wait until ready
-        for (int i = 0; i<num_devices; i++)
-            printf("Device %d returns %3.1foC\r\n", i, probe[i]->temperature());
-        printf("\r\n");
-        wait(1);
-    }
-    
+}
+
+//Funcion que se repite cada 200mSeg
+void ADC_CONV_TIEMPO (void)
+{
+    probe1.convertTemperature(false, DS1820::all_devices);  //Prepara al sensor para la medicion (lo requiere la lib)
+    acumHel =  (probe1.temperature() + acumHel);            //Se guarda la medicion y se le suma al acumulado
+    cuentaHel++;                                            //La variable que guarda la cant de mediciones aumenta 1
 }
 
-#else
-#include "mbed.h"
-#include "DS1820.h"
- 
-DS1820 probe(DATA_PIN);
- 
-int main() {
-    while(1) {
-        probe.convertTemperature(true, DS1820::all_devices);         //Start temperature conversion, wait until ready
-        printf("It is %3.1foC\r\n", probe.temperature());
-        wait(1);
+
+unsigned char LCDState = MODO_HELADERA;  //Variable de estado del LCD
+//Maquina de estado que escribe en el LCD el modo en el que se está
+void LCDStep(void)
+{
+    switch(LCDState) {                                                          
+        default:            //Si no se definio estado, es MODO_HELADERA
+        case MODO_HELADERA: //Estado MODO_HELADERA         
+            lcd.printf("Temp Hel: %2.1f", resHel);  //Escribe en el LCD Temp Hel: y el valor del promedio del sensor con 1 decimal de precision
+            lcd.putc(0);                            //Escribe en el LCD el simbolo de º
+            lcd.printf("C");                        //Escribe en el LCD una C, terminando el espacio en esa fila
+            lcd.printf("Temp Set: 0%d.0",set_hel);  //Escribe en el LCD Temp Set: y el valor seteado por el usuario
+            lcd.putc(0);                            //Escribe en el LCD el simbolo de º
+            lcd.printf("C");                        //Escribe en el LCD una C, terminando el espacio en esa fila
+            lcd.locate(0,0);                        //Coloca al cursor en la primera posicion del LCD
+            break;
+
+        case SET_HELADERA:   //Estado SET_HELADERA  
+            lcd.printf("Hel set:  %d",set_hel);  //Escribe en el LCD Set Hel: y el valor actual seteado
+            lcd.putc(0);                         //Escribe en el LCD el simbolo de º
+            lcd.printf("C\n");                   //Escribe en el LCD una C y baja al proximo renglon
+            lcd.printf("  UP ");                 //Escribe en el LCD UP 
+            lcd.putc(3);                         //Escribe en el LCD el simbolo de una flecha hacia arriba
+            lcd.printf("   DOWN ");              //Escribe en el LCD DOWN 
+            lcd.putc(4);                         //Escribe en el LCD el simbolo de una flecha hacia abajo
+            lcd.locate(0,0);                     //Coloca al cursor en la primera posicion del LCD
+            break;
+
+        case MODO_FREEZER:      //Estado MODO_FREEZER
+            lcd.printf("Temp FRZ:-");                 //Escribe en el LCD Temp FRZ:- 
+            if(resFrz < 10)   //Si la medicion es menor a 10...
+                lcd.printf("0%2.1f", resFrz);         //Escribe el valor del promedio del sensor con 1 decimal de precision, con un cero delante
+            else
+                lcd.printf("%2.1f", resFrz);          //Si no escribe el valor del promedio del sensor con 1 decimal de precision
+            lcd.putc(0);                              //Escribe en el LCD el simbolo de º
+            lcd.printf("C");                          //Escribe en el LCD una C, terminando el espacio en esa fila
+            lcd.printf("Temp Set:-%d.0",set_frz);     //Escribe en el LCD Temp Set:- y el valor seteado por el usuario  
+            lcd.putc(0);                              //Escribe en el LCD el simbolo de º
+            lcd.printf("C");                          //Escribe en el LCD una C, terminando el espacio en esa fila
+            lcd.locate(0,0);                          //Coloca al cursor en la primera posicion del LCD
+            break;
+
+        case SET_FREEZER:     //Estado SET_FREEZER 
+            lcd.printf("FRZ set: -%d",set_frz);         //Escribe en el LCD FRZ set:-
+            lcd.putc(0);                                //Escribe en el LCD el simbolo de º
+            lcd.printf("C\n");                          //Escribe en el LCD una C y baja al proximo renglon
+            lcd.printf("  UP ");                        //Escribe en el LCD UP
+            lcd.putc(3);                                //Escribe en el LCD el simbolo de una flecha hacia arriba
+            lcd.printf("   DOWN ");                     //Escribe en el LCD DOWN 
+            lcd.putc(4);                                //Escribe en el LCD el simbolo de una flecha hacia abajo
+            lcd.locate(0,0);                            //Coloca al cursor en la primera posicion del LCD
+            break;
     }
 }
 
-#endif
\ No newline at end of file
+//Funcion que inicializa el LCD
+void LCD_init(void)                                                          
+{
+    lcd.setBacklight(TextLCD::LightOn);             //Se enciende el BackLight
+    lcd.setCursor(TextLCD::CurOff_BlkOff);          //Se desactiva el cursor y el parpadeo de este
+    lcd.setUDC(0, (char *) udc_degr);               //Se crea el simbolo de grado asociandolo al caracter 0
+    lcd.setUDC(3, (char *) udc_uparrow);            //Se crea el simbolo de flecha UP asociandolo al caracter 3
+    lcd.setUDC(4, (char *) udc_downarrow);          //Se crea el simbolo de flecha DOWN sociandolo al caracter 4
+}
+
+//Maquina de estado antirrebote del pulsador de MODO
+void anti_rebote_step_modo(void)                                                
+{
+    switch(anti_rebote_state) {
+        case CERO:                  //Estado de que el pulsador quedo en cero (presionado)
+            puls_modo = 0;          //iguala variable a como quedo el pulsador de modo
+            habilitacion = 0;       //deshabilita la maquina (se vuelve a habilitar con interrupin)
+            break;
+
+        case ESPERANDO:             //estado de espera para sacar el rebote
+            if(espera_tic >0)       //si no paso la espera termina aca la maquina
+                return;             
+            valor_puls_modo = modo.read();      //si paso la espera, iguala una variable a lo que lee en la entrada del pulsador
+
+            if(valor_puls_modo == 0) {          //si esa variable es 0, cambia el estado de la maquina a CERO
+                anti_rebote_state = CERO;
+
+                switch (LCDState) {             //Si estaba  en modo heladera pasa a freezer
+                    case MODO_HELADERA:
+                        lcd.cls();
+                        LCDState = MODO_FREEZER;
+                        break;
+
+                    case MODO_FREEZER:          //Si estaba en modo freezer pasa a heladera
+                        lcd.cls();
+                        LCDState = MODO_HELADERA;
+                        break;
+
+                    default:
+                        break;
+                }
+
+            } else
+                anti_rebote_state = UNO;        //si la variable no es 0 (es 1), cambia el estado de la maquina a UNO
+            break;
+
+        case UNO:                   //Estado de que el pulsador quedo en cero (presionado)
+            puls_modo = 1;          //iguala variable a como quedo el pulsador de modo
+            habilitacion = 0;       //deshabilita la maquina (se vuelve a habilitar con interrupin)
+            break;
+    }
+}
+
+void anti_rebote_step_set(void)                                                 //PULSADOR DE SET
+{                                //TODOS LOS PULSADORES SON IGUALES, SOLO CAMBIAN LOS NOMBRES DE LAS VARIABLES PARA DIFERENCIARLOS
+    switch(anti_rebote_state) {
+        case CERO:
+            puls_set = 0;
+            habilitacion = 0;
+            break;
+
+        case ESPERANDO:
+            if(espera_tic >0)
+                return;
+            valor_puls_set = set.read();
+
+            if(valor_puls_set == 0) {
+                anti_rebote_state = CERO;
+
+                switch (LCDState) {                                             //LO QUE HACE
+                    case MODO_HELADERA:
+                        lcd.cls();
+                        LCDState = SET_HELADERA;
+                        break;
+
+                    case MODO_FREEZER:
+                        lcd.cls();
+                        LCDState = SET_FREEZER;
+                        break;
+
+                    case SET_HELADERA:
+                        lcd.cls();
+                        LCDState = MODO_HELADERA;
+                        break;
+
+                    case SET_FREEZER:
+                        lcd.cls();
+                        LCDState = MODO_FREEZER;
+                        break;
+                    default:
+                        break;
+                }
+            } else
+                anti_rebote_state = UNO;
+            break;
+
+        case UNO:
+            puls_set = 1;
+            habilitacion = 0;
+            break;
+    }
+}
+
+void anti_rebote_step_up(void)                                                  //PULSADOR DE UP
+{                                //TODOS LOS PULSADORES SON IGUALES, SOLO CAMBIAN LOS NOMBRES DE LAS VARIABLES PARA DIFERENCIARLOS
+    switch(anti_rebote_state) {
+        case CERO:
+            puls_up = 0;
+            habilitacion = 0;
+            break;
+
+        case ESPERANDO:
+            if(espera_tic >0)
+                return;
+            valor_puls_up = up.read();
+
+            if(valor_puls_up == 0) {
+                anti_rebote_state = CERO;
+
+                switch (LCDState) {   //En el caso de los pulsadore UP y DOWN, lo que hacen es aumentar/disminuir en 1 la variable set que corresponda
+
+                    case SET_HELADERA:
+                        if(set_hel<8)       //Si no se llegó al limite, aumenta 1
+                            set_hel++;
+                        else
+                            set_hel = 2;    //Vuelve al valor minimo
+                        break;
+
+                    case SET_FREEZER:
+
+                        if(set_frz < 24) //Si no se llegó al limite, aumenta 1
+                            set_frz++;
+                        else
+                            set_frz = 16;  //Vuelve al valor minimo
+                        break;
+
+                    default:
+                        break;
+                }
+
+            } else
+                anti_rebote_state = UNO;
+            break;
+
+        case UNO:
+            puls_up = 1;
+            habilitacion = 0;
+            break;
+    }
+}
+
+void anti_rebote_step_down(void)                                                //PULSADOR DE DOWN
+{                                //TODOS LOS PULSADORES SON IGUALES, SOLO CAMBIAN LOS NOMBRES DE LAS VARIABLES PARA DIFERENCIARLOS
+    switch(anti_rebote_state) {
+        case CERO:
+            puls_down = 0;
+            habilitacion = 0;
+            break;
+
+        case ESPERANDO:
+            if(espera_tic >0)
+                return;
+            valor_puls_down = down.read();
+
+            if(valor_puls_down == 0) {
+                anti_rebote_state = CERO;
+
+                switch (LCDState) {   //En el caso de los pulsadore UP y DOWN, lo que hacen es aumentar/disminuir en 1 la variable set que corresponda                                   
+
+                    case SET_HELADERA:
+
+                        if(set_hel > 2) //Si no se llegó al limite, disminuye 1
+                            set_hel--;
+                        else
+                            set_hel = 8; //Vuelve al valor maximo
+                        break;
+
+                    case SET_FREEZER:
+
+                        if(set_frz > 16) //Si no se llegó al limite, disminuye 1
+                            set_frz--;
+                        else
+                            set_frz = 24;  //Vuelve al valor maximo
+                        break;
+
+                    default:
+                        break;
+                }
+
+            } else
+                anti_rebote_state = UNO;
+            break;
+
+        case UNO:
+            puls_down = 1;
+            habilitacion = 0;
+            break;
+    }
+}
+
+void flanco_modo (void)                             //Si se detecto un flanco ascendente o descendente del pulsador de modo
+{
+    PULS_tic = 40; // Demora de Puls es 40mSeg, demora para evitar el rebote
+    hab_antirrebote = MODO;                 //eligue que pulsador habilitar
+    anti_rebote_state = ESPERANDO;          //modifica el estado de la maquina antirrebote a ESPERANDO
+    habilitacion = 1;                       //habilita la maquina de antirrebote
+}
+
+void flanco_set (void)
+{                                                   //TODOS LOS DETECTORES DE FLANCO SON IGUALES, SOLO CAMBIA QUE MAQUINA SE HABILITA DE LAS 4 OPCIONES DE PUILSADORES
+    PULS_tic = 40; // Demora de Puls es 40mSeg
+    hab_antirrebote = SET;
+    anti_rebote_state = ESPERANDO;
+    habilitacion = 1;
+}
+
+void flanco_up (void)
+{                                                   //TODOS LOS DETECTORES DE FLANCO SON IGUALES, SOLO CAMBIA QUE MAQUINA SE HABILITA DE LAS 4 OPCIONES DE PUILSADORES
+    PULS_tic = 40; // Demora de Puls es 40mSeg
+    hab_antirrebote = UP;
+    anti_rebote_state = ESPERANDO;
+    habilitacion = 1;
+}
+
+void flanco_down (void)
+{                                                   //TODOS LOS DETECTORES DE FLANCO SON IGUALES, SOLO CAMBIA QUE MAQUINA SE HABILITA DE LAS 4 OPCIONES DE PUILSADORES
+    PULS_tic = 40; // Demora de Puls es 40mSeg
+    hab_antirrebote = DOWN;
+    anti_rebote_state = ESPERANDO;
+    habilitacion = 1;
+}
+
+
+void Interrupciones(void)                                                       //HABILITA INTERRUPCIONES DE PULSADORES
+{
+
+    modo.fall(&flanco_modo); //Habilita interrupción MODO 
+    modo.rise(&flanco_modo);
+    set.fall(&flanco_set);   //Habilita interrupción SET
+    set.rise(&flanco_set);
+    up.fall(&flanco_up);     //Habilita interrupción UP
+    up.rise(&flanco_up);
+    down.fall(&flanco_down); //Habilita interrupción DOWN
+    down.rise(&flanco_down);
+
+    if(habilitacion == 1) {                 //si se detecto un flanco en alguna de las entradas de los pulsadores
+        switch (hab_antirrebote) {          //dependiendo de que pulsador se toco, eligue que maquina debe ejecutar
+            case MODO:                      
+                anti_rebote_step_modo();    //maquina modo
+                break;
+            case SET:
+                anti_rebote_step_set();     //maquina set
+                break;
+            case UP:
+                anti_rebote_step_up();      //maquina up
+                break;
+            case DOWN:
+                anti_rebote_step_down();    //maquina down
+                break;
+        }
+    }
+}
+
+//Funcion que controla las salidas
+void Activacion_frio(void)                                                     
+{
+    if(resHel < (set_hel - 1))   //Si el promedio de las mediciones es menor al valor seteado menos un grado de margen...
+        salida_hel = 0;          // No hay que enfriar, se desactiva la salida
+    else if(resHel > (set_hel + 1))  //Si el promedio de las mediciones es mayor al valor seteado mas un grado de margen...
+        salida_hel = 1;              //Se debe enfriar, se activa la salida
+        
+//Como el valor seteado se toma como positivo para la funcion de los pulsadores up y down, al compararlos se debe tomar como negativos
+
+    if(resFrz < ((set_frz * -1) - 1))  //Si el promedio de las mediciones es menor al valor seteado menos un grado de margen...
+        salida_frz = 0;                // No hay que enfriar, se desactiva la salida
+    else if(resFrz  > ((set_frz * -1) + 1))  //Si el promedio de las mediciones es mayor al valor seteado mas un grado de margen...
+        salida_frz = 1;                      //Se debe enfriar, se activa la salida
+}
\ No newline at end of file