![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Heladera Lauckner Lipari
Dependencies: DS1820 TextLCD mbed
Fork of DS1820_HelloWorld by
main.cpp
- Committer:
- juanlipari
- Date:
- 2018-05-23
- Revision:
- 6:b2a27e6f6195
- Parent:
- 5:838bc36ed9e4
File content as of revision 6:b2a27e6f6195:
#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 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; } } //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 } 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; } } //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 }