Controlador PWM de temperatura Por Medio de accion por PWM... Lectura y filtro digiral de lectura de temperatura de Sensor LM35 a entradas análogas. Accionamiento de potencia por medio de Relés. Link De La Implementación: https://www.youtube.com/watch?v=gcQtUNqF5M0&list=UULR7eSOJgpTUlpzbloXAgIQ

Dependencies:   DebouncedIn QEI TextLCD_encoder mbed

Fork of PID_Encoder by Gustavo Ramirez

main.cpp

Committer:
payarito32
Date:
2014-11-16
Revision:
5:e3a1ff046504
Parent:
4:d42fe3777735

File content as of revision 5:e3a1ff046504:

#include "mbed.h"
#include "DebouncedIn.h"
#include "TextLCD.h"
#include "QEI.h"

TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7 entradas del LCD
QEI wheel (PTD7, PTD6, NC, 100); // entradas para el ENCODER
AnalogIn LM(PTB0); // temperatura leida por un LM35
PwmOut bomb(PTC5); //salida para activar un bombillo
PwmOut vent(PTC4); //salida para activar un ventilador
DigitalOut led3(LED3); // Led para indicar que los botones se presionan
DebouncedIn button3(PTC16); //boton 3 es el pulsador del ENCODER
DebouncedIn button4(PTA13); // boton 4 es para la configuración de las constantes del pid, de tiempo de rampa y de temperatura del horno

//codigos movimiento del curzor LCD
int C2=0x18; // desplaza izquierda
int C3=0x1A; // desplaza derecha
int C4=0x0C; // quito cursor bajo
int C1=0x0F; // solo muestra el curzor
Serial pc(USBTX, USBRX, "pc");

//definicion de varibles
int i=1; // i controla cambio de "modo" del boton 4. i=1 -> (constantes PID), i=2 -> (Tiempo y temperatura)
int j=1; //j controla cambio de posiciones para cambiar variable (con el boton del ENCODER)
int kp, ki, kd, sp; //constantes del pid y del setpoint
int t1, t2, t3; //tiempos de la rapmpa de subida, temperatura estable y tiempo de bajada t1=t2=t3 [segundos]
int temp=50; // temp:temperatura final a la que llega el horno[ºC]
float ta; // ta: temperatura ambiente que se lee con el LM35, antes de empezar control
float yr, ap, ai, ad, err, med, err_v, cycle, pid; //
float dt1, dt2, dt3,c=0; // variables para ciclos de control en tiempos t1, t2 y t3
int b=0; // Se usa para imprimir datos en la LCD
float pidn;
Timer t;

