Heladera Lauckner Lipari
Dependencies: DS1820 TextLCD mbed
Fork of DS1820_HelloWorld by
Diff: main.cpp
- Revision:
- 5:838bc36ed9e4
- Parent:
- 3:f483abe4bc57
diff -r 01060b5e01b4 -r 838bc36ed9e4 main.cpp --- 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