![](/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
main.cpp@3:2e823b16a4a1, 2017-05-13 (annotated)
- Committer:
- NicolasV
- Date:
- Sat May 13 20:36:07 2017 +0000
- Revision:
- 3:2e823b16a4a1
- Parent:
- 2:00db719ebd81
- Child:
- 4:82ac4b34c3d9
Se realiza un controlador PID para controlar el voltaje sobre un condensador. Se transmite el set-point y la salida por medio de Bluetooth a una aplicaci?n de Android en donde se hace la gr?fica de estas se?ales.
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
NicolasV | 2:00db719ebd81 | 1 | /* |
NicolasV | 2:00db719ebd81 | 2 | * Código por: Laura Álvila |
NicolasV | 2:00db719ebd81 | 3 | * Daniela López |
NicolasV | 2:00db719ebd81 | 4 | * Nicolás Villegas |
NicolasV | 2:00db719ebd81 | 5 | */ |
NicolasV | 2:00db719ebd81 | 6 | |
tony63 | 0:4e0dfcf0e7ce | 7 | #include "mbed.h" |
tony63 | 0:4e0dfcf0e7ce | 8 | #include "QEI.h" |
tony63 | 0:4e0dfcf0e7ce | 9 | #include "TextLCD.h" |
tony63 | 0:4e0dfcf0e7ce | 10 | |
NicolasV | 2:00db719ebd81 | 11 | Serial GSM(PTE0,PTE1); // Módulo Bluetooh |
tony63 | 0:4e0dfcf0e7ce | 12 | TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7 |
NicolasV | 3:2e823b16a4a1 | 13 | QEI encoder (PTA13, PTD5, NC, 10); |
NicolasV | 3:2e823b16a4a1 | 14 | Timer t; |
NicolasV | 2:00db719ebd81 | 15 | |
NicolasV | 2:00db719ebd81 | 16 | AnalogIn y(PTC2); // Entrada análoga: Salida del sistema |
NicolasV | 2:00db719ebd81 | 17 | AnalogOut u(PTE30); // Salida análoga: Señal de control |
NicolasV | 2:00db719ebd81 | 18 | |
tony63 | 0:4e0dfcf0e7ce | 19 | DigitalOut led1(LED1); |
tony63 | 0:4e0dfcf0e7ce | 20 | DigitalOut led2(LED2); |
tony63 | 0:4e0dfcf0e7ce | 21 | DigitalOut led3(LED3); |
tony63 | 0:4e0dfcf0e7ce | 22 | |
NicolasV | 2:00db719ebd81 | 23 | DigitalIn button3(PTC16); // Botón del encoder |
NicolasV | 2:00db719ebd81 | 24 | DigitalIn button4(PTC17); // Pulsador |
tony63 | 0:4e0dfcf0e7ce | 25 | |
NicolasV | 2:00db719ebd81 | 26 | // Códigos movimiento del cursor: |
NicolasV | 2:00db719ebd81 | 27 | int C1=0x0F; |
tony63 | 0:4e0dfcf0e7ce | 28 | int C2=0x18; // desplaza izquierda |
tony63 | 0:4e0dfcf0e7ce | 29 | int C3=0x1A; // desplaza derecha |
tony63 | 0:4e0dfcf0e7ce | 30 | int C4=0x0C; // quito cursor bajo |
tony63 | 0:4e0dfcf0e7ce | 31 | |
NicolasV | 2:00db719ebd81 | 32 | int cambio = 0, diferencia = 0; |
NicolasV | 3:2e823b16a4a1 | 33 | float pid, o, ai, ad, ap, med, err, setpoint; |
tony63 | 1:058b8f5c135d | 34 | float err_v; |
NicolasV | 2:00db719ebd81 | 35 | int spnum = 0, kinum = 0, kpnum = 0 ,kdnum = 0, pos = 1; |
NicolasV | 2:00db719ebd81 | 36 | int j,k; |
NicolasV | 3:2e823b16a4a1 | 37 | long t_pid = 0, t_btn = 0; |
tony63 | 0:4e0dfcf0e7ce | 38 | |
NicolasV | 2:00db719ebd81 | 39 | int main() { |
NicolasV | 3:2e823b16a4a1 | 40 | |
NicolasV | 2:00db719ebd81 | 41 | // Se asigna baudrate y se configura el puerto serie de la USART |
NicolasV | 3:2e823b16a4a1 | 42 | |
NicolasV | 2:00db719ebd81 | 43 | GSM.baud(9600); |
NicolasV | 2:00db719ebd81 | 44 | GSM.format(8,Serial::None,1); |
NicolasV | 3:2e823b16a4a1 | 45 | t.start(); |
NicolasV | 3:2e823b16a4a1 | 46 | |
NicolasV | 3:2e823b16a4a1 | 47 | for (int i = 3; i < 24; ++i) { |
NicolasV | 3:2e823b16a4a1 | 48 | lcd.cls(); |
NicolasV | 3:2e823b16a4a1 | 49 | lcd.locate(0,0); |
NicolasV | 3:2e823b16a4a1 | 50 | lcd.printf("**Control PID**"); |
NicolasV | 3:2e823b16a4a1 | 51 | wait_ms(1000/i); |
NicolasV | 3:2e823b16a4a1 | 52 | |
NicolasV | 3:2e823b16a4a1 | 53 | ++i; |
NicolasV | 3:2e823b16a4a1 | 54 | lcd.cls(); |
NicolasV | 3:2e823b16a4a1 | 55 | lcd.locate(1,0); |
NicolasV | 3:2e823b16a4a1 | 56 | lcd.printf("**Control PID**"); |
NicolasV | 3:2e823b16a4a1 | 57 | wait_ms(1000/i); |
NicolasV | 3:2e823b16a4a1 | 58 | |
NicolasV | 3:2e823b16a4a1 | 59 | ++i; |
NicolasV | 3:2e823b16a4a1 | 60 | lcd.cls(); |
NicolasV | 3:2e823b16a4a1 | 61 | lcd.locate(1,1); |
NicolasV | 3:2e823b16a4a1 | 62 | lcd.printf("**Control PID**"); |
NicolasV | 3:2e823b16a4a1 | 63 | wait_ms(1000/i); |
NicolasV | 3:2e823b16a4a1 | 64 | |
NicolasV | 3:2e823b16a4a1 | 65 | ++i; |
NicolasV | 3:2e823b16a4a1 | 66 | lcd.cls(); |
NicolasV | 3:2e823b16a4a1 | 67 | lcd.locate(0,1); |
NicolasV | 3:2e823b16a4a1 | 68 | lcd.printf("**Control PID**"); |
NicolasV | 3:2e823b16a4a1 | 69 | wait_ms(1000/i); |
NicolasV | 3:2e823b16a4a1 | 70 | } |
NicolasV | 3:2e823b16a4a1 | 71 | |
NicolasV | 3:2e823b16a4a1 | 72 | init: |
NicolasV | 3:2e823b16a4a1 | 73 | |
NicolasV | 3:2e823b16a4a1 | 74 | lcd.cls(); |
NicolasV | 3:2e823b16a4a1 | 75 | lcd.writeCommand(C1); |
NicolasV | 3:2e823b16a4a1 | 76 | |
NicolasV | 3:2e823b16a4a1 | 77 | lcd.locate(8,0); |
NicolasV | 3:2e823b16a4a1 | 78 | lcd.printf("Ki=%d", kinum); |
NicolasV | 2:00db719ebd81 | 79 | |
tony63 | 0:4e0dfcf0e7ce | 80 | lcd.locate(0,1); |
NicolasV | 3:2e823b16a4a1 | 81 | lcd.printf("Kd=%d", kdnum); |
NicolasV | 2:00db719ebd81 | 82 | |
NicolasV | 3:2e823b16a4a1 | 83 | lcd.locate(8,1); |
NicolasV | 3:2e823b16a4a1 | 84 | lcd.printf("**PID**"); |
NicolasV | 3:2e823b16a4a1 | 85 | |
NicolasV | 3:2e823b16a4a1 | 86 | lcd.locate(0,0); |
NicolasV | 2:00db719ebd81 | 87 | lcd.printf("Kp=%d", kpnum); |
NicolasV | 3:2e823b16a4a1 | 88 | |
NicolasV | 3:2e823b16a4a1 | 89 | bool state = 1; |
NicolasV | 3:2e823b16a4a1 | 90 | |
NicolasV | 2:00db719ebd81 | 91 | while(true) { |
tony63 | 0:4e0dfcf0e7ce | 92 | |
NicolasV | 3:2e823b16a4a1 | 93 | diferencia=(encoder.getPulses() - cambio)*3; |
tony63 | 0:4e0dfcf0e7ce | 94 | cambio=encoder.getPulses(); |
NicolasV | 2:00db719ebd81 | 95 | |
NicolasV | 3:2e823b16a4a1 | 96 | if (diferencia != 0 && state) { |
NicolasV | 2:00db719ebd81 | 97 | switch (pos) { |
NicolasV | 2:00db719ebd81 | 98 | case 1: |
NicolasV | 2:00db719ebd81 | 99 | kpnum += diferencia; |
NicolasV | 2:00db719ebd81 | 100 | |
NicolasV | 2:00db719ebd81 | 101 | if (kpnum >= 999) |
NicolasV | 2:00db719ebd81 | 102 | kpnum = 999; |
NicolasV | 2:00db719ebd81 | 103 | else if (kpnum < 0) |
NicolasV | 2:00db719ebd81 | 104 | kpnum = 0; |
NicolasV | 3:2e823b16a4a1 | 105 | |
NicolasV | 3:2e823b16a4a1 | 106 | lcd.locate(3,0); |
tony63 | 0:4e0dfcf0e7ce | 107 | lcd.printf(" "); |
NicolasV | 3:2e823b16a4a1 | 108 | lcd.locate(3,0); |
tony63 | 0:4e0dfcf0e7ce | 109 | lcd.printf("%d", kpnum); |
NicolasV | 2:00db719ebd81 | 110 | break; |
NicolasV | 3:2e823b16a4a1 | 111 | case 2: |
NicolasV | 2:00db719ebd81 | 112 | kinum += diferencia; |
NicolasV | 2:00db719ebd81 | 113 | |
NicolasV | 2:00db719ebd81 | 114 | if (kinum >= 999) |
NicolasV | 2:00db719ebd81 | 115 | kinum = 999; |
NicolasV | 2:00db719ebd81 | 116 | else if (kinum < 0) |
NicolasV | 2:00db719ebd81 | 117 | kinum = 0; |
NicolasV | 2:00db719ebd81 | 118 | |
NicolasV | 3:2e823b16a4a1 | 119 | lcd.locate(11,0); |
tony63 | 0:4e0dfcf0e7ce | 120 | lcd.printf(" "); |
NicolasV | 3:2e823b16a4a1 | 121 | lcd.locate(11,0); |
tony63 | 0:4e0dfcf0e7ce | 122 | lcd.printf("%d", kinum); |
NicolasV | 2:00db719ebd81 | 123 | break; |
NicolasV | 3:2e823b16a4a1 | 124 | case 3: |
NicolasV | 2:00db719ebd81 | 125 | kdnum += diferencia; |
NicolasV | 2:00db719ebd81 | 126 | |
NicolasV | 2:00db719ebd81 | 127 | if (kdnum >= 999) |
NicolasV | 2:00db719ebd81 | 128 | kdnum = 999; |
NicolasV | 2:00db719ebd81 | 129 | else if (kdnum < 0) |
NicolasV | 2:00db719ebd81 | 130 | kdnum = 0; |
NicolasV | 2:00db719ebd81 | 131 | |
NicolasV | 3:2e823b16a4a1 | 132 | lcd.locate(3,1); |
tony63 | 0:4e0dfcf0e7ce | 133 | lcd.printf(" "); |
NicolasV | 3:2e823b16a4a1 | 134 | lcd.locate(3,1); |
tony63 | 0:4e0dfcf0e7ce | 135 | lcd.printf("%d", kdnum); |
NicolasV | 2:00db719ebd81 | 136 | break; |
NicolasV | 3:2e823b16a4a1 | 137 | } |
NicolasV | 3:2e823b16a4a1 | 138 | } |
NicolasV | 3:2e823b16a4a1 | 139 | |
NicolasV | 3:2e823b16a4a1 | 140 | if (diferencia != 0 && !state) { |
NicolasV | 3:2e823b16a4a1 | 141 | |
NicolasV | 3:2e823b16a4a1 | 142 | spnum += diferencia; |
NicolasV | 3:2e823b16a4a1 | 143 | |
NicolasV | 3:2e823b16a4a1 | 144 | if (spnum >= 999) spnum = 999; |
NicolasV | 3:2e823b16a4a1 | 145 | else if (spnum < 0) spnum = 0; |
NicolasV | 3:2e823b16a4a1 | 146 | |
NicolasV | 3:2e823b16a4a1 | 147 | lcd.locate(10,0); |
NicolasV | 3:2e823b16a4a1 | 148 | lcd.printf(" "); |
NicolasV | 3:2e823b16a4a1 | 149 | lcd.locate(10,0); |
NicolasV | 3:2e823b16a4a1 | 150 | lcd.printf("%d", spnum); |
NicolasV | 3:2e823b16a4a1 | 151 | } |
NicolasV | 3:2e823b16a4a1 | 152 | |
NicolasV | 2:00db719ebd81 | 153 | |
NicolasV | 2:00db719ebd81 | 154 | if (!button3) { // Cambia la posición de ingreso de parámetros |
NicolasV | 2:00db719ebd81 | 155 | led3 = !led3; |
NicolasV | 2:00db719ebd81 | 156 | switch(pos++) { |
NicolasV | 3:2e823b16a4a1 | 157 | case 3: |
NicolasV | 2:00db719ebd81 | 158 | pos = 1; |
tony63 | 0:4e0dfcf0e7ce | 159 | lcd.locate(3,0); |
NicolasV | 3:2e823b16a4a1 | 160 | lcd.printf("%d", kpnum); |
NicolasV | 2:00db719ebd81 | 161 | break; |
NicolasV | 2:00db719ebd81 | 162 | case 1: |
tony63 | 0:4e0dfcf0e7ce | 163 | lcd.locate(11,0); |
NicolasV | 3:2e823b16a4a1 | 164 | lcd.printf("%d", kinum); |
NicolasV | 2:00db719ebd81 | 165 | break; |
NicolasV | 2:00db719ebd81 | 166 | case 2: |
tony63 | 0:4e0dfcf0e7ce | 167 | lcd.locate(3,1); |
tony63 | 0:4e0dfcf0e7ce | 168 | lcd.printf("%d", kdnum); |
NicolasV | 2:00db719ebd81 | 169 | break; |
NicolasV | 3:2e823b16a4a1 | 170 | } |
NicolasV | 3:2e823b16a4a1 | 171 | wait(0.2); |
NicolasV | 3:2e823b16a4a1 | 172 | } |
tony63 | 0:4e0dfcf0e7ce | 173 | |
NicolasV | 3:2e823b16a4a1 | 174 | if (!button4 && state) { |
NicolasV | 3:2e823b16a4a1 | 175 | lcd.cls(); |
NicolasV | 3:2e823b16a4a1 | 176 | lcd.locate(8,1); |
NicolasV | 3:2e823b16a4a1 | 177 | lcd.printf("**PID**"); |
NicolasV | 3:2e823b16a4a1 | 178 | lcd.locate(0,0); |
NicolasV | 3:2e823b16a4a1 | 179 | lcd.printf("Set-Point="); |
NicolasV | 3:2e823b16a4a1 | 180 | lcd.locate(10,0); |
NicolasV | 3:2e823b16a4a1 | 181 | lcd.printf("%d", spnum); |
NicolasV | 3:2e823b16a4a1 | 182 | wait(0.2); |
NicolasV | 3:2e823b16a4a1 | 183 | state = 0; |
NicolasV | 3:2e823b16a4a1 | 184 | } |
NicolasV | 3:2e823b16a4a1 | 185 | else if (!button4 && !state) { |
NicolasV | 3:2e823b16a4a1 | 186 | wait(0.2); |
NicolasV | 3:2e823b16a4a1 | 187 | break; |
tony63 | 0:4e0dfcf0e7ce | 188 | } |
tony63 | 0:4e0dfcf0e7ce | 189 | wait(0.1); |
tony63 | 0:4e0dfcf0e7ce | 190 | } |
NicolasV | 3:2e823b16a4a1 | 191 | |
tony63 | 0:4e0dfcf0e7ce | 192 | |
NicolasV | 3:2e823b16a4a1 | 193 | // Transición |
NicolasV | 2:00db719ebd81 | 194 | lcd.writeCommand(C4); // Escribimos un comando segun el manual del módulo LCD para quitar cursor bajo |
tony63 | 0:4e0dfcf0e7ce | 195 | lcd.cls(); |
NicolasV | 3:2e823b16a4a1 | 196 | lcd.locate(0,0); lcd.printf("y="); |
NicolasV | 3:2e823b16a4a1 | 197 | lcd.locate(8,0); lcd.printf("e="); |
NicolasV | 3:2e823b16a4a1 | 198 | lcd.locate(0,1); lcd.printf("r="); |
NicolasV | 3:2e823b16a4a1 | 199 | lcd.locate(8,1); lcd.printf("u="); |
tony63 | 0:4e0dfcf0e7ce | 200 | |
NicolasV | 3:2e823b16a4a1 | 201 | loop: |
NicolasV | 2:00db719ebd81 | 202 | |
NicolasV | 3:2e823b16a4a1 | 203 | if (t.read_ms() - t_pid > 10) { |
NicolasV | 3:2e823b16a4a1 | 204 | |
NicolasV | 3:2e823b16a4a1 | 205 | med = y.read()*999; |
NicolasV | 2:00db719ebd81 | 206 | err = spnum - med; // Se calcula el error |
NicolasV | 3:2e823b16a4a1 | 207 | ap = kpnum*err*0.01f; // Se calcula la acción proporcional |
NicolasV | 2:00db719ebd81 | 208 | ai += kinum*err*0.01f; // Cálculo de la integral del error |
NicolasV | 2:00db719ebd81 | 209 | ad = kdnum*(err - err_v)*0.01f; // Cálculo de la acción derivativa |
NicolasV | 2:00db719ebd81 | 210 | pid = ap + ai + ad; |
NicolasV | 3:2e823b16a4a1 | 211 | |
NicolasV | 3:2e823b16a4a1 | 212 | if (pid <= 0) pid = 0; |
NicolasV | 3:2e823b16a4a1 | 213 | if (pid > 999) pid = 999; |
NicolasV | 2:00db719ebd81 | 214 | |
NicolasV | 3:2e823b16a4a1 | 215 | setpoint = spnum; |
NicolasV | 3:2e823b16a4a1 | 216 | GSM.printf("#%3.0f%3.0f&", med, setpoint); |
NicolasV | 3:2e823b16a4a1 | 217 | |
NicolasV | 3:2e823b16a4a1 | 218 | lcd.locate(3,0); lcd.printf("%3.0f ", med); |
NicolasV | 3:2e823b16a4a1 | 219 | lcd.locate(3,1); lcd.printf("%3d ", spnum); |
NicolasV | 3:2e823b16a4a1 | 220 | lcd.locate(11,0); lcd.printf("%3.0f ", err); |
NicolasV | 3:2e823b16a4a1 | 221 | lcd.locate(11,1); lcd.printf("%3.0f ", pid); |
tony63 | 0:4e0dfcf0e7ce | 222 | |
tony63 | 1:058b8f5c135d | 223 | err_v = err; |
tony63 | 1:058b8f5c135d | 224 | o = pid/999; |
tony63 | 1:058b8f5c135d | 225 | u.write(o); |
tony63 | 1:058b8f5c135d | 226 | |
NicolasV | 3:2e823b16a4a1 | 227 | t_pid = t.read_ms(); |
NicolasV | 3:2e823b16a4a1 | 228 | } |
NicolasV | 3:2e823b16a4a1 | 229 | else { |
NicolasV | 3:2e823b16a4a1 | 230 | |
NicolasV | 3:2e823b16a4a1 | 231 | diferencia=(encoder.getPulses() - cambio)*6; |
NicolasV | 3:2e823b16a4a1 | 232 | cambio=encoder.getPulses(); |
NicolasV | 3:2e823b16a4a1 | 233 | |
NicolasV | 3:2e823b16a4a1 | 234 | if (diferencia != 0) { |
NicolasV | 3:2e823b16a4a1 | 235 | spnum += diferencia; |
NicolasV | 3:2e823b16a4a1 | 236 | if (spnum >= 999) spnum = 999; |
NicolasV | 3:2e823b16a4a1 | 237 | else if (spnum < 0) spnum = 0; |
NicolasV | 3:2e823b16a4a1 | 238 | } |
NicolasV | 3:2e823b16a4a1 | 239 | |
NicolasV | 3:2e823b16a4a1 | 240 | } |
NicolasV | 3:2e823b16a4a1 | 241 | |
NicolasV | 3:2e823b16a4a1 | 242 | if (!button4) { |
NicolasV | 3:2e823b16a4a1 | 243 | u.write(0); |
NicolasV | 3:2e823b16a4a1 | 244 | med = 0; |
NicolasV | 3:2e823b16a4a1 | 245 | err = 0; |
NicolasV | 3:2e823b16a4a1 | 246 | pid = 0; |
NicolasV | 3:2e823b16a4a1 | 247 | |
NicolasV | 3:2e823b16a4a1 | 248 | goto init; |
NicolasV | 3:2e823b16a4a1 | 249 | } |
NicolasV | 3:2e823b16a4a1 | 250 | else |
NicolasV | 2:00db719ebd81 | 251 | goto loop; |
NicolasV | 3:2e823b16a4a1 | 252 | |
NicolasV | 3:2e823b16a4a1 | 253 | } |