// Inicia el código
int main()
{
    
    kp =60;
    ki = 10;
    kd=4;
    t1 = 5;
    t2= 5;
    t3=20;
    temp = 50;
    while(1) {
        if(i==1) {
            lcd.cls();
            lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD
            lcd.locate(0,0);
            lcd.printf(" PID");
            lcd.locate(8,0);
            lcd.printf("Kp:%d",kp);
            lcd.locate(0,1);
            lcd.printf("Ki:%d",ki);
            lcd.locate(8,1);
            lcd.printf("Kd:%d",kd);

            led3 =1;
            if (button3.falling()) {  //INCREMENTA POSICION DEL MENU CON BOTON 3 (Switche encoder)
                led3 =!led3;
            }

            if (j==1) {
                kp=kp+wheel.getPulses();
                wheel.reset();
                if (kp>999) {
                    kp=999;
                }
                if (kp<0) {
                    kp=0;
                }
                lcd.locate(11,0);
                lcd.printf("     ");
                lcd.locate(11,0);
                lcd.printf("%d",kp);
                wait(0.2);

                if(button3.falling()) {
                    j=2;
                    led3=0;
                    wait(0.3);
                    wheel.reset();
                }
            }
            if (j==2) {
                ki=ki+wheel.getPulses();
                wheel.reset();
                if (ki>999) {
                    ki=999;
                }
                if (ki<0) {
                    ki=0;
                }
                lcd.locate(3,1);
                lcd.printf("     ");
                lcd.locate(3,1);
                lcd.printf("%d",ki);
                wait(0.2);

                if(button3.falling()) {
                    j=3;
                    led3=0;
                    wait(0.3);
                    wheel.reset();
                }
            }
            if (j==3) {
                kd=kd+wheel.getPulses();
                wheel.reset();
                if (kd>999) {
                    kd=999;
                }
                if (kd<0) {
                    kd=0;
                }
                lcd.locate(11,1);
                lcd.printf("     ");
                lcd.locate(11,1);
                lcd.printf("%d",kd);
                wait(0.2);

                if(button3.falling()) {
                    j=1;
                    led3=0;
                    wait(0.3);
                    wheel.reset();
                }
            }
            if (j==4) {
                j=1;
            }
            if(button4.falling()) {
                i=2;
                j=0;
            }
        }//CIERRA EL MODO i=1 -> constantes PID
        if(i==2) { //INICIA EL MODO i=2 -> tiempos y temperatura
            lcd.cls();
            lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD
            lcd.locate(0,0);
            lcd.printf("T1:%d",t1);
            lcd.locate(8,0);
            lcd.printf("T2:%d",t2);
            lcd.locate(0,1);
            lcd.printf("T3:%d",t3);
            lcd.locate(8,1);
            lcd.printf("Tm:%d",temp);


            led3 =1;
            if (button3.falling()) {  //INCREMENTA POSICION DEL MENU CON BOTON 3 (Switche encoder)
                led3 =!led3;
            }
            if (j==0) {
                t1=t1+wheel.getPulses();
                wheel.reset();
                if (t1>5*60) { // Tiempos no mayores a 6 minutos
                    t1=5*60;
                }
                if (t1<60) {
                    t1=60;
                }
                lcd.locate(3,0);
                lcd.printf("   ",t1);
                lcd.locate(3,0);
                lcd.printf("%d",t1);
                wait(0.2);

                if(button3.falling()) {
                    j=1;
                    led3=0;
                    wait(0.3);
                    wheel.reset();
                }
            }

            if (j==1) {
                t2=t2+wheel.getPulses();
                wheel.reset();
                if (t2>5*60) {
                    t2=5*60;
                }
                if (t2<60) {
                    t2=60;
                }
                lcd.locate(11,0);
                lcd.printf("   ");
                lcd.locate(11,0);
                lcd.printf("%d",t2);
                wait(0.2);

                if(button3.falling()) {
                    j=2;
                    led3=0;
                    wait(0.3);
                    wheel.reset();
                }
            }
            if (j==2) {
                t3=t3+wheel.getPulses();
                wheel.reset();
                if (t3>5*60) {
                    t3=5*60;
                }
                if (t3<60) {
                    t3=60;
                }
                lcd.locate(3,1);
                lcd.printf("     ");
                lcd.locate(3,1);
                lcd.printf("%d",t3);
                wait(0.2);

                if(button3.falling()) {
                    j=3;
                    led3=0;
                    wait(0.3);
                    wheel.reset();
                }
            }
            if (j==3) {
                temp=temp+wheel.getPulses();
                wheel.reset();
                if (temp>60) {
                    temp=60;
                }
                if (temp<20) {
                    temp=20;
                }
                lcd.locate(11,1);
                lcd.printf("     ");
                lcd.locate(11,1);
                lcd.printf("%d",temp);
                wait(0.2);

                if(button3.falling()) {
                    j=0;
                    led3=0;
                    wait(0.3);
                    wheel.reset();
                }
            }
            if (j==4) {
                j=0;
            }
            if (button4.falling()) {
                break;
            }
        }//CIERRE MODO i=2 -> tiempo y temperatura
    }// Cierre del while(1)
//%---------------------------------------------------------------------


    lcd.writeCommand(C4);//escribimos un comando segun el manual del modulo LCD para quitar cursor bajo
    lcd.cls(); //borra la pantalla
    lcd.printf("Valores \nGuardados");
    wait(1);

    ta=100*3*LM.read()-13;
    lcd.cls(); //borra la pantalla
    lcd.printf("T Ambiente:%2f",ta);
    wait(2);

    // se imprimen los parches del control  *****************************************
    lcd.cls();
    lcd.printf("Er:%f",err);
    lcd.locate(8,0);
    lcd.printf("Me:%f",med);
    lcd.locate(0,1);
    lcd.printf("dt:%f",dt1);
    wait(2);

    // CICLO PARA CONTROL DE RAMPA ASCENDENTE (T1)
    b=0;
    // Comienza el ciclo for para la primera parte del control(Rampa ascendente)
    for(dt1=ta; dt1<=temp; dt1+=(temp-ta)/t1 ) {
        med=100*3*LM.read()-13;  //leer puerto analogo y asignar a med (*100 ya que LM35 da 10mV/ºC)
        err = (dt1-med);
        ap = kp*err;   //calculo de la acción proporcional
        // se verifica que la accion integral no sea muy grande
        if(ai<100) {
            ai =(ki*err)+ai;    //calculo de la integral del error
        }
        ad = kd*(err-err_v); //calculo de la accion derivativa
        pid = (ap+ai+ad);
        // se verifica que pid sea positivo **************************************
        if(pid<=0) {
            pid=0;
        }
        // se verifica que pid sea menor o igual la valor maximo *****************
        if(pid>=100) {
            pid=100;
        }
        // se actualizan las variables *******************************************
        err_v = err;
        //se muestran las variables******************************************
        //if (b==0) {
        //  t.start();
        //    b=1;
        //}
        //if(t>=0.01) {
        lcd.cls();
        lcd.locate(0,0);
        lcd.printf("Er:%f",err);
        lcd.locate(8,0);
        lcd.printf("Me:%f",med);
        lcd.locate(0,1);
        lcd.printf("dt:%f",dt1);
        //}
        //Normalizacion de la salida
        pidn=pid/100;
        //  se envia el valor pid a puerto analogico de salida (D/A) **************
        bomb.write(pidn);
        //  se repite el ciclo
        wait(1);
    }
    // Comienza el segundo ciclo para la segunda parte del control (Temperatura estable)
    t.start();
    while(t<=t2) {
        med=100*3*LM.read()-13;  //leer puerto analogo y asignar a med (*100 ya que LM35 da 10mV/ºC)
        err = (temp-med);
        ap = kp*err;   //calculo de la acción proporcional
        // se verifica que la accion integral no sea muy grande
        if(ai<100) {
            ai =(ki*err)+ai;    //calculo de la integral del error
        }
        ad = kd*(err-err_v); //calculo de la accion derivativa
        pid = (ap+ai+ad);
        // se verifica que pid sea positivo **************************************
        if(pid<=0) {
            pid=0;
        }
        // se verifica que pid sea menor o igual la valor maximo *****************
        if(pid>=100) {
            pid=100;
        }
        // se actualizan las variables *******************************************
        err_v = err;
        //se muestran las variables******************************************
        //if (b==0) {
        //  t.start();
        //    b=1;
        //}
        //if(t>=0.01) {
        lcd.cls();
        lcd.locate(0,0);
        lcd.printf("Er:%f",err);
        lcd.locate(8,0);
        lcd.printf("Me:%f",med);
        lcd.locate(0,1);
        lcd.printf("Tm:%d",temp);
        //}
        //Normalizacion de la salida
        pidn=pid/100;
        //  se envia el valor pid a puerto analogico de salida (D/A) **************
        bomb.write(pidn);
        //  se repite el ciclo
        wait(1);
    }
    bomb=0;
    ta=3*100*LM.read()-13;
    // Comienza el tercerciclo para la ultima parte del control (Descenso de rampa)
    for(dt3=temp; dt3>=ta; dt3-=(temp-ta)/t3 ) {
        med=100*3*LM.read()-13;  //leer puerto analogo y asignar a med (*100 ya que LM35 da 10mV/ºC)
        err = (dt3-med);
        ap = kp*err;   //calculo de la acción proporcional
        // se verifica que la accion integral no sea muy grande
        if(ai<100) {
            ai =(ki*err)+ai;    //calculo de la integral del error
        }
        ad = kd*(err-err_v); //calculo de la accion derivativa
        pid = (ap+ai+ad);
        // se verifica que pid sea positivo **************************************
        if(pid<=0) {
            pid=0;
        }
        // se verifica que pid sea menor o igual la valor maximo *****************
        if(pid>=100) {
            pid=100;
        }
        // se actualizan las variables *******************************************
        err_v = err;
        //se muestran las variables******************************************
        //if (b==0) {
          //  t.start();
        //    b=1;
        //}
        //if(t>=0.01) {
            lcd.cls();
            lcd.locate(0,0);
            lcd.printf("Er:%f",err);
            lcd.locate(8,0);
            lcd.printf("Me:%f",med);
            lcd.locate(0,1);
            lcd.printf("dt:%f",dt3);
        //}
        //Normalizacion de la salida
        pidn=pid/100;
        //  se envia el valor pid a puerto analogico de salida (D/A) **************
        vent.write(pidn);
        //  se repite el ciclo
        wait(1);
    }
    bomb=0;
    vent=0;
    lcd.cls();
    lcd.printf("fin");
}