PID que funciona con pulsadores y tiene autotunning.

Dependencies:   Debounced QEI TextLCD mbed

Revision:
0:2d05e443a44d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/PID.CPP	Tue Nov 28 19:48:57 2017 +0000
@@ -0,0 +1,487 @@
+#include "mbed.h"
+#include "TextLCD.h"
+#include "DebouncedIn.h"
+
+TextLCD lcd(PTB8, PTB9,PTB10,PTB11,PTE2, PTE3);
+
+AnalogIn Vin(PTC2);        
+AnalogOut Vout(PTE30);     
+
+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 P1(PTC16);    //Pulsador que aumenta
+DebouncedIn P2(PTC13);    //SET 
+DebouncedIn P3(PTC12);    //Pulsador que disminuye
+int t2;
+int o2=0;
+float t1;
+int B;
+
+float ko,Kp,Ki,Kd,kc,TC;
+int AT=0;
+int i=1;
+int j=1;
+int k=1;
+int v6;
+int q;
+int q2;
+char D[30];
+float v2;
+//------------------------------------------------------------------------------
+int a, sp, kp, ki, kd, ciclo; // indice de la variable
+float med, sp0, ap, err, ai, ad, pid, err_v;
+
+   //Códigos LCD
+int C1=0x0E;            // Muestra el cursor
+// 0x18;                // desplazamiento izquierda
+// 0x1A;                // desplazamiento derecha
+int C4=0x0C;            // Quita el cursor
+
+
+Timer t;
+
+int p=1;
+int main()
+{
+    led1=led2=led3=1;
+    lcd.cls();          //limpio la pantalla
+    lcd.locate(5,1);
+    lcd.printf("BIENVENIDO");
+    wait(1.5);
+    lcd.cls();
+    //lcd.writeCommand(int 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);
+    
+    while(true){    if ((P1.rising())&&(P3.rising())){      
+                                                AT=1;
+                        if (AT==1){
+                                                if(p==1){
+                                                lcd.cls();          //limpio la pantalla
+                                                lcd.locate(5,1);
+                                                lcd.printf("AUTOTUNING");
+                                                wait(1.5);
+                                                lcd.cls();
+                                                
+                                                sp=2;  //Set point inicial
+                                                p=2;   
+                                                }
+                                                if (p==2){
+                                              for (Kp=0.5;Kp<2;Kp=Kp+0.1){
+                                                
+                                                if (j==1 && k==1 && v6==0){
+                                                for (i=1;i<20;i++){
+                                                            pid=999;
+                                                            Vout=(pid/999); 
+                                                            v2=(Vin.read())*3300;//la medicion es convertida a un valor en mV,siendo el máximo valor esperado 3300mV (3.3V)
+                                                            float kp0;
+                                                            sp0 = sp;
+                                                            err = (sp0*1000-v2); //Estoy ingresando un valor en V, pero opero internamente en mV
+                                                            kp0 = Kp;
+                                                            ap = kp0*err;
+                                                            pid = ap;
+                                                            
+                                                            if (pid>999){pid=999;}
+                                                            if (pid<0){pid=0;}
+                                                
+                                                            Vout=(pid/999); 
+                                                      //      lcd.locate(5,1);
+                                                        //    lcd.printf("y %4.2f",v2/1000);
+                                                          //   lcd.locate(0,0);
+                                                          //  lcd.printf("i %d",i);
+                                                               lcd.locate(5,1);
+                                                               lcd.printf("Leyendo..");
+                                                            D[i]=v2/1000;
+                                                            
+                                                            led1=0;
+                                                            wait(1);
+                                                            led1=1;
+                                                            }
+                                                            }
+                                                                  lcd.cls();                       
+                                                if (i==20 && k==1 && v6==0){
+                                                
+                                                for (j=1;j<20;j=j+2)    {
+                                                    //lcd.locate(0,0);
+                                                    //lcd.printf("j %d",j); 
+                                                                                      
+                                                            if (D[j]==D[j+2]){ 
+                                                            led2=0;
+                                                            q=q++;
+                                                            lcd.locate(5,1);
+                                                            lcd.printf("Operando..");
+                                                            wait(1);
+                                                                                }
+                                                                        }
+                                                                        
+                                                                    }
+                                                lcd.cls();
+                                                
+                                                if(j==21 && i==20 && k!=21 && v6==0){
+                                                    for(k=1;k<20;k=k+2) {
+                                                 //lcd.locate(0,0);
+                                                   // lcd.printf("k %d",k);     
+                                                    if (D[k+1]==D[k+3]){ 
+                                                    led3=0;
+                                                    led2=1;
+                                                    q2=q2++;
+                                                    lcd.locate(5,1);
+                                                    lcd.printf("Analisis...");
+                                                    wait(1);}
+                                                    
+                                                                    }
+                                                                                                
+                                                       }
+                                                                                             
+                                                        lcd.cls();
+                                                
+                                                 
+                                                if (i==20 && j==21 && k==21 && q>8 && q2>8){
+                                                    led2=0;
+                                                    kc=Kp;
+                                                    p=3;
+                                                    v6=1;
+                                                    lcd.locate(5,1);
+                                                    lcd.printf("Terminado");
+                                                    wait(1);
+                                                    lcd.cls();
+                                                    lcd.printf("KC: %4.2f",Kp);
+                                                    wait(1);
+                                                    //UTILIZO A ESTE KP COMO GANANCIA CRITICA
+                                               
+                                                    break;
+                                                                }
+                                                    if(i==20 && j>20 && k==21 && q<=8 && q2<=8){
+                                                                        lcd.locate(5,1);
+                                                                        lcd.printf("Terminado");
+                                                                        wait(1);
+                                                                        lcd.cls();
+                                                                        lcd.printf("NO ES LA KC");
+                                                                       wait(1);
+                                                                       lcd.cls();
+                                                                        i=1;
+                                                                        j=1;
+                                                                        k=1;
+                                                                        q=0;
+                                                                        q2=0;
+                                                                        }
+                                                                            }
+                                                                                               
+                                                }                                                               
+                                             }
+                                             if (v6==1){
+                                                 TC=1;
+                                                 Kp=0.59*kc;
+                                                 Ki=1.18*kc*(1/TC);
+                                                 Kd=0.074*kc*TC;
+                                                    
+                                                 lcd.cls();
+                                                 lcd.printf("INICIA EL PID");
+                                                 wait(2);
+                                                               // se imprimen los parches del control  *****************************************
+                                                
+                                                   lcd.locate(0,0);
+                                                   lcd.printf("E:%d");
+                                                   lcd.locate(8,0);
+                                                   lcd.printf("Y:%d");
+                                                   lcd.locate(0,1);
+                                                   lcd.printf("Sp:%d");
+                                                   lcd.locate(8,1);
+                                                lcd.printf("Co:%0.1f");
+                                              // CICLO PRINCIPAL CONTROLADOR PID
+                                                                                 
+                                                                                 while(1) {
+                                                                                   
+                                                                             wait(0.001);
+                                             //                                                                                                        
+                                                                             v2 = (Vin.read()*3300);//la medicion es convertida a un valor en mV,siendo el máximo valor esperado 3300mV (3.3V)
+                                                                             sp0 = sp;
+                                                                             err = (sp0*1000-v2); //Estoy ingresando un valor en V, pero opero internamente en mV
+                                                                             float kp0;
+                                                                             kp0 = Kp;
+                                                                             ap = kp0*err;
+                                                                             float ki0;
+                                                                             ki0 = Ki;        
+                                                                             ai =  (ki0*err)+ai;     //calculo de la integral del error
+                                                                             float kd0;
+                                                                             kd0 =Kd;
+                                                                             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 > 999){
+                                                                                   pid=999;
+                                                                                  } // 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/999);                
+                                                                                                        //Mostrar resultados PID
+                                                                                  if(ciclo>700)  {         
+                                                                                  lcd.locate(2,0);
+                                                                                  lcd.printf("      "); 
+                                                                                  lcd.locate(0,0);
+                                                                                  lcd.printf("E:%4.2f",err/1000);
+                                                                                  lcd.locate(10,0);
+                                                                                  lcd.printf("      ");
+                                                                                lcd.locate(8,0);
+                                                                                  lcd.printf("Y:%4.2f",v2/1000);
+                                                                                  lcd.locate(2,1);
+                                                                                           lcd.printf("      ");
+                                                                                        lcd.locate(0,1);
+                                                                                       lcd.printf("Sp:%4.2f",sp0);
+                                                                                        lcd.locate(10,1);
+                                                                                   lcd.printf("      ");
+                                                                                   lcd.locate(11,1);
+                                                                                    lcd.printf(":%0.1f",pid*3.3/999);
+                                                                                    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 cicl                                                                                                            
+                   }
+                   }
+                                                                                            
+                                                                                                   
+                                                                                                                                                                       
+                     else{                                         
+                    if (AT==0){
+                                                
+                    if (P2.rising()) {      //Cambia la posición del cursor  
+                       
+                       a++;
+                       led1=0;
+                       wait(0.15);     //enciende el led rojo 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  (P1.rising()) {      //Incrementa la variable      
+                            led2=0;
+                            wait(0.15);              //enciende el led verde cada vez que se oprime el botón de incremento
+                            led2=1;
+                            
+                                        switch (a) {
+                                        case 0:
+                                        if (sp>3){
+                                                    sp=3;}
+                                        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>999){
+                                                    kp=999;}
+                                        lcd.locate(10,0);       //Ubica el parámetro kp
+                                        lcd.printf("=  ");
+                                        lcd.locate(11,0);
+                                        lcd.printf("%d", ++kp);
+                                              
+                                        break;
+                           
+                                        case 2:
+                                        if (ki>999){ ki=999;}
+                                        lcd.locate(2,1);        //Ubica el parámetro ki
+                                        lcd.printf("=  ");
+                                        lcd.locate(3,1);
+                                        lcd.printf("%d", ++ki);
+                                         
+                                        break;
+                                        
+                                        case 3:
+                                        if (kd>999){ kd=999;}
+                                        lcd.locate(10,1);       //Ubica el parámetro kd
+                                        lcd.printf("=  ");
+                                        lcd.locate(11,1);
+                                        lcd.printf("%d", ++kd);
+                                          
+                                        break;
+                                }
+               }
+                              if   (P3.rising()) {      //Decrementa la variable      
+                                     wait(0.1);
+                                     led3=0;
+                                     wait(0.15);             //enciende el led azul 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;
+                                                }
+                                 }
+                        //PARA GUARDAR LOS PARAMETROS SE PRESIONA EL PULSADOR SET DURANTE 5 SEGUNDOS
+                        if (P2==1 && kp>0 && ki>0 && kd>0 )
+                        {B=1;
+                        t.start(); //empieza timer
+                        t2=t.read(); //lee el timer y lo almacena en una variable entera t2
+                                             
+                            }
+                                    if(t2==5 && P2==1){
+                                        t.stop(); //para el timer
+                                        B=0;
+                                        lcd.cls();
+                                         }
+                             
+                               if (t2==5 && B==0)
+                               {      
+                                  t2=0;
+                                  lcd.printf("GUARDADOS!"); 
+                                   wait(2);
+                                   lcd.cls();
+                                   lcd.printf("INICIA EL PID");
+                                   wait(2);
+                                  // se imprimen los parches del control
+                                   lcd.cls();
+                                         
+                                   lcd.printf("E:%d");
+                                   lcd.locate(8,0);
+                                   lcd.printf("Y:%d");
+                                   lcd.locate(0,1);
+                                   lcd.printf("Sp:%d");
+                                   lcd.locate(8,1);
+                                   lcd.printf("Co:%0.1f");
+                                   wait(1);
+                                  
+                                   // CICLO PRINCIPAL CONTROLADOR PID
+                                 
+                                   while(1) {
+                                   
+                                   wait(0.001);
+                                   med = (Vin.read()*3300);//la medicion es convertida a un valor en mV,siendo el máximo valor esperado 3300mV (3.3V)
+                                   sp0 = sp;
+                                   err = (sp0*1000-med); //Estoy ingresando un valor en V, pero opero internamente en mV
+                                   float kp0;
+                                   kp0 = kp;
+                                   ap = kp0*err;
+                                   float ki0;
+                                   ki0 = ki;      
+                                   ai =  (ki0*err)+ai;     //calculo de la integral del error
+                                   float kd0;
+                                   kd0 = kd;
+                                   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 > 999){
+                                   pid=999;
+                                   } 
+                                   
+                                   // 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/999);       
+                                    //Mostrar resultados PID
+                                      if(ciclo>700)  {         
+                                       lcd.locate(2,0);
+                                       lcd.printf("      "); 
+                                       lcd.locate(0,0);
+                                       lcd.printf("E=%2.1f",err/1000); //error
+                                       lcd.locate(10,0);
+                                       lcd.printf("      ");
+                                       lcd.locate(8,0);
+                                       lcd.printf("Y=%4.2f",med/1000); //Salida del circuito
+                                       lcd.locate(2,1);
+                                       lcd.printf("      ");
+                                       lcd.locate(0,1);
+                                       lcd.printf("Sp=%4.2f",sp0); //Set point
+                                        lcd.locate(10,1);
+                                        lcd.printf("   ");
+                                        lcd.locate(10,1);
+                                        lcd.printf("=%0.1f",pid*3.3/999); //Esfuerzo de control
+                                       
+                                       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
+                                  }    
+                                                 
+                                  }
+                                  }     
+                                }                                                                  
+                                }
\ No newline at end of file