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)

Files at this revision

API Documentation at this revision

Comitter:
tony63
Date:
Sun Apr 24 18:32:52 2016 +0000
Parent:
0:4e0dfcf0e7ce
Commit message:
Control PID gen?rico que se parametriza con un encoder rotatorio. Todos los c?lculos se procesan en coma flotante. Se imprimen sin cifras significativas por dificultades de impresi?n en la LCD.

Changed in this revision

main.cpp Show annotated file Show diff for this revision Revisions of this file
diff -r 4e0dfcf0e7ce -r 058b8f5c135d main.cpp
--- 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;
 }