El siguiente programa presenta un PID al cual se le pueden modificar los parámetros, para ello se han usado cuatro pulsadores.
Dependencies: Debounced TextLCD mbed
main.cpp
- Committer:
- caarbelaezg
- Date:
- 2015-04-08
- Revision:
- 0:f0eb5248ae8f
File content as of revision 0:f0eb5248ae8f:
#include "mbed.h" #include "TextLCD.h" #include "DebouncedIn.h" TextLCD lcd(PTE0, PTE1, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7 Teclado DebouncedIn button1(PTC12); //Botón Aumento DebouncedIn button2(PTC13); //Botón Decremento DebouncedIn button3(PTC16); //Botón de pasar DebouncedIn button4(PTC17); //Botón para iniciar el PID AnalogIn y(PTB1); // Salida de la planta AnalogOut u(PTE30); // Señal de control DigitalOut led1(LED1); // Salidas para comprobar el funcionamiento del programa DigitalOut led2(LED2); DigitalOut led3(LED3); Timer t; //Para cuantizar el tiempoque se deja undido un botón de aumento o decremento int C1=0x0F; // Codigo para escribir y matener el el LCD int sp=0,kp=0,kd=0,ki=0,p=1; // Inicializacion de las variables para el controlador float ap, ai, ad, err, med, err_v, pid=0; // int main() { lcd.writeCommand(C1); lcd.printf(" CONTROL PID\n"); wait(2); lcd.cls(); lcd.printf(" EQUIPO1:\nJuan Jose Munoz"); wait(2); lcd.cls(); lcd.printf("Carlos Arbelaez Rafael Barriento"); wait(2); lcd.cls(); lcd.printf(" INGRESO DE\n PARAMETROS "); wait(2); retorno: //Cuando se presiona por segunda vez el botón 4 se retorna a la interfaz de parametros para modificarlos p=1; 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()) { led1 =!led1; if (p==1) { ++sp; lcd.locate(3,0); lcd.printf(" "); lcd.locate(3,0); lcd.printf("%d", sp); if(sp>=5){ sp=5; //saturamos el setpoint hasta 5 segun la escala medida ya que trabajaremos entre 0V y 5V lcd.locate(3,0); lcd.printf(" "); lcd.locate(3,0); lcd.printf("%d", sp); } //A continuación se explica para Kp como funciona el aumento de los parametros, para el resto de parametros //funciona de la misma manera así que se omiten los comentarios, para el decremento tambien funciona igual //En este caso se exhibe cuando el tiempo pasa los parametros aumentan de 10 o 100 veces, tambien se puede realizar // con aumento unitario y más velocidad en la subida del parametro a medida que pasa el tiempo así: /* if((t<7) && (t>=1)){ //Primera velocidad de incremento en el intervalo wait(0.3); //Cada cierto intervalo de tiempo se cambia el wait por un valor mas pequeño ++kp; //perceptible al ojo, de modo que aumente mas rapido unitariamente lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); } */ } else if (p==2) { ++kp; //Aumento unitario de la constante lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); while(button1==0){ //Verifica si el botón 1 se deja presionado if(t==0){t.start();} //Inicia a contar el tiempo que se deja presionado if((t<7) && (t>=1)){ //Primera velocidad de incremento en el intervalo wait(0.3); //Espera 0.3 segundos para volver a imprimir ++kp; lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); } if((t>=7)&&(t<13)){ //Segunda velocidad de incremento wait(0.3); kp=10+kp; //ahora aumenta de 10 en 10 lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); } if((t>=13) && (t<19)){ //Tercera velocidad de incremento 100 wait(0.3); kp=100+kp; //Aumenta de 100 en 100 lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); } if(kp>999){ //Saturación máxima de los parametos kp=999; lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); } } t.reset(); //Se reinicia el tiempo y vuelve a incrementar unitariamente } else if (p==3) { ++ki; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); while(button1==0){ if(t==0){t.start();} if((t<7) && (t>=1)){ wait(0.3); ++ki; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); } if((t>=7)&&(t<13)){ wait(0.3); ki=10+ki; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); } if((t>=13) && (t<19)){ wait(0.3); ki=100+ki; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); } if(ki>999){ ki=999; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); } } t.reset(); } else if (p==4) { ++kd; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); while(button1==0){ if(t==0){t.start();} if((t<7) && (t>=1)){ wait(0.3); ++kd; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); } if((t>=7)&&(t<13)){ wait(0.3); kd=10+kd; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); } if((t>=13) && (t<19)){ wait(0.3); kd=100+kd; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); } if(kd>=999){ kd=999; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); } } t.reset(); } } if (button2.falling()) { led2 =!led2; if (p==1) { if (sp==0) // no mostrar nada { } else { --sp; lcd.locate(3,0); lcd.printf(" "); lcd.locate(3,0); lcd.printf("%d", sp); } } if (p==2) { if (kp==0) // no mostrar nada { } else { --kp; lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); while(button2==0){ if(t==0){t.start();} if((t<7) && (t>=1)){ wait(0.3); --kp; lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); } if((t>=7)&&(t<13)){ wait(0.3); kp=kp-10; lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); } if((t>=13) && (t<19)){ wait(0.3); kp=kp-100; lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); } } t.reset(); } } if (p==3) { if (ki==0) // no mostrar nada { } else { --ki; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); while(button2==0){ if(t==0){t.start();} if((t<7) && (t>=1)){ wait(0.3); --ki; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); } if((t>=7)&&(t<13)){ wait(0.3); ki=ki-10; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); } if((t>=13) && (t<19)){ wait(0.3); ki=ki-100; lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); } } t.reset(); } } if (p==4) { if (kd==0) // no mostrar nada { } else { --kd; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); while(button2==0){ if(t==0){t.start();} if((t<7) && (t>=1)){ wait(0.3); --kd; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); } if((t>=7)&&(t<13)){ wait(0.3); kd=kd-10; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); } if((t>=13) && (t<19)){ wait(0.3); kd=kd-100; lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); } } t.reset(); } } } if (button3.falling()) { led3 =!led3; if (p==1) { ++p; lcd.locate(11,0); lcd.printf("%d", kp); } else if (p==2) { ++p; lcd.locate(3,1); lcd.printf("%d", ki); lcd.locate(3,1); } else if (p==3) { ++p; lcd.locate(11,1); lcd.printf("%d", kd); } else if (p==4) { p=1; lcd.locate(3,0); lcd.printf("%d", sp); } } if(button4.falling()){ p=1; lcd.cls(); lcd.printf("Iniciando PID\n"); wait(1); while(p==1){ //La segunda vez que se presiona es para volver a la interfaz para modificar parametros if(button4.falling()){ p=0; goto retorno; } med=5*y.read(); err=sp-med; ap = kp*err; // se verifica que la accion integral no sea muy grande if(ai<5) { ai =(ki*err)+ai; //calculo de la integral del error } ad = kd*(err-err_v); //calculo de la accion derivativa pid = (ap+ai+ad); // se verifica que pid sea positivo ************************************** if(pid<=0){pid=0;} // se verifica que pid sea menor o igual la valor maximo ***************** if(pid>=5){pid=5;} u.write(pid); t.start(); if(t>=1){ lcd.cls(); lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD lcd.locate(8,0); lcd.printf("Err=%0.1f", err); lcd.locate(0,1); lcd.printf("Med=%0.1f", med); lcd.locate(8,1); lcd.printf("PID=%0.1f", pid); lcd.locate(0,0); lcd.printf("Sp=%d", sp); t.reset(); } } } } }