Control PID para un planta RC (control de la carga del capacitor), los parámetros se ingresan por medio de 4 pulsadores, teniendo en cuenta una librería antirebote y el resultado del control se visualiza en una pantalla LCD 16x2.

Dependencies:   TextLCD mbed

Fork of DebouncedIn_HelloWorld by Chris Styles

/media/uploads/Wilmar87/img_4005.jpg

main.cpp

Committer:
Wilmar87
Date:
2013-12-13
Revision:
1:3e6a41eba6bb
Parent:
0:672241227e0d

File content as of revision 1:3e6a41eba6bb:

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

AnalogIn Vin(PTC2);
AnalogOut Vout(PTE30);

TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); //Puertos LCD rs, e, d4, d5, d6, d7
 
DigitalOut led1(LED1);      //led de cambio de posición
DigitalOut led2(LED2);      //led incremento de parámetros
DigitalOut led3(LED3);      //led decremento de parámetros
DebouncedIn bot1(PTC12);    //cambiar la posición
DebouncedIn bot2(PTC13);    //incrementar variable
DebouncedIn bot3(PTC16);    //decrementar variable
DebouncedIn bot4(PTC17);    //salida de bucle
  
   //Códigos LCD
int C1=0x0E;            // Muestra el cursor
// 0x18;                // desplazamiento izquierda
// 0x1A;                // desplazamiento derecha
int C4=0x0C;            // Quita el cursor
                     
                     
int a, sp, kp, ki, kd, ciclo; // indice de la variable
float med, sp0, ap, err, ai, ad, pid, err_v;

 
int main() {

    led1=led2=led3=1;
    lcd.printf("Control PID");
    wait(1.5);
    lcd.cls();
    
    lcd.writeCommand(C1);          //Comando para mostrar el cursor en el LCD                   
    lcd.locate(0,0);               //Ubica e imprime nombre de las variables en la LCD
    lcd.printf("Sp=%d",sp);
    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);
   
    
    //Inicio del ciclo
        
    while(1) {
           if (bot1.falling()) {      //Aumenta posición el cursor       
               a++;
               led1=0;
               wait(.15);             //enciende el led azul cada vez que se oprime este botón
               led1=1;
               if (a>3){
               a = 0;
               }   
               switch (a) {
               case 0:
               
               lcd.locate(2,0);
               lcd.printf("=");
               break;
               
               case 1:
               lcd.locate(10,0);
               lcd.printf("=");
               break;
               
               case 2:
               lcd.locate(2,1);
               lcd.printf("=");
               break;
               
               case 3:
               lcd.locate(10,1);
               lcd.printf("=");
               break;
               }
           }
               
                        if  (bot2.falling()) {      //Incrementa la variable      
                            led2=0;
                            wait(.15);              //enciende el led verde cada vez que se oprime el botón de incremento
                            led2=1;
                            
                            switch (a) {
                            case 0:
               
                            lcd.locate(2,0);        //Ubica el parámetro Set-point
                            lcd.printf("=  ");
                            lcd.locate(3,0);
                            lcd.printf("%d", ++sp);
                            break;
               
                            case 1:
                            lcd.locate(10,0);       //Ubica el parámetro kp
                            lcd.printf("=  ");
                            lcd.locate(11,0);
                            lcd.printf("%d", ++kp);
                            break;
               
                            case 2:
                            lcd.locate(2,1);        //Ubica el parámetro ki
                            lcd.printf("=  ");
                            lcd.locate(3,1);
                            lcd.printf("%d", ++ki);
                            break;
                            
                            case 3:
                            lcd.locate(10,1);       //Ubica el parámetro kd
                            lcd.printf("=  ");
                            lcd.locate(11,1);
                            lcd.printf("%d", ++kd);
                            break;
                    }
               }
                                  if   (bot3.falling()) {      //Decrementa la variable      
                                     wait(0.1);
                                     led3=0;
                                     wait(.15);             //enciende el led roja cada vez que se oprime este botón
                                     led3=1;
                                     
                                     switch (a) {
                                     case 0: 
                                     if (sp<0) {            //No se admite valores negativos
                                      sp=0;
                                      }                                                                                                                             
                                     lcd.locate(2,0);       //Ubica el parámetro Set-point
                                     lcd.printf("=    ");
                                     lcd.locate(3,0);
                                     lcd.printf("%d",sp--);
                                     break;
                                     
                                     case 1:
                                     if (kp<0) {            //No se admite valores negativos
                                     kp=0;
                                     }
                                     lcd.locate(10,0);      //Ubica el parámetro kp
                                     lcd.printf("=    ");
                                     lcd.locate(11,0);
                                     lcd.printf("%d",kp--);
                                     break;
                                       
                                     case 2:
                                     if (ki<0) {             //No se admite valores negativos
                                     ki=0;
                                     }
                                     lcd.locate(2,1);        //Ubica el parámetro ki 
                                     lcd.printf("=    ");
                                     lcd.locate(3,1);
                                     lcd.printf("%d",ki--);
                                     break;
                                       
                                     case 3:
                                     if (kd<0)  {            //No se admite valores negativos
                                     kd=0;
                                     }
                                     lcd.locate(10,1);       //Ubica el parámetro kd
                                     lcd.printf("=    ");
                                     lcd.locate(11,1);
                                     lcd.printf("%d",kd--);
                                     break;
                                }
                          }
                           if (bot4.falling()){         //sale del bucle de la pantalla
                           led1=led2=led3=0;            //Flash para salir del bucle
                           wait(0.25);
                           led1=led2=led3=1;
                           break;                                                 
                     }  
                  }              
           lcd.writeCommand(C4);                                   //Quita el cursor bajo del LCD
           lcd.cls();                                              //borra la pantalla
           lcd.printf("GUARDADOS!"); 
           wait(2);
           lcd.cls();
           lcd.printf("INICIA EL PID");
           wait(2);
                                                                   // se imprimen los parches del control  *****************************************
           lcd.cls();
                 
           lcd.printf("Er%d",err);
           lcd.locate(8,0);
           lcd.printf("Me%d",med);
           lcd.locate(0,1);
           lcd.printf("Sp%d",sp0);
           lcd.locate(8,1);
           lcd.printf("Pid%d",pid);
                      
           // CICLO PRINCIPAL CONTROLADOR PID
         
           while(1) {
           
           wait(0.001);
           //leer puerto analogo y asignar a med
           
           
           med = (Vin*3.27);
           sp0 = sp*0.0327;
           err = (sp0-med); 
           float kp0;
           kp0 = kp*0.001;
           ap = kp0*err;
           float ki0;
           ki0 = ki*0.001;      
           ai =  (ki0*err)+ai;     //calculo de la integral del error
           float kd0;
           kd0 = kd*0.0001;
           ad =  kd0*(err-err_v);  //calculo de la accion derivativa
           pid = ap+ai+ad;
           
           
              // se verifica que pid sea menor o igual la valor maximo *****************
           if (pid > 0.999){
           pid=1;
           } 
           
           // se verifica que pid sea positivo **************************************
           if (pid < 0){
           pid=0;
           } 
                 
           // se verifica que la accion integral no sea muy grande
           if (ai > 999){
           ai=1000;
           } 
                     
           Vout=(pid);                
                                //Mostrar resultados PID
          if(ciclo>700)  {         
           lcd.locate(2,0);
           lcd.printf("      "); 
           lcd.locate(0,0);
           lcd.printf("Er%2.1f",err);
           lcd.locate(10,0);
           lcd.printf("      ");
           lcd.locate(8,0);
           lcd.printf("Me%4.2f",med);
           lcd.locate(2,1);
           lcd.printf("      ");
           lcd.locate(0,1);
           lcd.printf("Sp%4.2f",sp0);
           lcd.locate(10,1);
           lcd.printf("      ");
           lcd.locate(8,1);
           lcd.printf("Pid%4.3f",pid);
           ciclo=0;
           }
           else 
           ciclo++;     
           err_v = err;  //guarda el error 
          }      //  Envía parámetro pid al puerto analogico de salida (D/A) y se repite el ciclo
      }