Controlador PID Genérico que se parametriza por medio de un encoder rotatorio- Sp (Set-point), Kp(Ganancia proporcional) ,Ki(Constante integral), Kd(Constante Derivativa), usa dos pulsadores adicionales

Dependencies:   QEI TextLCD mbed

Este programa es un control PID genérico que se parametriza usando un encoder manual. Se puede ajustar. Set-Point Kp Ki Kd

Emplea el pulsador central del encoder para cambiar de parámetro y otro adicional para consolidar los parámetros y ejecutar el controlador

Se puede probar por medio de un sistema de primer orden conformado por una red RC. de 11K y un condensador de 22uF desde la salida hasta la entrada. que se ve en el mini protoboard de la figura siguiente

a continuación mostramos la respuesta del controlador PID a esos parámetros trabajando en lazo cerrado. que da cero error

Donde se ve, Error (Er), Medida(Me), Setpoint(Sp), Control o salida(Co) de voltaje. /media/uploads/tony63/pidok1.png

Se aprecia la izquierda el encoder manual y en la entrada análoga se aplicó un anillo de ferrita o balum; ya que estas entradas análogas son muy sensibles al ruido.

Abajo se aprecia el esquemático. Las conexiones del LCD se deducen de los listados de programa y de la guia del CookBook de esta webb, en la parte de LCD. /media/uploads/tony63/planta1.png

Si quiere ver la respuesta del sistema a cambios de carga, coloque de forma temporal una resistencia de 100K en paralelo con el condensador de 22uF.

Bug del esquemático (intercambie los puertos de los dos pulsadores)

Revision:
1:058b8f5c135d
Parent:
0:4e0dfcf0e7ce
--- a/main.cpp	Fri Apr 22 23:11:38 2016 +0000
+++ b/main.cpp	Sun Apr 24 18:32:52 2016 +0000
@@ -4,8 +4,7 @@
 
 TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7
 QEI encoder (PTA13, PTD5, NC, 624);
-
-AnalogIn y(PTB0);//entrada analoga
+AnalogIn y(PTB3);//entrada analoga
 AnalogOut u(PTE30);//salida analoga OJO solo se le pueden drenar 1.5mA en circuitos use un Buffer
 //si se ignora esto se arruina la FRDMKL25Z
 DigitalOut led1(LED1);
@@ -24,11 +23,10 @@
 int C4=0x0C; // quito cursor bajo
 
 int C1=0x0F;
-int err, med, yr, pid, ap, ai, ad, err_v, cambio=0, diferencia=0;
-float pidn;
+int cambio=0, diferencia=0;
+float pid,o,ai,ad,ap,med,err;
+float err_v;
 int spnum=0,kinum=0,kpnum=0,kdnum=0,pos=1;
-int flagt=0;
-Timer t;
 
 int main()
 {
@@ -64,9 +62,9 @@
         {
             if(pos==1)
             {
-                if(spnum+diferencia>=9999)
+                if(spnum+diferencia>=999)
                 {
-                    spnum=9999;
+                    spnum=999;
                     lcd.locate(3,0);
                     lcd.printf("    ");
                     lcd.locate(3,0);
@@ -81,9 +79,9 @@
             }
             else if(pos==2)
             {
-                if(kpnum+diferencia>=9999)
+                if(kpnum+diferencia>=999)
                 {
-                    kpnum=9999;
+                    kpnum=999;
                     lcd.locate(11,0);
                     lcd.printf("    ");
                     lcd.locate(11,0);
@@ -98,9 +96,9 @@
             }
             else if(pos==3)
             {
-                if(kinum+diferencia>=9999)
+                if(kinum+diferencia>=999)
                 {
-                    kinum=9999;
+                    kinum=999;
                     lcd.locate(3,1);
                     lcd.printf("    ");
                     lcd.locate(3,1);
@@ -115,9 +113,9 @@
             }
             else if(pos==4)
             {
-                if(kdnum+diferencia>=9999)
+                if(kdnum+diferencia>=999)
                 {
-                    kdnum=9999;
+                    kdnum=999;
                     lcd.locate(11,1);
                     lcd.printf("    ");
                     lcd.locate(11,1);
@@ -245,34 +243,22 @@
     wait(1);
 // se imprimen los parches del control  *****************************************
     lcd.cls();
-    lcd.printf("Er=%d",err);
+    lcd.printf("Er=%3.0f",err);
     lcd.locate(8,0);
-    lcd.printf("Me=%d",med);
+    lcd.printf("Me=%3.0f",med);
     lcd.locate(0,1);
-    lcd.printf("Sp=%d",spnum);
+    lcd.printf("Sp=%3.0f",spnum);
     lcd.locate(8,1);
-    lcd.printf("Co=%d",pid);
-    wait(2);
+    lcd.printf("Co=%3.0f",pid);
+    wait(1);
 
 // CICLO PRINCIPAL CONTROLADOR PID
-    flagt=0;
-    while(1)
-    {
-        med=999*y.read();   //leer puerto analogo y asignar a med
+ lop1:  med = y.read()*999;
         err = (spnum-med);  //se calcula el error
-
-        ap = kpnum*err;     //se calcula la accion proporcinal
-
-        // se verifica que la accion integral no sea muy grande
-        if(ai<100)
-        {
-            ai =(kinum*err)+ai;    //calculo de la integral del error
-        }
-
-        ad = kdnum*(err-err_v); //calculo de la accion derivativa
-
+        ap = kpnum*err*0.01f;     //se calcula la accion proporcinal
+        ai =(kinum*err*0.01f)+ai;    //calculo de la integral del error
+        ad = kdnum*(err-err_v)*0.01f; //calculo de la accion derivativa
         pid = (ap+ai+ad);
-
         // se verifica que pid sea positivo **************************************
         if(pid<=0)
         {
@@ -285,42 +271,36 @@
             pid=999;
         }
 
-        // se actualizan las variables *******************************************
-        err_v = err;
-
+       
         //se muestran las variables******************************************
-        if(flagt==0)
-        {
-            t.start();
-            flagt=1;
-        }
-        if(t>=0.3)
-        {
             lcd.locate(3,0);
             lcd.printf("    ");
             lcd.locate(3,0);
-            lcd.printf("%d",err);
+            lcd.printf("%3.0f",err);
             lcd.locate(11,0);
-            lcd.printf("    ");
+            lcd.printf("   ");
             lcd.locate(11,0);
-            lcd.printf("%d",med);
+            lcd.printf("%3.0f",med);
             lcd.locate(3,1);
-            lcd.printf("    ");
+            lcd.printf("   ");
             lcd.locate(3,1);
             lcd.printf("%d",spnum);
             lcd.locate(11,1);
-            lcd.printf("    ");
+            lcd.printf("   ");
             lcd.locate(11,1);
-            lcd.printf("%d",pid);
-            flagt=0;
-            t.reset();
-        }
+            lcd.printf("%3.0f",pid);
+           
+            
+        
 
         //Normalizacion de la salida
-        pidn=pid/999;
+        // se actualizan las variables *******************************************
+        err_v = err;
+        o = pid/999;
+        u.write(o);
         //  se envia el valor pid a puerto analogico de salida (D/A) **************
-        u.write(pidn);
+        
         //  se repite el ciclo
-        wait(0.005);
-    }
+        wait_ms(300);
+        goto lop1;
 }