PID para el control de voltaje de un capacitor en un circuito RC

Dependencies:   Debounced TextLCD mbed

Fork of pid_teclas by Gustavo Ramirez

/media/uploads/PabloViana/general.jpg

main.cpp

Committer:
PabloViana
Date:
2015-10-01
Revision:
1:19ecfc5a15c7
Parent:
0:9aa80672eb3d

File content as of revision 1:19ecfc5a15c7:

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

AnalogIn MedidaAnaloga(PTC2);//Medida de tensión
AnalogOut SalidaAnaloga(PTE30);//Salida analoga;
TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7

DigitalOut led1(LED1);
DigitalOut led2(LED2);
DigitalOut led3(LED3);
DebouncedIn Incrementar(PTC17);//
DebouncedIn Decrementar(PTC16);
DebouncedIn Saltar(PTC13);
DebouncedIn IniciarPID(PTC12);

int C1=0x0F;//Inicializar el cursor;
float sp=1;
int kp=25,kd=0,ki=10,p=1; 
float errormV = 0; //Variable en la que almacenaré la diferencia entre el set point  la medida real;
float ek_1=0; //Error en el instante de tiempo anterior;
float medidamV=0;//Variable en la que almacenaré la medida en mV;
float PID;

//Variables del PID
    float Proporcional;
    float Derivativo;
    float Integrativo;
//Función del PID//
void ControlPID()
{
    
    Proporcional= kp*errormV;
    Integrativo= (ki*errormV) + Integrativo;
    if(Integrativo>999){Integrativo=999;}//Saturo la salida;
    Derivativo = kd*(errormV-ek_1);
    ek_1=errormV;//Almaceno el valor para el instante de tiempo sieguiente;
    PID = Proporcional + Integrativo + Derivativo;
    if (PID>999){PID=999;}//Saturo la salida;
    if (PID<0){PID=0;}//saturo la salida
    
 
    SalidaAnaloga = PID/999; //Escrino en la salida;
}
//Función lectura de botones
void Botones()
/*¡¡¡CÓDIGO RECICLADO!!!!, en este caso se debe considerar que se usarán pulsadores normalmente abiertos,
por esta razón los evento a considerar son los flancos de subida, detectados mediante el la instrucción ".rising" */
{
        if (Incrementar.rising())
        {
            led1 =!led1;
            if (p==1)
            {
                sp=sp+0.1;
                if(sp>3.3){sp=3.3;}//Limito el valor del Set Point;
                lcd.locate(3,0);
                lcd.printf("   ");
                lcd.locate(3,0);
                lcd.printf("%0.1f", sp);
            }
            else if (p==2)
            {
                ++kp;
                lcd.locate(11,0);
                lcd.printf("   ");
                lcd.locate(11,0);
                lcd.printf("%d", kp);
            }
            else if (p==3)
            {
                ++ki;
                lcd.locate(3,1);
                lcd.printf("   ");
                lcd.locate(3,1);
                lcd.printf("%d", ki);
            }
            else if (p==4)
            {
                ++kd;
                lcd.locate(11,1);
                lcd.printf("   ");
                lcd.locate(11,1);
                lcd.printf("%d", kd);
            }
        }
        if (Decrementar.rising())
        {
            led2 =!led2;
            if (p==1)
            {
                if (sp==0)  // no mostrar nada
                {
                }
                else
                {
                    sp=sp-0.1;
                    if(sp<0){sp=0;}//Limito el valor del Set Point
                    lcd.locate(3,0);
                    lcd.printf("   ");
                    lcd.locate(3,0);
                    lcd.printf("%.1f", sp);
                }
            }
            if (p==2)
            {
                if (kp==0)  // no mostrar nada
                {
                }
                else
                {
                    --kp;
                    lcd.locate(11,0);
                    lcd.printf("   ");
                    lcd.locate(11,0);
                    lcd.printf("%d", kp);
                }
            }
            if (p==3)
            {
                if (ki==0)  // no mostrar nada
                {
                }
                else
                {
                    --ki;
                    lcd.locate(3,1);
                    lcd.printf("   ");
                    lcd.locate(3,1);
                    lcd.printf("%d", ki);
                }
            }
            if (p==4)
            {
                if (kd==0)  // no mostrar nada
                {
                }
                else
                {
                    --kd;
                    lcd.locate(11,1);
                    lcd.printf("   ");
                    lcd.locate(11,1);
                    lcd.printf("%d", kd);
                }
            }
        }
        if (Saltar.rising())
        {
            led3 =!led3;
            if (p==1)
            {
                ++p;
                lcd.locate(11,0);
                lcd.printf("%d", kp);
                
                
            }
            else if (p==2)
            {
                ++p;
                lcd.locate(3,1);
                lcd.printf("%d", ki);
                lcd.locate(3,1);
                
            }
            else if (p==3)
            {
                ++p;
                lcd.locate(11,1);
                lcd.printf("%d", kd);
                
                
            }
            else if (p==4)
            {
                p=1;
                lcd.locate(3,0);
                lcd.printf("%.1f", sp);
                
                
            }
        }    
    
    
}//Botones



//Inicio la función principal;
int main()
{   int contador=0;
    lcd.cls();
    lcd.writeCommand(C1);//Mando al LCD el comano que inicializa el cursor
    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);
    lcd.locate(0,0);
    lcd.printf("Sp=%.1f", sp);
    SalidaAnaloga=0;
    
    while(1) //Iniciar Ciclo Infinito
    {
        Botones(); //Inicia la función que revisa el estado de los botones
        
        if(IniciarPID.rising()) //Se presiona el botón Iniciar PID
        {
           lcd.cls();//Borrar pantalla;
           lcd.locate(0,0);
           lcd.printf("PID...");
           wait(1);
           lcd.cls();//Borrar pantalla;
           break; // Termino el ciclo infinito;
        }//if
    }//while
    
    while(1)//ciclo infinito para el PID
    {
    medidamV=MedidaAnaloga*3300;//La medida es convertida a un valor en mV, siendo el máximo valor esperado 3300mV (3.3V)
    
    errormV= (sp*1000)- medidamV; //Estoy ingresando un valor en V, pero opero internamente en mV
    contador++; //Contador para actualizar la pantalla cada cierto número de ciclos;
    if(contador ==10)
    {
        lcd.cls();
        lcd.locate(0,0);
        lcd.printf("Sp:%.2fV", sp);//Muestro el set point;
        
        lcd.locate(0,1);
        lcd.printf("M:%.2fV", medidamV/1000);//Muestro la medida;
        
        lcd.locate(8,1);
        lcd.printf("E:%.2fV", errormV/1000);//Muestro el error;   
        
        lcd.locate(9,0);
        lcd.printf("U:%.1fV",PID*3.3/999); //Muestro el esfuerzo de control
        contador=0;//Reinicializo el contador;             
    }//if
    ControlPID();//Llamo la función PID;
    if(Incrementar.rising()){sp=sp+0.5;}
    if(sp>3.3){sp=3.3;}//Limito el valor del Set Point;
    if(Decrementar.rising()){sp=sp-0.5;}
    if(sp<0){sp=0;}//Limito el valor del Set Point;
    wait(0.05);//Espero un tiempo;
    }
}