![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
Se realiza un control PID sobre el voltaje de un condensador en un filtro RC. Se transmiten las señales de salida y set-point por medio de Bluetooth para luego ser graficadas en una aplicación de Android.
Dependencies: QEI TextLCD mbed
Fork of PID by
Diff: main.cpp
- Revision:
- 3:2e823b16a4a1
- Parent:
- 2:00db719ebd81
- Child:
- 4:82ac4b34c3d9
diff -r 00db719ebd81 -r 2e823b16a4a1 main.cpp --- a/main.cpp Wed May 10 22:36:03 2017 +0000 +++ b/main.cpp Sat May 13 20:36:07 2017 +0000 @@ -10,8 +10,8 @@ Serial GSM(PTE0,PTE1); // Módulo Bluetooh TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7 -QEI encoder (PTA13, PTD5, NC, 1000); - +QEI encoder (PTA13, PTD5, NC, 10); +Timer t; AnalogIn y(PTC2); // Entrada análoga: Salida del sistema AnalogOut u(PTE30); // Salida análoga: Señal de control @@ -30,65 +30,85 @@ int C4=0x0C; // quito cursor bajo int cambio = 0, diferencia = 0; -float pid, o, ai, ad, ap, med, err; +float pid, o, ai, ad, ap, med, err, setpoint; float err_v; int spnum = 0, kinum = 0, kpnum = 0 ,kdnum = 0, pos = 1; int j,k; +long t_pid = 0, t_btn = 0; int main() { + // Se asigna baudrate y se configura el puerto serie de la USART + GSM.baud(9600); GSM.format(8,Serial::None,1); + t.start(); + + for (int i = 3; i < 24; ++i) { + lcd.cls(); + lcd.locate(0,0); + lcd.printf("**Control PID**"); + wait_ms(1000/i); + + ++i; + lcd.cls(); + lcd.locate(1,0); + lcd.printf("**Control PID**"); + wait_ms(1000/i); + + ++i; + lcd.cls(); + lcd.locate(1,1); + lcd.printf("**Control PID**"); + wait_ms(1000/i); + + ++i; + lcd.cls(); + lcd.locate(0,1); + lcd.printf("**Control PID**"); + wait_ms(1000/i); + } + +init: + + lcd.cls(); + lcd.writeCommand(C1); + + lcd.locate(8,0); + lcd.printf("Ki=%d", kinum); lcd.locate(0,1); - lcd.printf("**Control PID**"); - wait(3); + lcd.printf("Kd=%d", kdnum); - lcd.cls(); // Borrar Pantalla - lcd.writeCommand(C1); // Escribimos un comando segun el manual del modulo LCD - - lcd.locate(8,0); + lcd.locate(8,1); + lcd.printf("**PID**"); + + lcd.locate(0,0); lcd.printf("Kp=%d", kpnum); - lcd.locate(0,1); - lcd.printf("Ki=%d", kinum); - lcd.locate(8,1); - lcd.printf("Kd=%d", kdnum); - lcd.locate(0,0); - lcd.printf("Sp=%d", spnum); - + + bool state = 1; + while(true) { - diferencia=encoder.getPulses() - cambio; + diferencia=(encoder.getPulses() - cambio)*3; cambio=encoder.getPulses(); - if (diferencia != 0) { + if (diferencia != 0 && state) { switch (pos) { case 1: - spnum += diferencia; - - if (spnum >= 999) - spnum = 999; - else if (spnum < 0) - spnum = 0; - - lcd.locate(3,0); - lcd.printf(" "); - lcd.locate(3,0); - lcd.printf("%d", spnum); - break; - case 2: kpnum += diferencia; if (kpnum >= 999) kpnum = 999; else if (kpnum < 0) kpnum = 0; - lcd.locate(11,0); + + lcd.locate(3,0); lcd.printf(" "); - lcd.locate(11,0); + lcd.locate(3,0); lcd.printf("%d", kpnum); break; - case 3: + case 2: kinum += diferencia; if (kinum >= 999) @@ -96,12 +116,12 @@ else if (kinum < 0) kinum = 0; - lcd.locate(3,1); + lcd.locate(11,0); lcd.printf(" "); - lcd.locate(3,1); + lcd.locate(11,0); lcd.printf("%d", kinum); break; - case 4: + case 3: kdnum += diferencia; if (kdnum >= 999) @@ -109,143 +129,125 @@ else if (kdnum < 0) kdnum = 0; - lcd.locate(11,1); + lcd.locate(3,1); lcd.printf(" "); - lcd.locate(11,1); + lcd.locate(3,1); lcd.printf("%d", kdnum); break; - default: - break; - } // Fin switch - } // Fin if + } + } + + if (diferencia != 0 && !state) { + + spnum += diferencia; + + if (spnum >= 999) spnum = 999; + else if (spnum < 0) spnum = 0; + + lcd.locate(10,0); + lcd.printf(" "); + lcd.locate(10,0); + lcd.printf("%d", spnum); + } + if (!button3) { // Cambia la posición de ingreso de parámetros - led3 = !led3; - switch(pos++) { - case 4: + case 3: pos = 1; lcd.locate(3,0); - lcd.printf("%d", spnum); + lcd.printf("%d", kpnum); break; case 1: lcd.locate(11,0); - lcd.printf("%d", kpnum); + lcd.printf("%d", kinum); break; case 2: lcd.locate(3,1); - lcd.printf("%d", kinum); - break; - case 3: - lcd.locate(11,1); lcd.printf("%d", kdnum); break; - default: - break; - } // Fin switch - wait(0.25); - } // Fin if - + } + wait(0.2); + } - if (!button4) { - break; //sale del bucle si pisan suiche4 + if (!button4 && state) { + lcd.cls(); + lcd.locate(8,1); + lcd.printf("**PID**"); + lcd.locate(0,0); + lcd.printf("Set-Point="); + lcd.locate(10,0); + lcd.printf("%d", spnum); + wait(0.2); + state = 0; + } + else if (!button4 && !state) { + wait(0.2); + break; } wait(0.1); } - + -// Transición + // Transición lcd.writeCommand(C4); // Escribimos un comando segun el manual del módulo LCD para quitar cursor bajo - lcd.cls(); // Borra la pantalla - lcd.printf(" GUARDADOS!"); - wait(1); - lcd.cls(); - lcd.printf(" *** PID ***"); - wait(1); - lcd.cls(); - lcd.printf("e=%3.0f",err); - lcd.locate(8,0); - lcd.printf("y=%3.0f",med); - lcd.locate(0,1); - lcd.printf("r=%3.0f",spnum); - lcd.locate(8,1); - lcd.printf("u=%3.0f",pid); - wait(1); + lcd.locate(0,0); lcd.printf("y="); + lcd.locate(8,0); lcd.printf("e="); + lcd.locate(0,1); lcd.printf("r="); + lcd.locate(8,1); lcd.printf("u="); -int referencia; -int salida; +loop: -// CICLO PRINCIPAL CONTROLADOR PID -loop: med = y.read()*999; + if (t.read_ms() - t_pid > 10) { + + med = y.read()*999; err = spnum - med; // Se calcula el error - ap = kpnum*err*0.01f; // Se calcula la acción proporcional + ap = kpnum*err*0.01f; // Se calcula la acción proporcional ai += kinum*err*0.01f; // Cálculo de la integral del error ad = kdnum*(err - err_v)*0.01f; // Cálculo de la acción derivativa pid = ap + ai + ad; - - referencia = (spnum / 999) * 255; - salida = med / 999 * 743 + 256; - - if (referencia < 256) { // Debo generar dos casos a APP inventor solo me recibe hex asi: 0xhhhh (4 cifras) - GSM.putc(0); // si el numero es hasta 255 se le ponen dos ceros adelante a la secuencia de bits - GSM.putc(referencia); // luego la cifra menos significativa - } - /* + + if (pid <= 0) pid = 0; + if (pid > 999) pid = 999; - if (salida > 255){ // pero si es mayor a 255 las cifras deben ser convertidas a un hex de dos bytes de la siguiente forma - j = salida/256; // calculo la cifra mas significativa - k = salida - j*256; // calculo la cifra menos significativa - GSM.putc(j); // las envio a la usart para que se las ponga al modulo bluetooth y la lleve al android - GSM.putc(k); // mas significativa primero, menos despues si no no funciona!!! y con la orden PUTC solo asi le envia binarios - } - - - GSM.putc('r'); // Se envía el set-point al módulo Bluetooth. - if (spnum < 256) { - GSM.putc(0); - GSM.putc(spnum); - } - if (spnum > 255){ - j = spnum/256; - k = spnum - j*256; - GSM.putc(j); - GSM.putc(k); - } - */ - - // Se verifica que pid sea positivo: - if (pid <= 0) - pid = 0; - else if (pid > 999) - pid = 999; + setpoint = spnum; + GSM.printf("#%3.0f%3.0f&", med, setpoint); + + lcd.locate(3,0); lcd.printf("%3.0f ", med); + lcd.locate(3,1); lcd.printf("%3d ", spnum); + lcd.locate(11,0); lcd.printf("%3.0f ", err); + lcd.locate(11,1); lcd.printf("%3.0f ", pid); - - // Se muestran las variables en LCD: - lcd.locate(3,0); - lcd.printf(" "); - lcd.locate(3,0); - lcd.printf("%3.0f",err); - lcd.locate(11,0); - lcd.printf(" "); - lcd.locate(11,0); - lcd.printf("%3.0f",med); - lcd.locate(3,1); - lcd.printf(" "); - lcd.locate(3,1); - lcd.printf("%d",spnum); - lcd.locate(11,1); - lcd.printf(" "); - lcd.locate(11,1); - lcd.printf("%3.0f",pid); - - // Normalización de la salida y actualización de variables: err_v = err; o = pid/999; u.write(o); - // Se repite el ciclo: - wait_ms(300); + t_pid = t.read_ms(); + } + else { + + diferencia=(encoder.getPulses() - cambio)*6; + cambio=encoder.getPulses(); + + if (diferencia != 0) { + spnum += diferencia; + if (spnum >= 999) spnum = 999; + else if (spnum < 0) spnum = 0; + } + + } + + if (!button4) { + u.write(0); + med = 0; + err = 0; + pid = 0; + + goto init; + } + else goto loop; -} + +} \ No newline at end of file