PID que funciona con pulsadores y tiene autotunning.

Dependencies:   Debounced QEI TextLCD mbed

Files at this revision

API Documentation at this revision

Comitter:
PROCESADORES_2017_2
Date:
Tue Nov 28 19:48:57 2017 +0000
Commit message:
PID que funciona con pulsadores y tiene autotunning.

Changed in this revision

Debounced.lib Show annotated file Show diff for this revision Revisions of this file
PID.CPP Show annotated file Show diff for this revision Revisions of this file
QEI.lib Show annotated file Show diff for this revision Revisions of this file
TextLCD.lib Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Debounced.lib	Tue Nov 28 19:48:57 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/WarwickRacing/code/Debounced/#8992c13bbb9b
--- /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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/QEI.lib	Tue Nov 28 19:48:57 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/aberk/code/QEI/#5c2ad81551aa
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TextLCD.lib	Tue Nov 28 19:48:57 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/simon/code/TextLCD/#308d188a2d3a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Tue Nov 28 19:48:57 2017 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/e7ca05fa8600
\ No newline at end of file