PID para el control de voltaje de un capacitor en un circuito RC

Dependencies:   Debounced TextLCD mbed

Fork of pid_teclas by Gustavo Ramirez

/media/uploads/PabloViana/general.jpg

Revision:
1:19ecfc5a15c7
Parent:
0:9aa80672eb3d
--- a/main.cpp	Wed Oct 16 17:10:11 2013 +0000
+++ b/main.cpp	Thu Oct 01 11:50:42 2015 +0000
@@ -2,43 +2,62 @@
 #include "DebouncedIn.h"
 #include "TextLCD.h"
 
-AnalogIn Vin(PTC2);
+AnalogIn MedidaAnaloga(PTC2);//Medida de tensión
+AnalogOut SalidaAnaloga(PTE30);//Salida analoga;
 TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7
 
 DigitalOut led1(LED1);
 DigitalOut led2(LED2);
 DigitalOut led3(LED3);
-DebouncedIn button1(PTC12);
-DebouncedIn button2(PTC13);
-DebouncedIn button3(PTC16);
+DebouncedIn Incrementar(PTC17);//
+DebouncedIn Decrementar(PTC16);
+DebouncedIn Saltar(PTC13);
+DebouncedIn IniciarPID(PTC12);
 
-int C1=0x0F;
-int sp=0,kp=0,kd=0,ki=0,p=1;
-int main()
+int C1=0x0F;//Inicializar el cursor;
+float sp=1;
+int kp=25,kd=0,ki=10,p=1; 
+float errormV = 0; //Variable en la que almacenaré la diferencia entre el set point  la medida real;
+float ek_1=0; //Error en el instante de tiempo anterior;
+float medidamV=0;//Variable en la que almacenaré la medida en mV;
+float PID;
+
+//Variables del PID
+    float Proporcional;
+    float Derivativo;
+    float Integrativo;
+//Función del PID//
+void ControlPID()
 {
-    lcd.cls();
-    lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD
-    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);
-    lcd.locate(0,0);
-    lcd.printf("Sp=%d", sp);
-
-    while(1)
-    {
-        if (button1.falling())
+    
+    Proporcional= kp*errormV;
+    Integrativo= (ki*errormV) + Integrativo;
+    if(Integrativo>999){Integrativo=999;}//Saturo la salida;
+    Derivativo = kd*(errormV-ek_1);
+    ek_1=errormV;//Almaceno el valor para el instante de tiempo sieguiente;
+    PID = Proporcional + Integrativo + Derivativo;
+    if (PID>999){PID=999;}//Saturo la salida;
+    if (PID<0){PID=0;}//saturo la salida
+    
+ 
+    SalidaAnaloga = PID/999; //Escrino en la salida;
+}
+//Función lectura de botones
+void Botones()
+/*¡¡¡CÓDIGO RECICLADO!!!!, en este caso se debe considerar que se usarán pulsadores normalmente abiertos,
+por esta razón los evento a considerar son los flancos de subida, detectados mediante el la instrucción ".rising" */
+{
+        if (Incrementar.rising())
         {
             led1 =!led1;
             if (p==1)
             {
-                ++sp;
+                sp=sp+0.1;
+                if(sp>3.3){sp=3.3;}//Limito el valor del Set Point;
                 lcd.locate(3,0);
                 lcd.printf("   ");
                 lcd.locate(3,0);
-                lcd.printf("%d", sp);
+                lcd.printf("%0.1f", sp);
             }
             else if (p==2)
             {
@@ -65,7 +84,7 @@
                 lcd.printf("%d", kd);
             }
         }
-        if (button2.falling())
+        if (Decrementar.rising())
         {
             led2 =!led2;
             if (p==1)
@@ -75,11 +94,12 @@
                 }
                 else
                 {
-                    --sp;
+                    sp=sp-0.1;
+                    if(sp<0){sp=0;}//Limito el valor del Set Point
                     lcd.locate(3,0);
                     lcd.printf("   ");
                     lcd.locate(3,0);
-                    lcd.printf("%d", sp);
+                    lcd.printf("%.1f", sp);
                 }
             }
             if (p==2)
@@ -125,7 +145,7 @@
                 }
             }
         }
-        if (button3.falling())
+        if (Saltar.rising())
         {
             led3 =!led3;
             if (p==1)
@@ -156,10 +176,74 @@
             {
                 p=1;
                 lcd.locate(3,0);
-                lcd.printf("%d", sp);
+                lcd.printf("%.1f", sp);
                 
                 
             }
-        }
+        }    
+    
+    
+}//Botones
+
+
+
+//Inicio la función principal;
+int main()
+{   int contador=0;
+    lcd.cls();
+    lcd.writeCommand(C1);//Mando al LCD el comano que inicializa el cursor
+    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);
+    lcd.locate(0,0);
+    lcd.printf("Sp=%.1f", sp);
+    SalidaAnaloga=0;
+    
+    while(1) //Iniciar Ciclo Infinito
+    {
+        Botones(); //Inicia la función que revisa el estado de los botones
+        
+        if(IniciarPID.rising()) //Se presiona el botón Iniciar PID
+        {
+           lcd.cls();//Borrar pantalla;
+           lcd.locate(0,0);
+           lcd.printf("PID...");
+           wait(1);
+           lcd.cls();//Borrar pantalla;
+           break; // Termino el ciclo infinito;
+        }//if
+    }//while
+    
+    while(1)//ciclo infinito para el PID
+    {
+    medidamV=MedidaAnaloga*3300;//La medida es convertida a un valor en mV, siendo el máximo valor esperado 3300mV (3.3V)
+    
+    errormV= (sp*1000)- medidamV; //Estoy ingresando un valor en V, pero opero internamente en mV
+    contador++; //Contador para actualizar la pantalla cada cierto número de ciclos;
+    if(contador ==10)
+    {
+        lcd.cls();
+        lcd.locate(0,0);
+        lcd.printf("Sp:%.2fV", sp);//Muestro el set point;
+        
+        lcd.locate(0,1);
+        lcd.printf("M:%.2fV", medidamV/1000);//Muestro la medida;
+        
+        lcd.locate(8,1);
+        lcd.printf("E:%.2fV", errormV/1000);//Muestro el error;   
+        
+        lcd.locate(9,0);
+        lcd.printf("U:%.1fV",PID*3.3/999); //Muestro el esfuerzo de control
+        contador=0;//Reinicializo el contador;             
+    }//if
+    ControlPID();//Llamo la función PID;
+    if(Incrementar.rising()){sp=sp+0.5;}
+    if(sp>3.3){sp=3.3;}//Limito el valor del Set Point;
+    if(Decrementar.rising()){sp=sp-0.5;}
+    if(sp<0){sp=0;}//Limito el valor del Set Point;
+    wait(0.05);//Espero un tiempo;
     }
 }