PID for ramp temperature control using LM35 temperature sensor and two actuators, a bulb and a ventilator.

Dependencies:   DebouncedIn QEI TextLCD_encoder mbed

Fork of PID_Encoder by Gustavo Ramirez

Committer:
Gregorio
Date:
Thu Jun 12 16:43:28 2014 +0000
Revision:
5:ad88703dc6d3
Parent:
4:d42fe3777735
PID for ramp temperature control using LM35 temperature sensor and two actuators, a bulb and a ventilator.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
lcorralesc1 0:8d2bbee60422 1 #include "mbed.h"
lcorralesc1 0:8d2bbee60422 2 #include "DebouncedIn.h"
lcorralesc1 0:8d2bbee60422 3 #include "TextLCD.h"
Gregorio 5:ad88703dc6d3 4 #include "QEI.h"
lcorralesc1 0:8d2bbee60422 5
Gregorio 5:ad88703dc6d3 6 TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7 entradas del LCD
Gregorio 5:ad88703dc6d3 7 QEI wheel (PTD5, PTD0, NC, 100); // entradas para el ENCODER
Gregorio 5:ad88703dc6d3 8 AnalogIn LM(PTB1); // temperatura leida por un LM35
Gregorio 5:ad88703dc6d3 9 PwmOut bomb(PTD4); //salida para activar un bombillo
Gregorio 5:ad88703dc6d3 10 PwmOut vent(PTA12); //salida para activar un ventilador
Gregorio 5:ad88703dc6d3 11 DigitalOut led3(LED3); // Led para indicar que los botones se presionan
Gregorio 5:ad88703dc6d3 12 DebouncedIn button3(PTC16); //boton 3 es el pulsador del ENCODER
Gregorio 5:ad88703dc6d3 13 DebouncedIn button4(PTA13); // boton 4 es para la configuración de las constantes del pid, de tiempo de rampa y de temperatura del horno
lcorralesc1 0:8d2bbee60422 14
Gregorio 5:ad88703dc6d3 15 //codigos movimiento del curzor LCD
lcorralesc1 0:8d2bbee60422 16 int C2=0x18; // desplaza izquierda
lcorralesc1 0:8d2bbee60422 17 int C3=0x1A; // desplaza derecha
lcorralesc1 0:8d2bbee60422 18 int C4=0x0C; // quito cursor bajo
Gregorio 5:ad88703dc6d3 19 int C1=0x0F; // solo muestra el curzor
Gregorio 5:ad88703dc6d3 20
lcorralesc1 0:8d2bbee60422 21
Gregorio 5:ad88703dc6d3 22 //definicion de varibles
Gregorio 5:ad88703dc6d3 23 int i=1; // i controla cambio de "modo" del boton 4. i=1 -> (constantes PID), i=2 -> (Tiempo y temperatura)
Gregorio 5:ad88703dc6d3 24 int j=1; //j controla cambio de posiciones para cambiar variable (con el boton del ENCODER)
Gregorio 5:ad88703dc6d3 25 int kp=40, ki=40, kd=40, sp; //constantes del pid y del setpoint
Gregorio 5:ad88703dc6d3 26 int t1=60, t2=60, t3=60; //tiempos de la rapmpa de subida, temperatura estable y tiempo de bajada t1=t2=t3 [segundos]
Gregorio 5:ad88703dc6d3 27 int temp=45; // temp:temperatura final a la que llega el horno[ºC]
Gregorio 5:ad88703dc6d3 28 float ta, avg, a[10]; // ta: temperatura ambiente que se lee con el LM35, antes de empezar control, avg, promedio de temperatura para minimizar error
Gregorio 5:ad88703dc6d3 29 float yr, ap, ai, ad, err, med, err_v, cycle, pid; //
Gregorio 5:ad88703dc6d3 30 float dt1, dt2, dt3,c=0; // variables para ciclos de control en tiempos t1, t2 y t3
Gregorio 5:ad88703dc6d3 31 int b=0; // Se usa para imprimir datos en la LCD
lcorralesc1 0:8d2bbee60422 32 float pidn;
lcorralesc1 3:9347b362d33c 33 Timer t;
lcorralesc1 0:8d2bbee60422 34
Gregorio 5:ad88703dc6d3 35 // Inicia el código
Gregorio 5:ad88703dc6d3 36 int main()
Gregorio 5:ad88703dc6d3 37 {
lcorralesc1 0:8d2bbee60422 38 while(1) {
Gregorio 5:ad88703dc6d3 39 if(i==1) {
Gregorio 5:ad88703dc6d3 40 lcd.cls();
Gregorio 5:ad88703dc6d3 41 lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD
Gregorio 5:ad88703dc6d3 42 lcd.locate(0,0);
Gregorio 5:ad88703dc6d3 43 lcd.printf(" PID");
Gregorio 5:ad88703dc6d3 44 lcd.locate(8,0);
Gregorio 5:ad88703dc6d3 45 lcd.printf("Kp:%d",kp);
Gregorio 5:ad88703dc6d3 46 lcd.locate(0,1);
Gregorio 5:ad88703dc6d3 47 lcd.printf("Ki:%d",ki);
Gregorio 5:ad88703dc6d3 48 lcd.locate(8,1);
Gregorio 5:ad88703dc6d3 49 lcd.printf("Kd:%d",kd);
Gregorio 5:ad88703dc6d3 50
Gregorio 5:ad88703dc6d3 51 led3 =1;
Gregorio 5:ad88703dc6d3 52 if (button3.falling()) { //INCREMENTA POSICION DEL MENU CON BOTON 3 (Switche encoder)
Gregorio 5:ad88703dc6d3 53 led3 =!led3;
Gregorio 5:ad88703dc6d3 54 }
Gregorio 5:ad88703dc6d3 55
Gregorio 5:ad88703dc6d3 56 if (j==1) {
Gregorio 5:ad88703dc6d3 57 kp=kp+wheel.getPulses();
Gregorio 5:ad88703dc6d3 58 wheel.reset();
Gregorio 5:ad88703dc6d3 59 if (kp>999) {
Gregorio 5:ad88703dc6d3 60 kp=999;
Gregorio 5:ad88703dc6d3 61 }
Gregorio 5:ad88703dc6d3 62 if (kp<0) {
Gregorio 5:ad88703dc6d3 63 kp=0;
Gregorio 5:ad88703dc6d3 64 }
Gregorio 5:ad88703dc6d3 65 lcd.locate(11,0);
Gregorio 5:ad88703dc6d3 66 lcd.printf(" ");
Gregorio 5:ad88703dc6d3 67 lcd.locate(11,0);
Gregorio 5:ad88703dc6d3 68 lcd.printf("%d",kp);
Gregorio 5:ad88703dc6d3 69 wait(0.2);
Gregorio 5:ad88703dc6d3 70
Gregorio 5:ad88703dc6d3 71 if(button3.falling()) {
Gregorio 5:ad88703dc6d3 72 j=2;
Gregorio 5:ad88703dc6d3 73 led3=0;
Gregorio 5:ad88703dc6d3 74 wait(0.3);
Gregorio 5:ad88703dc6d3 75 wheel.reset();
Gregorio 5:ad88703dc6d3 76 }
Gregorio 5:ad88703dc6d3 77 }
Gregorio 5:ad88703dc6d3 78 if (j==2) {
Gregorio 5:ad88703dc6d3 79 ki=ki+wheel.getPulses();
Gregorio 5:ad88703dc6d3 80 wheel.reset();
Gregorio 5:ad88703dc6d3 81 if (ki>999) {
Gregorio 5:ad88703dc6d3 82 ki=999;
Gregorio 5:ad88703dc6d3 83 }
Gregorio 5:ad88703dc6d3 84 if (ki<0) {
Gregorio 5:ad88703dc6d3 85 ki=0;
Gregorio 5:ad88703dc6d3 86 }
Gregorio 5:ad88703dc6d3 87 lcd.locate(3,1);
Gregorio 5:ad88703dc6d3 88 lcd.printf(" ");
Gregorio 5:ad88703dc6d3 89 lcd.locate(3,1);
Gregorio 5:ad88703dc6d3 90 lcd.printf("%d",ki);
Gregorio 5:ad88703dc6d3 91 wait(0.2);
Gregorio 5:ad88703dc6d3 92
Gregorio 5:ad88703dc6d3 93 if(button3.falling()) {
Gregorio 5:ad88703dc6d3 94 j=3;
Gregorio 5:ad88703dc6d3 95 led3=0;
Gregorio 5:ad88703dc6d3 96 wait(0.3);
Gregorio 5:ad88703dc6d3 97 wheel.reset();
Gregorio 5:ad88703dc6d3 98 }
Gregorio 5:ad88703dc6d3 99 }
Gregorio 5:ad88703dc6d3 100 if (j==3) {
Gregorio 5:ad88703dc6d3 101 kd=kd+wheel.getPulses();
Gregorio 5:ad88703dc6d3 102 wheel.reset();
Gregorio 5:ad88703dc6d3 103 if (kd>999) {
Gregorio 5:ad88703dc6d3 104 kd=999;
Gregorio 5:ad88703dc6d3 105 }
Gregorio 5:ad88703dc6d3 106 if (kd<0) {
Gregorio 5:ad88703dc6d3 107 kd=0;
Gregorio 5:ad88703dc6d3 108 }
Gregorio 5:ad88703dc6d3 109 lcd.locate(11,1);
Gregorio 5:ad88703dc6d3 110 lcd.printf(" ");
Gregorio 5:ad88703dc6d3 111 lcd.locate(11,1);
Gregorio 5:ad88703dc6d3 112 lcd.printf("%d",kd);
Gregorio 5:ad88703dc6d3 113 wait(0.2);
Gregorio 5:ad88703dc6d3 114
Gregorio 5:ad88703dc6d3 115 if(button3.falling()) {
Gregorio 5:ad88703dc6d3 116 j=1;
Gregorio 5:ad88703dc6d3 117 led3=0;
Gregorio 5:ad88703dc6d3 118 wait(0.3);
Gregorio 5:ad88703dc6d3 119 wheel.reset();
Gregorio 5:ad88703dc6d3 120 }
Gregorio 5:ad88703dc6d3 121 }
Gregorio 5:ad88703dc6d3 122 if (j==4) {
Gregorio 5:ad88703dc6d3 123 j=1;
Gregorio 5:ad88703dc6d3 124 }
Gregorio 5:ad88703dc6d3 125 if(button4.falling()) {
Gregorio 5:ad88703dc6d3 126 i=2;
Gregorio 5:ad88703dc6d3 127 j=0;
Gregorio 5:ad88703dc6d3 128 }
Gregorio 5:ad88703dc6d3 129 }//CIERRA EL MODO i=1 -> constantes PID
Gregorio 5:ad88703dc6d3 130 if(i==2) { //INICIA EL MODO i=2 -> tiempos y temperatura
Gregorio 5:ad88703dc6d3 131 lcd.cls();
Gregorio 5:ad88703dc6d3 132 lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD
Gregorio 5:ad88703dc6d3 133 lcd.locate(0,0);
Gregorio 5:ad88703dc6d3 134 lcd.printf("T1:%d",t1);
Gregorio 5:ad88703dc6d3 135 lcd.locate(8,0);
Gregorio 5:ad88703dc6d3 136 lcd.printf("T2:%d",t2);
Gregorio 5:ad88703dc6d3 137 lcd.locate(0,1);
Gregorio 5:ad88703dc6d3 138 lcd.printf("T3:%d",t3);
Gregorio 5:ad88703dc6d3 139 lcd.locate(8,1);
Gregorio 5:ad88703dc6d3 140 lcd.printf("Tm:%d",temp);
Gregorio 5:ad88703dc6d3 141
Gregorio 5:ad88703dc6d3 142
Gregorio 5:ad88703dc6d3 143 led3 =1;
Gregorio 5:ad88703dc6d3 144 if (button3.falling()) { //INCREMENTA POSICION DEL MENU CON BOTON 3 (Switche encoder)
Gregorio 5:ad88703dc6d3 145 led3 =!led3;
Gregorio 5:ad88703dc6d3 146 }
Gregorio 5:ad88703dc6d3 147 if (j==0) {
Gregorio 5:ad88703dc6d3 148 t1=t1+wheel.getPulses();
Gregorio 5:ad88703dc6d3 149 wheel.reset();
Gregorio 5:ad88703dc6d3 150 if (t1>5*60) { // Tiempos no mayores a 6 minutos
Gregorio 5:ad88703dc6d3 151 t1=5*60;
Gregorio 5:ad88703dc6d3 152 }
Gregorio 5:ad88703dc6d3 153 if (t1<60) {
Gregorio 5:ad88703dc6d3 154 t1=60;
Gregorio 5:ad88703dc6d3 155 }
Gregorio 5:ad88703dc6d3 156 lcd.locate(3,0);
Gregorio 5:ad88703dc6d3 157 lcd.printf(" ",t1);
Gregorio 5:ad88703dc6d3 158 lcd.locate(3,0);
Gregorio 5:ad88703dc6d3 159 lcd.printf("%d",t1);
Gregorio 5:ad88703dc6d3 160 wait(0.2);
Gregorio 5:ad88703dc6d3 161
Gregorio 5:ad88703dc6d3 162 if(button3.falling()) {
Gregorio 5:ad88703dc6d3 163 j=1;
Gregorio 5:ad88703dc6d3 164 led3=0;
Gregorio 5:ad88703dc6d3 165 wait(0.3);
Gregorio 5:ad88703dc6d3 166 wheel.reset();
Gregorio 5:ad88703dc6d3 167 }
Gregorio 5:ad88703dc6d3 168 }
Gregorio 5:ad88703dc6d3 169
Gregorio 5:ad88703dc6d3 170 if (j==1) {
Gregorio 5:ad88703dc6d3 171 t2=t2+wheel.getPulses();
Gregorio 5:ad88703dc6d3 172 wheel.reset();
Gregorio 5:ad88703dc6d3 173 if (t2>5*60) {
Gregorio 5:ad88703dc6d3 174 t2=5*60;
Gregorio 5:ad88703dc6d3 175 }
Gregorio 5:ad88703dc6d3 176 if (t2<60) {
Gregorio 5:ad88703dc6d3 177 t2=60;
Gregorio 5:ad88703dc6d3 178 }
Gregorio 5:ad88703dc6d3 179 lcd.locate(11,0);
Gregorio 5:ad88703dc6d3 180 lcd.printf(" ");
Gregorio 5:ad88703dc6d3 181 lcd.locate(11,0);
Gregorio 5:ad88703dc6d3 182 lcd.printf("%d",t2);
Gregorio 5:ad88703dc6d3 183 wait(0.2);
Gregorio 5:ad88703dc6d3 184
Gregorio 5:ad88703dc6d3 185 if(button3.falling()) {
Gregorio 5:ad88703dc6d3 186 j=2;
Gregorio 5:ad88703dc6d3 187 led3=0;
Gregorio 5:ad88703dc6d3 188 wait(0.3);
Gregorio 5:ad88703dc6d3 189 wheel.reset();
Gregorio 5:ad88703dc6d3 190 }
Gregorio 5:ad88703dc6d3 191 }
Gregorio 5:ad88703dc6d3 192 if (j==2) {
Gregorio 5:ad88703dc6d3 193 t3=t3+wheel.getPulses();
Gregorio 5:ad88703dc6d3 194 wheel.reset();
Gregorio 5:ad88703dc6d3 195 if (t3>5*60) {
Gregorio 5:ad88703dc6d3 196 t3=5*60;
Gregorio 5:ad88703dc6d3 197 }
Gregorio 5:ad88703dc6d3 198 if (t3<60) {
Gregorio 5:ad88703dc6d3 199 t3=60;
Gregorio 5:ad88703dc6d3 200 }
Gregorio 5:ad88703dc6d3 201 lcd.locate(3,1);
Gregorio 5:ad88703dc6d3 202 lcd.printf(" ");
Gregorio 5:ad88703dc6d3 203 lcd.locate(3,1);
Gregorio 5:ad88703dc6d3 204 lcd.printf("%d",t3);
Gregorio 5:ad88703dc6d3 205 wait(0.2);
Gregorio 5:ad88703dc6d3 206
Gregorio 5:ad88703dc6d3 207 if(button3.falling()) {
Gregorio 5:ad88703dc6d3 208 j=3;
Gregorio 5:ad88703dc6d3 209 led3=0;
Gregorio 5:ad88703dc6d3 210 wait(0.3);
Gregorio 5:ad88703dc6d3 211 wheel.reset();
Gregorio 5:ad88703dc6d3 212 }
Gregorio 5:ad88703dc6d3 213 }
Gregorio 5:ad88703dc6d3 214 if (j==3) {
Gregorio 5:ad88703dc6d3 215 temp=temp+wheel.getPulses();
Gregorio 5:ad88703dc6d3 216 wheel.reset();
Gregorio 5:ad88703dc6d3 217 if (temp>60) {
Gregorio 5:ad88703dc6d3 218 temp=60;
Gregorio 5:ad88703dc6d3 219 }
Gregorio 5:ad88703dc6d3 220 if (temp<20) {
Gregorio 5:ad88703dc6d3 221 temp=20;
Gregorio 5:ad88703dc6d3 222 }
Gregorio 5:ad88703dc6d3 223 lcd.locate(11,1);
Gregorio 5:ad88703dc6d3 224 lcd.printf(" ");
Gregorio 5:ad88703dc6d3 225 lcd.locate(11,1);
Gregorio 5:ad88703dc6d3 226 lcd.printf("%d",temp);
Gregorio 5:ad88703dc6d3 227 wait(0.2);
Gregorio 5:ad88703dc6d3 228
Gregorio 5:ad88703dc6d3 229 if(button3.falling()) {
Gregorio 5:ad88703dc6d3 230 j=0;
Gregorio 5:ad88703dc6d3 231 led3=0;
Gregorio 5:ad88703dc6d3 232 wait(0.3);
Gregorio 5:ad88703dc6d3 233 wheel.reset();
Gregorio 5:ad88703dc6d3 234 }
Gregorio 5:ad88703dc6d3 235 }
Gregorio 5:ad88703dc6d3 236 if (j==4) {
Gregorio 5:ad88703dc6d3 237 j=0;
Gregorio 5:ad88703dc6d3 238 }
Gregorio 5:ad88703dc6d3 239 if (button4.falling()) {
Gregorio 5:ad88703dc6d3 240 break;
Gregorio 5:ad88703dc6d3 241 }
Gregorio 5:ad88703dc6d3 242 }//CIERRE MODO i=2 -> tiempo y temperatura
Gregorio 5:ad88703dc6d3 243 }// Cierre del while(1)
Gregorio 5:ad88703dc6d3 244 //%---------------------------------------------------------------------
Gregorio 5:ad88703dc6d3 245
Gregorio 5:ad88703dc6d3 246
Gregorio 5:ad88703dc6d3 247 lcd.writeCommand(C4);//escribimos un comando segun el manual del modulo LCD para quitar cursor bajo
Gregorio 5:ad88703dc6d3 248 lcd.cls(); //borra la pantalla
Gregorio 5:ad88703dc6d3 249 lcd.printf("Valores \nGuardados");
Gregorio 5:ad88703dc6d3 250 wait(1);
Gregorio 5:ad88703dc6d3 251
Gregorio 5:ad88703dc6d3 252 avg=0;
Gregorio 5:ad88703dc6d3 253 for(i=0; i<10; i++) {
Gregorio 5:ad88703dc6d3 254 a[i]=LM.read();
Gregorio 5:ad88703dc6d3 255 wait(.001);
Gregorio 5:ad88703dc6d3 256 }
Gregorio 5:ad88703dc6d3 257 for(i=0; i<10; i++) {
Gregorio 5:ad88703dc6d3 258 avg=avg+(a[i]/10);
Gregorio 5:ad88703dc6d3 259 }
Gregorio 5:ad88703dc6d3 260
Gregorio 5:ad88703dc6d3 261 ta=(avg*3.10143686*100);
Gregorio 5:ad88703dc6d3 262
Gregorio 5:ad88703dc6d3 263 lcd.cls(); //borra la pantalla
Gregorio 5:ad88703dc6d3 264 lcd.printf("T Ambiente:%.2f",ta);
Gregorio 5:ad88703dc6d3 265 wait(2);
Gregorio 5:ad88703dc6d3 266
Gregorio 5:ad88703dc6d3 267 // se imprimen los parches del control *****************************************
Gregorio 5:ad88703dc6d3 268 lcd.cls();
Gregorio 5:ad88703dc6d3 269 lcd.printf("Er:%.2f",err);
Gregorio 5:ad88703dc6d3 270 lcd.locate(8,0);
Gregorio 5:ad88703dc6d3 271 lcd.printf("Me:%.2f",med);
Gregorio 5:ad88703dc6d3 272 lcd.locate(0,1);
Gregorio 5:ad88703dc6d3 273 lcd.printf("dt:%.2f",dt1);
Gregorio 5:ad88703dc6d3 274 lcd.locate(10,1);
Gregorio 5:ad88703dc6d3 275 lcd.printf("t:%.0f",0);
Gregorio 5:ad88703dc6d3 276 wait(1);
Gregorio 5:ad88703dc6d3 277
Gregorio 5:ad88703dc6d3 278 // CICLO PARA CONTROL DE RAMPA ASCENDENTE (T1)
Gregorio 5:ad88703dc6d3 279 b=0;
Gregorio 5:ad88703dc6d3 280 t.start();
Gregorio 5:ad88703dc6d3 281 // Comienza el ciclo for para la primera parte del control(Rampa ascendente)
Gregorio 5:ad88703dc6d3 282 for(dt1=ta; dt1<=temp; dt1+=(temp-ta)/t1) {
Gregorio 5:ad88703dc6d3 283 avg=0;
Gregorio 5:ad88703dc6d3 284 for(i=0; i<10; i++) {
Gregorio 5:ad88703dc6d3 285 a[i]=LM.read();
Gregorio 5:ad88703dc6d3 286 wait(.001);
lcorralesc1 3:9347b362d33c 287 }
Gregorio 5:ad88703dc6d3 288 for(i=0; i<10; i++) {
Gregorio 5:ad88703dc6d3 289 avg=avg+(a[i]/10);
Gregorio 5:ad88703dc6d3 290 }
Gregorio 5:ad88703dc6d3 291 med=(avg*3.10143686*100); //leer puerto analogo y asignar a med (*100 ya que LM35 da 10mV/ºC)
Gregorio 5:ad88703dc6d3 292 err = (dt1-med);
Gregorio 5:ad88703dc6d3 293 // Para activar la bombilla en el tiempo de ascenso
Gregorio 5:ad88703dc6d3 294 if(err>=0) {
Gregorio 5:ad88703dc6d3 295 vent=0;
Gregorio 5:ad88703dc6d3 296 ap = kp*err; //calculo de la acción proporcional
Gregorio 5:ad88703dc6d3 297 // se verifica que la accion integral no sea muy grande
Gregorio 5:ad88703dc6d3 298 if(ai<100) {
Gregorio 5:ad88703dc6d3 299 ai =(ki*err)+ai; //calculo de la integral del error
Gregorio 5:ad88703dc6d3 300 }
Gregorio 5:ad88703dc6d3 301 ad = kd*(err-err_v); //calculo de la accion derivativa
Gregorio 5:ad88703dc6d3 302 pid = (ap+ai+ad);
Gregorio 5:ad88703dc6d3 303 // se verifica que pid sea positivo **************************************
Gregorio 5:ad88703dc6d3 304 if(pid<=0) {
Gregorio 5:ad88703dc6d3 305 pid=0;
Gregorio 5:ad88703dc6d3 306 }
Gregorio 5:ad88703dc6d3 307 // se verifica que pid sea menor o igual la valor maximo *****************
Gregorio 5:ad88703dc6d3 308 if(pid>=100) {
Gregorio 5:ad88703dc6d3 309 pid=100;
Gregorio 5:ad88703dc6d3 310 }
Gregorio 5:ad88703dc6d3 311 err_v = err;
Gregorio 5:ad88703dc6d3 312 //Normalizacion de la salida
Gregorio 5:ad88703dc6d3 313 pidn=pid/100;
Gregorio 5:ad88703dc6d3 314 // se envia el valor pid a puerto analogico de salida (D/A) **************
Gregorio 5:ad88703dc6d3 315 bomb.write(pidn);
Gregorio 5:ad88703dc6d3 316 }
Gregorio 5:ad88703dc6d3 317 // Para activar ventilador en el tiempo de ascenso
Gregorio 5:ad88703dc6d3 318 if(err<0) {
Gregorio 5:ad88703dc6d3 319 bomb=0;
Gregorio 5:ad88703dc6d3 320 err=-1*err;
Gregorio 5:ad88703dc6d3 321 ap = kp*err;
Gregorio 5:ad88703dc6d3 322 if(ai<100) {
Gregorio 5:ad88703dc6d3 323 ai =(ki*err)+ai;
Gregorio 5:ad88703dc6d3 324 }
Gregorio 5:ad88703dc6d3 325 ad = kd*(err-err_v);
Gregorio 5:ad88703dc6d3 326 pid = (ap+ai+ad);
Gregorio 5:ad88703dc6d3 327 if(pid<=0) {
Gregorio 5:ad88703dc6d3 328 pid=0;
Gregorio 5:ad88703dc6d3 329 }
Gregorio 5:ad88703dc6d3 330 if(pid>=100) {
Gregorio 5:ad88703dc6d3 331 pid=100;
Gregorio 5:ad88703dc6d3 332 }
Gregorio 5:ad88703dc6d3 333 err_v = err;
Gregorio 5:ad88703dc6d3 334 pidn=pid/100;
Gregorio 5:ad88703dc6d3 335 vent.write(pidn);
Gregorio 5:ad88703dc6d3 336 }
Gregorio 5:ad88703dc6d3 337 // se repite el ciclo
Gregorio 5:ad88703dc6d3 338 lcd.cls();
Gregorio 5:ad88703dc6d3 339 lcd.locate(0,0);
Gregorio 5:ad88703dc6d3 340 lcd.printf("Er:%.2f",err);
Gregorio 5:ad88703dc6d3 341 lcd.locate(8,0);
Gregorio 5:ad88703dc6d3 342 lcd.printf("Me:%.2f",med);
Gregorio 5:ad88703dc6d3 343 lcd.locate(0,1);
Gregorio 5:ad88703dc6d3 344 lcd.printf("dt:%.2f",dt1);
Gregorio 5:ad88703dc6d3 345 lcd.locate(10,1);
Gregorio 5:ad88703dc6d3 346 lcd.printf("t1:%.0f",t.read());
Gregorio 5:ad88703dc6d3 347 wait(1);
Gregorio 5:ad88703dc6d3 348 }
Gregorio 5:ad88703dc6d3 349 bomb=0;
Gregorio 5:ad88703dc6d3 350 vent=0;
Gregorio 5:ad88703dc6d3 351 // Comienza el segundo ciclo para la segunda parte del control (Temperatura estable)
Gregorio 5:ad88703dc6d3 352 t.start();
Gregorio 5:ad88703dc6d3 353 while(t<=t2) {
Gregorio 5:ad88703dc6d3 354 avg=0;
Gregorio 5:ad88703dc6d3 355 for(i=0; i<10; i++) {
Gregorio 5:ad88703dc6d3 356 a[i]=LM.read();
Gregorio 5:ad88703dc6d3 357 wait(.001);
Gregorio 5:ad88703dc6d3 358 }
Gregorio 5:ad88703dc6d3 359 for(i=0; i<10; i++) {
Gregorio 5:ad88703dc6d3 360 avg=avg+(a[i]/10);
Gregorio 5:ad88703dc6d3 361 }
Gregorio 5:ad88703dc6d3 362
Gregorio 5:ad88703dc6d3 363 med=(avg*3.10143686*100); //leer puerto analogo y asignar a med (*100 ya que LM35 da 10mV/ºC)
Gregorio 5:ad88703dc6d3 364 err = (temp-med);
Gregorio 5:ad88703dc6d3 365 // Para activar la bombilla en el tiempo de ascenso
Gregorio 5:ad88703dc6d3 366 if(err>=0) {
Gregorio 5:ad88703dc6d3 367 vent=0;
Gregorio 5:ad88703dc6d3 368 ap = kp*err; //calculo de la acción proporcional
Gregorio 5:ad88703dc6d3 369 // se verifica que la accion integral no sea muy grande
Gregorio 5:ad88703dc6d3 370 if(ai<100) {
Gregorio 5:ad88703dc6d3 371 ai =(ki*err)+ai; //calculo de la integral del error
Gregorio 5:ad88703dc6d3 372 }
Gregorio 5:ad88703dc6d3 373 ad = kd*(err-err_v); //calculo de la accion derivativa
Gregorio 5:ad88703dc6d3 374 pid = (ap+ai+ad);
Gregorio 5:ad88703dc6d3 375 // se verifica que pid sea positivo **************************************
Gregorio 5:ad88703dc6d3 376 if(pid<=0) {
Gregorio 5:ad88703dc6d3 377 pid=0;
Gregorio 5:ad88703dc6d3 378 }
Gregorio 5:ad88703dc6d3 379 // se verifica que pid sea menor o igual la valor maximo *****************
Gregorio 5:ad88703dc6d3 380 if(pid>=100) {
Gregorio 5:ad88703dc6d3 381 pid=100;
Gregorio 5:ad88703dc6d3 382 }
Gregorio 5:ad88703dc6d3 383 err_v = err;
Gregorio 5:ad88703dc6d3 384 //Normalizacion de la salida
Gregorio 5:ad88703dc6d3 385 pidn=pid/100;
Gregorio 5:ad88703dc6d3 386 // se envia el valor pid a puerto analogico de salida (D/A) **************
Gregorio 5:ad88703dc6d3 387 bomb.write(pidn);
Gregorio 5:ad88703dc6d3 388 }
Gregorio 5:ad88703dc6d3 389 // Para activar ventilador en el tiempo de ascenso
Gregorio 5:ad88703dc6d3 390 if(err<0) {
Gregorio 5:ad88703dc6d3 391 bomb=0;
Gregorio 5:ad88703dc6d3 392 err=-1*err;
Gregorio 5:ad88703dc6d3 393 ap = kp*err;
Gregorio 5:ad88703dc6d3 394 if(ai<100) {
Gregorio 5:ad88703dc6d3 395 ai =(ki*err)+ai;
Gregorio 5:ad88703dc6d3 396 }
Gregorio 5:ad88703dc6d3 397 ad = kd*(err-err_v);
Gregorio 5:ad88703dc6d3 398 pid = (ap+ai+ad);
Gregorio 5:ad88703dc6d3 399 if(pid<=0) {
Gregorio 5:ad88703dc6d3 400 pid=0;
Gregorio 5:ad88703dc6d3 401 }
Gregorio 5:ad88703dc6d3 402 if(pid>=100) {
Gregorio 5:ad88703dc6d3 403 pid=100;
Gregorio 5:ad88703dc6d3 404 }
Gregorio 5:ad88703dc6d3 405 err_v = err;
Gregorio 5:ad88703dc6d3 406 //Normalizacion de la salida
Gregorio 5:ad88703dc6d3 407 pidn=pid/100;
Gregorio 5:ad88703dc6d3 408 // se envia el valor pid a puerto analogico de salida (D/A) **************
Gregorio 5:ad88703dc6d3 409 vent.write(pidn);
Gregorio 5:ad88703dc6d3 410 }
Gregorio 5:ad88703dc6d3 411 lcd.cls();
Gregorio 5:ad88703dc6d3 412 lcd.locate(0,0);
Gregorio 5:ad88703dc6d3 413 lcd.printf("Er:%.2f",err);
Gregorio 5:ad88703dc6d3 414 lcd.locate(8,0);
Gregorio 5:ad88703dc6d3 415 lcd.printf("Me:%.2f",med);
Gregorio 5:ad88703dc6d3 416 lcd.locate(0,1);
Gregorio 5:ad88703dc6d3 417 lcd.printf("Tm:%.2d",temp);
Gregorio 5:ad88703dc6d3 418 lcd.locate(10,1);
Gregorio 5:ad88703dc6d3 419 lcd.printf("t2:%.0f",t.read());
Gregorio 5:ad88703dc6d3 420 wait(1);
Gregorio 5:ad88703dc6d3 421 }
Gregorio 5:ad88703dc6d3 422 bomb=0;
Gregorio 5:ad88703dc6d3 423 vent=0;
Gregorio 5:ad88703dc6d3 424 // Comienza el tercer ciclo para la ultima parte del control (Descenso de rampa)
Gregorio 5:ad88703dc6d3 425 t.start();
Gregorio 5:ad88703dc6d3 426 for(dt3=temp; dt3>=ta; dt3-=((temp-ta)/t3)) {
Gregorio 5:ad88703dc6d3 427 avg=0;
Gregorio 5:ad88703dc6d3 428 for(i=0; i<10; i++) {
Gregorio 5:ad88703dc6d3 429 a[i]=LM.read();
Gregorio 5:ad88703dc6d3 430 wait(.001);
Gregorio 5:ad88703dc6d3 431 }
Gregorio 5:ad88703dc6d3 432 for(i=0; i<10; i++) {
Gregorio 5:ad88703dc6d3 433 avg=avg+(a[i]/10);
Gregorio 5:ad88703dc6d3 434 }
Gregorio 5:ad88703dc6d3 435
Gregorio 5:ad88703dc6d3 436 med=(avg*3.10143686*100);//leer puerto analogo y asignar a med (*100 ya que LM35 da 10mV/ºC)
Gregorio 5:ad88703dc6d3 437 err = (med-dt3);
Gregorio 5:ad88703dc6d3 438 if(err>=0) {
Gregorio 5:ad88703dc6d3 439 bomb=0;
Gregorio 5:ad88703dc6d3 440 ap = kp*err; //calculo de la acción proporcional
Gregorio 5:ad88703dc6d3 441 // se verifica que la accion integral no sea muy grande
Gregorio 5:ad88703dc6d3 442 if(ai<100) {
Gregorio 5:ad88703dc6d3 443 ai =(ki*err)+ai; //calculo de la integral del error
Gregorio 5:ad88703dc6d3 444 }
Gregorio 5:ad88703dc6d3 445 ad = kd*(err-err_v); //calculo de la accion derivativa
Gregorio 5:ad88703dc6d3 446 pid = (ap+ai+ad);
Gregorio 5:ad88703dc6d3 447 // se verifica que pid sea positivo **************************************
Gregorio 5:ad88703dc6d3 448 if(pid<=0) {
Gregorio 5:ad88703dc6d3 449 pid=0;
Gregorio 5:ad88703dc6d3 450 }
Gregorio 5:ad88703dc6d3 451 // se verifica que pid sea menor o igual la valor maximo *****************
Gregorio 5:ad88703dc6d3 452 if(pid>=100) {
Gregorio 5:ad88703dc6d3 453 pid=100;
Gregorio 5:ad88703dc6d3 454 }
Gregorio 5:ad88703dc6d3 455 // se actualizan las variables *******************************************
Gregorio 5:ad88703dc6d3 456 err_v = err;
Gregorio 5:ad88703dc6d3 457 lcd.cls();
Gregorio 5:ad88703dc6d3 458 lcd.locate(0,0);
Gregorio 5:ad88703dc6d3 459 lcd.printf("Er:%.2f",err);
Gregorio 5:ad88703dc6d3 460 lcd.locate(8,0);
Gregorio 5:ad88703dc6d3 461 lcd.printf("Me:%.2f",med);
Gregorio 5:ad88703dc6d3 462 lcd.locate(0,1);
Gregorio 5:ad88703dc6d3 463 lcd.printf("dt:%.2f",dt3);
Gregorio 5:ad88703dc6d3 464 lcd.locate(10,1);
Gregorio 5:ad88703dc6d3 465 lcd.printf("t3:%.0f",t.read());
Gregorio 5:ad88703dc6d3 466
Gregorio 5:ad88703dc6d3 467 //Normalizacion de la salida
Gregorio 5:ad88703dc6d3 468 pidn=pid/100;
Gregorio 5:ad88703dc6d3 469 // se envia el valor pid a puerto analogico de salida (D/A) **************
Gregorio 5:ad88703dc6d3 470 vent.write(pidn);
Gregorio 5:ad88703dc6d3 471 // se repite el ciclo
Gregorio 5:ad88703dc6d3 472 wait(1);
Gregorio 5:ad88703dc6d3 473 }
Gregorio 5:ad88703dc6d3 474 if(err<0) {
Gregorio 5:ad88703dc6d3 475 err=-1*err;
Gregorio 5:ad88703dc6d3 476 vent=0;
Gregorio 5:ad88703dc6d3 477 ap = kp*err; //calculo de la acción proporcional
Gregorio 5:ad88703dc6d3 478 // se verifica que la accion integral no sea muy grande
Gregorio 5:ad88703dc6d3 479 if(ai<100) {
Gregorio 5:ad88703dc6d3 480 ai =(ki*err)+ai; //calculo de la integral del error
Gregorio 5:ad88703dc6d3 481 }
Gregorio 5:ad88703dc6d3 482 ad = kd*(err-err_v); //calculo de la accion derivativa
Gregorio 5:ad88703dc6d3 483 pid = (ap+ai+ad);
Gregorio 5:ad88703dc6d3 484 // se verifica que pid sea positivo **************************************
Gregorio 5:ad88703dc6d3 485 if(pid<=0) {
Gregorio 5:ad88703dc6d3 486 pid=0;
Gregorio 5:ad88703dc6d3 487 }
Gregorio 5:ad88703dc6d3 488 // se verifica que pid sea menor o igual la valor maximo *****************
Gregorio 5:ad88703dc6d3 489 if(pid>=100) {
Gregorio 5:ad88703dc6d3 490 pid=100;
Gregorio 5:ad88703dc6d3 491 }
Gregorio 5:ad88703dc6d3 492 // se actualizan las variables *******************************************
Gregorio 5:ad88703dc6d3 493 err_v = err;
Gregorio 5:ad88703dc6d3 494 lcd.cls();
Gregorio 5:ad88703dc6d3 495 lcd.locate(0,0);
Gregorio 5:ad88703dc6d3 496 lcd.printf("Er:%.2f",err);
Gregorio 5:ad88703dc6d3 497 lcd.locate(8,0);
Gregorio 5:ad88703dc6d3 498 lcd.printf("Me:%.2f",med);
Gregorio 5:ad88703dc6d3 499 lcd.locate(0,1);
Gregorio 5:ad88703dc6d3 500 lcd.printf("dt:%.2f",dt3);
Gregorio 5:ad88703dc6d3 501 lcd.locate(10,1);
Gregorio 5:ad88703dc6d3 502 lcd.printf("t3:%.0f",t.read());
Gregorio 5:ad88703dc6d3 503
Gregorio 5:ad88703dc6d3 504 //Normalizacion de la salida
Gregorio 5:ad88703dc6d3 505 pidn=pid/100;
Gregorio 5:ad88703dc6d3 506 // se envia el valor pid a puerto analogico de salida (D/A) **************
Gregorio 5:ad88703dc6d3 507 bomb.write(pidn);
Gregorio 5:ad88703dc6d3 508 // se repite el ciclo
Gregorio 5:ad88703dc6d3 509 wait(1);
Gregorio 5:ad88703dc6d3 510 }
Gregorio 5:ad88703dc6d3 511
Gregorio 5:ad88703dc6d3 512 }
Gregorio 5:ad88703dc6d3 513 bomb=0;
Gregorio 5:ad88703dc6d3 514 vent=0;
Gregorio 5:ad88703dc6d3 515 lcd.cls();
Gregorio 5:ad88703dc6d3 516 lcd.printf("Control\nTreminado");
Gregorio 5:ad88703dc6d3 517 }