PID que funciona con pulsadores y tiene autotunning.
Dependencies: Debounced QEI TextLCD mbed
Revision 0:2d05e443a44d, committed 2017-11-28
- 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
diff -r 000000000000 -r 2d05e443a44d Debounced.lib --- /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
diff -r 000000000000 -r 2d05e443a44d PID.CPP --- /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
diff -r 000000000000 -r 2d05e443a44d QEI.lib --- /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
diff -r 000000000000 -r 2d05e443a44d TextLCD.lib --- /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
diff -r 000000000000 -r 2d05e443a44d mbed.bld --- /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