Control PID para un planta RC (control de la carga del capacitor), los parámetros se ingresan por medio de 4 pulsadores, teniendo en cuenta una librería antirebote y el resultado del control se visualiza en una pantalla LCD 16x2.
Fork of DebouncedIn_HelloWorld by
main.cpp
- Committer:
- Wilmar87
- Date:
- 2013-12-13
- Revision:
- 3:caf76da61c9f
- Parent:
- 1:3e6a41eba6bb
File content as of revision 3:caf76da61c9f:
#include "mbed.h" #include "DebouncedIn.h" #include "TextLCD.h" AnalogIn Vin(PTC2); AnalogOut Vout(PTE30); TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); //Puertos LCD rs, e, d4, d5, d6, d7 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 bot1(PTC12); //cambiar la posición DebouncedIn bot2(PTC13); //incrementar variable DebouncedIn bot3(PTC16); //decrementar variable DebouncedIn bot4(PTC17); //salida de bucle //Códigos LCD int C1=0x0E; // Muestra el cursor // 0x18; // desplazamiento izquierda // 0x1A; // desplazamiento derecha int C4=0x0C; // Quita el cursor int a, sp, kp, ki, kd, ciclo; // indice de la variable float med, sp0, ap, err, ai, ad, pid, err_v; int main() { led1=led2=led3=1; lcd.printf("Control PID"); wait(1.5); lcd.cls(); lcd.writeCommand(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); //Inicio del ciclo while(1) { if (bot1.falling()) { //Aumenta posición el cursor a++; led1=0; wait(.15); //enciende el led azul 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 (bot2.falling()) { //Incrementa la variable led2=0; wait(.15); //enciende el led verde cada vez que se oprime el botón de incremento led2=1; switch (a) { case 0: lcd.locate(2,0); //Ubica el parámetro Set-point lcd.printf("= "); lcd.locate(3,0); lcd.printf("%d", ++sp); break; case 1: lcd.locate(10,0); //Ubica el parámetro kp lcd.printf("= "); lcd.locate(11,0); lcd.printf("%d", ++kp); break; case 2: lcd.locate(2,1); //Ubica el parámetro ki lcd.printf("= "); lcd.locate(3,1); lcd.printf("%d", ++ki); break; case 3: lcd.locate(10,1); //Ubica el parámetro kd lcd.printf("= "); lcd.locate(11,1); lcd.printf("%d", ++kd); break; } } if (bot3.falling()) { //Decrementa la variable wait(0.1); led3=0; wait(.15); //enciende el led roja 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; } } if (bot4.falling()){ //sale del bucle de la pantalla led1=led2=led3=0; //Flash para salir del bucle wait(0.25); led1=led2=led3=1; break; } } lcd.writeCommand(C4); //Quita el cursor bajo del LCD lcd.cls(); //borra la pantalla lcd.printf("GUARDADOS!"); wait(2); lcd.cls(); lcd.printf("INICIA EL PID"); wait(2); // se imprimen los parches del control ***************************************** lcd.cls(); lcd.printf("Er%d",err); lcd.locate(8,0); lcd.printf("Me%d",med); lcd.locate(0,1); lcd.printf("Sp%d",sp0); lcd.locate(8,1); lcd.printf("Pid%d",pid); // CICLO PRINCIPAL CONTROLADOR PID while(1) { wait(0.001); //leer puerto analogo y asignar a med med = (Vin*3.27); sp0 = sp*0.0327; err = (sp0-med); float kp0; kp0 = kp*0.001; ap = kp0*err; float ki0; ki0 = ki*0.001; ai = (ki0*err)+ai; //calculo de la integral del error float kd0; kd0 = kd*0.0001; 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 > 0.999){ pid=1; } // 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); //Mostrar resultados PID if(ciclo>700) { lcd.locate(2,0); lcd.printf(" "); lcd.locate(0,0); lcd.printf("Er%2.1f",err); lcd.locate(10,0); lcd.printf(" "); lcd.locate(8,0); lcd.printf("Me%4.2f",med); lcd.locate(2,1); lcd.printf(" "); lcd.locate(0,1); lcd.printf("Sp%4.2f",sp0); lcd.locate(10,1); lcd.printf(" "); lcd.locate(8,1); lcd.printf("Pid%4.3f",pid); 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 }