Trabajo práctico horno eléctrico

Dependencies:   TextLCD mbed

main.cpp

Committer:
MarceRondan
Date:
2018-05-23
Revision:
1:556fb9468e90
Parent:
0:d0f1b335181e

File content as of revision 1:556fb9468e90:

#include "mbed.h"
#include "TextLCD.h"

#define apretado 0
#define reposo 1

//Defino entradas, salidas e interrupciones
AnalogIn entrada_temp_sel(PTB0);
AnalogIn entrada_time_sel(PTB1);
AnalogIn entrada_temp(PTB2);


InterruptIn int_puls_coccion(PTD0);
InterruptIn int_puls_start(PTD2);
InterruptIn int_puls_luz(PTD3);
InterruptIn int_encoder1(PTD6);
InterruptIn int_encoder2(PTD7);

DigitalOut luz (LED1);

DigitalOut c1_sal (PTB8);
DigitalOut c2_sal (PTB9);
DigitalOut vent_sal (PTB10);
DigitalOut led_indicador (PTB11);

DigitalIn encoder1_b (PTA17);
DigitalIn encoder2_b (PTC13);

//Defino puertos I2C e inicializo LCD
I2C i2c_lcd(PTC2,PTC1);
TextLCD_I2C lcd(&i2c_lcd, 0x7E, TextLCD::LCD16x2);

//Declaro los estados de la máquina de estados
enum {off,on_calentar,on_enfriar};

//Declaro funciones
void timer_antirrebote(void);
void timer_refresh(void);
void timer_principal(void);
void display(void);
void detect(void);
void leer_pulsador(void);
void leer_potes(void);
void control(void);

//Defino variables
unsigned int start=0,enable_contador=0,enable_pulsador=0;
unsigned int temp_sel = 0,temp_sel_real = 0, temp_med, time_sel = 0, time_sel_real = 0, coccion_sel = 2;
unsigned int cont_antirrebote, cont_refresh;
unsigned int state;
unsigned int c1,c2,vent;
unsigned char hab_tomar_valor;
unsigned char hab;
unsigned int aux = 0;

//Defino timers
Ticker atrb;
Ticker refresh;
Ticker principal;

int main()
{
    //Inicializo timers
    atrb.attach(&timer_antirrebote,0.001);
    refresh.attach(&timer_refresh,0.01);
    principal.attach(&timer_principal,1);
    //Inicializo interrupciones
    int_puls_start.fall(&detect);
    int_puls_luz.fall(&detect);
    int_puls_coccion.fall(&detect);
    int_encoder1.fall(&detect);
    int_encoder2.fall(&detect);

    //Defino estado inicial del LCD
    lcd.setBacklight(lcd.LightOn);
    lcd.setCursor(lcd.CurOff_BlkOff);
    //Defino caracter "º" para LCD
    lcd.setUDC(0, (char *) udc_degr);

    //Escribo caracteres en LCD que nunca se modifican
    lcd.locate(4,1);
    lcd.putc(0);
    lcd.printf("C");
    lcd.locate(12,1);
    lcd.printf("min ");


    while (1) {
        leer_pulsador();//Función para leer pulsadores y eleminar rebote
        leer_potes();//Función para obtener valores de potenciómetros
        control();//Función principal de control de entradas y salidas
        display();//Función que escribe el LCD
    }
}

