![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
PID con pulsadores para circuito RC
Dependencies: Debounced TextLCD mbed
main.cpp
- Committer:
- Meli
- Date:
- 2015-10-13
- Revision:
- 0:96212ecff217
- Child:
- 1:744ee5bf7b7c
File content as of revision 0:96212ecff217:
#include "mbed.h" #include "DebouncedIn.h" #include "TextLCD.h" // se quiere que las constantes del controlador sean variables debido a que se desea ajustes a cambio en el setpoint. // la farma que se determino hacer fue que despues de mantener oprimido alguna de las constantes hasta cuenta de 1 en 1 hasta 10 // luego que si aun esta oprimido cuenta de 10 en 10 hasta 100 y si aun esta oprimido cuenta de 100 en 100 hasta 999, de igual // de igual manera funciona para decendente, el unico que no cumple estas condisiones es (sp)que llega maximo hasta 3 debido a //que la salida analoga maxima son 3.21 voltios ya con la conversion realizada. AnalogIn Vin(PTC2); // entrada analoga AnalogOut Vout(PTE30); // salida analoga TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7 int presionado_incremento(int columna,int fila,int constante);//funcion creada para incrementar el valor con el boton hundido int presionado_decremento(int columna,int fila,int constante);//funcion entrada para decrementar el valor con el boton hundido DigitalOut led1(LED1); DigitalOut led2(LED2); DigitalOut led3(LED3); DebouncedIn button1(PTC12); //incrementar DebouncedIn button2(PTC13);//decrementar DebouncedIn button3(PTC16);//cambiar DebouncedIn button4(PTC17); //enter int C1=0x0F; int sp=0,kp=0,kd=0,ki=0,p=1,bandera = 0; float error=0,pwmset,eInteg,pGain,ePrev,iGain,dGain,x; int main() { 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())//se cuenta en el flanco de caida para el boton 1 { led1 =!led1; if (p==1)// posicion 1 en el LCD { ++sp;//incrementa de a uno if (sp>=5) // se limita sp porque el mayor valor que toma es 3.2 {sp=5; } lcd.locate(3,0); lcd.printf(" ");//borra el valor anterior lcd.locate(3,0); lcd.printf("%d", sp);//decimal wait (0.5); //para evitar un error al hundir el boton, y que el programa no lo tome como si se hubiera dejado hundido el boton } else if (p==2) // cambia a posicion 2 { kp = kp+1; if (kp>=999)//se limita hasta 999 { kp= 999; } lcd.locate(11,0); lcd.printf(" "); lcd.locate(11,0); lcd.printf("%d", kp); wait (0.5); //para evitar un error al hundir el boton, y que el programa no lo tome como si se hubiera dejado hundido el boton kp=presionado_incremento(11,0,kp); //se llama la funcion de incremento para kp } else if (p==3) //cambia de posicion { ++ki; if (ki>=999) { ki= 999; } lcd.locate(3,1); lcd.printf(" "); lcd.locate(3,1); lcd.printf("%d", ki); wait (0.5); ki = presionado_incremento(3,1,ki); //se llama la funcion de incremento para ki } else if (p==4)//cambia de posicion { ++kd; if (kd>=999) { kd = 999; } lcd.locate(11,1); lcd.printf(" "); lcd.locate(11,1); lcd.printf("%d", kd); wait (0.5); kd = presionado_incremento(11,1,kd); //se llama la funcion de incremento para kd } } if (button2.falling())//se cuenta en el flanco de caida para el boton 2 decrementar { led2 =!led2; if (p==1) { if (sp==0) // no mostrar nada evita valores negativos { } else { --sp; lcd.locate(3,0); lcd.printf(" "); lcd.locate(3,0); lcd.printf("%d", sp); wait(0.5); sp = presionado_decremento(3,0,sp); //se utiliza la funcion decremento } } 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); wait(0.5); kp = presionado_decremento(11,0,kp); } } 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); wait(0.5); ki = presionado_decremento(3,1,ki); } } 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); wait(0.5); kd = presionado_decremento(11,1,kd); } } } if (button3.falling())//para el cambio de posicion { 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); } } //enter if(button4.falling()) { lcd.cls(); // al undir el boton 4 se borra la pantalla //for (int h=0;h<100;h++) //Vout= Vout+0.01; while(bandera==0) { wait(0.2); x=Vout.read(); // lee el voltaje de salida que nuestra analoga pero en porcentaje //x = x*(3.21/0.976801); // Voltios //} //pid error = sp-x; // Calcula el error pwmset = kp* error+ki * eInteg +kd* (error - ePrev); // ecuacion para el PID pwmset=(0.976801/5)*pwmset; // como el voltaje calculado fue un porcentaje se realiza una convercion respectiva al valor de salida Vout=pwmset; eInteg =eInteg+ error; // integral ePrev = error; lcd.locate(0,1); lcd.printf("error=%f",error); lcd.locate(1,0); lcd.printf("salida=%f",x); if (button4.falling()) { bandera=1; lcd.cls(); p=1; 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); } } bandera = 0; } } } // se intento de utilizar la funcion steady, pero esta no funciono cuando se mantenia presionado, por lo tanto se usaron banderas para que cuando // llegara a un valor determidado cambie de unidades // se crearon dos fnciones tanto de incremento como decremento ya que se reduce mucho codigo debido a que hay que crear 2 lineas de codigo para cada // cada constante kp, ki, kd y sp int presionado_incremento(int columna,int fila,int constante) { int marc=0,i=0; while(button1==0) // Cuando el boton 1 esta presionado { i=1; wait (0.5); if ((marc==2)&(i==1)) // entra cuando el modulo de la constante dividido 100 y el residuo es 0 { constante = constante+100; if (constante>=999) { constante = 999; } lcd.locate(columna,fila); lcd.printf(" "); lcd.locate(columna,fila); lcd.printf("%d", constante); i=0; } if ((marc==1)&(i==1)) { constante=constante+10; if(constante%100==0){marc=2;} // si el residuo de la constante dividido 100, la bandera es igual a dos if (constante>= 999) { constante = 999; } lcd.locate(columna,fila); lcd.printf(" "); lcd.locate(columna,fila); lcd.printf("%d", constante); i=0; } if ((marc==0)&(i==1)) { ++constante; if(constante%10==0){marc=1;} if (constante>= 999) { constante = 999; } lcd.locate(columna,fila); lcd.printf(" "); lcd.locate(columna,fila); lcd.printf("%d", constante); i=0; } } marc=0; return constante; } int presionado_decremento(int columna,int fila,int constante) { int marc=0,i=0; while(button2==0) // cuando el boton 2 esta precionado { i=1; wait (0.5); if ((marc==2)&(i==1)) { constante = constante-100; if (constante<=0) { constante = 0; } lcd.locate(columna,fila); lcd.printf(" "); lcd.locate(columna,fila); lcd.printf("%d", constante); i=0; } if ((marc==1)&(i==1)) { constante=constante-10; if(constante%100==0){marc=2;} if (constante<=0) { constante = 0; } lcd.locate(columna,fila); lcd.printf(" "); lcd.locate(columna,fila); lcd.printf("%d", constante); i=0; } if ((marc==0)&(i==1)) { --constante; if(constante%10==0){marc=1;} if (constante<=0) { constante = 0; } lcd.locate(columna,fila); lcd.printf(" "); lcd.locate(columna,fila); lcd.printf("%d", constante); i=0; } } marc=0; return constante; };