void control()
{
    if(start == 1) {

        if(hab_tomar_valor == 1) {
            //Congela los valores a utilizar por el horno e inicia la cocción
            temp_sel = temp_sel_real;
            time_sel = time_sel_real;
            state = on_calentar;
            hab_tomar_valor = 0;
        }
    } else {
        state = off;
        hab_tomar_valor = 1;
    }
    //Asigna los valores de las variables a sus correspondientes salidas
    c1_sal = c1;
    c2_sal = c2;
    vent_sal = vent;

    switch(state) {
        case off:
            //Caso "apagado"
            c1 = 0;
            c2 = 0;
            vent = 0;
            hab = 1;
            break;
        case on_calentar:
            //Caso "calentar" (cuando la temperatura está por debajo del umbral)
            if(hab == 1) {
                hab = 0;
                c1 = (coccion_sel >> 1)& 1;
                c2 = (coccion_sel >> 2)& 1;
                vent = (coccion_sel & 1);
                led_indicador = 0;
            }
            if(temp_med >= temp_sel + 10) { //Si la temperatura está por encima cambia estado
                state = on_enfriar;
                hab = 1;
            }
            if(time_sel <= 0) {
                //Si se termina el tiempo cambia estado a "off"
                led_indicador = 1;
                state = off;
                start = 0;
                hab = 1;
            }
            break;
        case on_enfriar:
            //Caso "enfriar" (cuando la temperatura está por encima del umbral)
            if(hab == 1) {
                hab = 0;
                c1 = 0;
                c2 = 0;
                vent = (coccion_sel & 1);
                led_indicador = 0;
            }
            if(temp_med <= temp_sel - 10) { //Si la temperatura está por debajo cambia estado
                state = on_calentar;
                hab = 1;
            }
            if(time_sel <= 0) {
                //Si se termina el tiempo cambia estado a "off"
                led_indicador = 1;
                state = off;
                start = 0;
                hab = 1;
            }
            break;
    }
}
void display()
{
    //Escribe el LCD actualizando variables
    if(!cont_refresh) {
        cont_refresh = 15;
        if((coccion_sel >> 1)& 1 == 1) {
            lcd.locate(2,0);
            lcd.printf("UP");
        }
        if((coccion_sel >> 2)& 1 == 1) {
            lcd.locate(5,0);
            lcd.printf("DOWN");
        }
        if((coccion_sel & 1) == 1) {
            lcd.locate(10,0);
            lcd.printf("VENT");
        }
        lcd.locate(1,1);
        if(state == off) {
            lcd.printf("%d",temp_sel_real);
            lcd.locate(8,1);
            if(time_sel_real<100)
                lcd.printf("0%d ",time_sel_real);
            else
                lcd.printf("%d ",time_sel_real);
        } else {
            lcd.printf("%d",temp_sel);
            lcd.locate(8,1);
            if(time_sel<100)
                lcd.printf("0%d ",time_sel);
            else
                lcd.printf("%d ",time_sel);
        }

    }
}

void leer_pulsador()
{
    if (enable_contador) {//Detecta que pulsador está apretado y realiza la acción correspondiente con su variable
        enable_contador = 0;
        if(int_puls_start.read() == apretado) {
            if(!start)
                start = 1;
            else
                start = 0;
        }
        if(int_puls_luz.read() == apretado) {
            if(!luz)
                luz = 1;
            else
                luz = 0;
        }
        if(int_puls_coccion.read() == apretado && state == off) {
            printf("%d",coccion_sel);
            lcd.locate(0,0);
            lcd.printf("                ");
            if(coccion_sel<7)
                coccion_sel++;
            else
                coccion_sel = 2;
        }
        if(int_encoder1.read() == apretado) {
            printf("%d\n",temp_sel_real);
            if(encoder1_b == 0) {
                if(temp_sel_real < 280)
                    temp_sel_real++;
            } else if(temp_sel_real > 100)
                temp_sel_real--;
        }
        if(int_encoder2.read() == apretado) {
            printf("%d\n",time_sel_real);
            if(encoder1_b == 0) {
                if(time_sel_real < 240)
                    time_sel_real++;
            } else if(time_sel_real > 1)
                time_sel_real--;
        }
    }
    if(enable_pulsador == 1) {
        enable_pulsador = 0;
    }
}

void leer_potes()
{
    //Asigna los valores de las entradas analógicas a las variables correspondientes
    temp_sel_real = (entrada_temp_sel.read()*120)+100;//Temperatura
    time_sel_real = entrada_time_sel.read()*240;//Tiempo
    temp_med = (entrada_temp.read_u16()*0.005)+180;//Temperatura medida por LM35
}

void detect()
{
    //Detecta una interrupción y activa el contador
    if (cont_antirrebote == 0 && enable_pulsador == 0) {
        cont_antirrebote = 20;
        enable_pulsador = 1;
    }
}
void timer_antirrebote()
{
    if (cont_antirrebote > 0) {//Resta la variable de antirrebote cada 1ms
        cont_antirrebote--;
        if(!cont_antirrebote)
            enable_contador = 1;
    }
}

void timer_refresh()
{
    if(cont_refresh > 0)//Resta cada 10ms
        cont_refresh--;
}

void timer_principal()
{
    if(time_sel > 0 && state != off)//Resta cada 1 segundo si el horno está en funcionamiento
        time_sel--;
}