Control PID para horno de reflujo con seguimiento de consigna
Dependencies: Debounced Pulse1 QEI RTC-DS1307 TextLCD mbed
Fork of Tarea3_procesadores_Ds1307 by
Tarea 4 procesadores 2018-1
Juan Camilo Londoño Julieta Serrano Escalante
PID para horno de reflujo conseguimiento de consigna
Revision 3:35a40be1047f, committed 2018-06-01
- Comitter:
- jclondonol
- Date:
- Fri Jun 01 21:58:03 2018 +0000
- Parent:
- 2:bef1b1c9e387
- Commit message:
- Tarea 4 Control PID para horno de reflujo con seguimiento de consigna
Changed in this revision
main.cpp | Show annotated file Show diff for this revision Revisions of this file |
--- a/main.cpp Wed May 09 19:55:50 2018 +0000 +++ b/main.cpp Fri Jun 01 21:58:03 2018 +0000 @@ -5,69 +5,50 @@ #include "Rtc_Ds1307.h" #include <Pulse1.h> -TextLCD lcd(PTB0, PTB1, PTB2, PTB3, PTC2, PTC1); // rs, e, d4, d5, d6, d7 +TextLCD lcd(PTE20, PTB1, PTB2, PTB3, PTC2, PTE21); // rs, e, d4, d5, d6, d7 Rtc_Ds1307 rtc(PTE0, PTE1); QEI wheel (PTD7, PTD6, NC, 30); DebouncedIn button_enco(PTC5); -PwmOut Sonido(PTD1); -PulseInOut irda(PTD5);// en este puerto se pone el sensor infrarrojo - - -float periodo; -float Frecuencia = 4000; -int C1 = 0x0C; -int m = 0, flag = 0; -uint8_t pot[7] = {1, 2, 4, 8, 16, 32, 64}; -uint8_t pot1[7] = {254, 253, 251, 248, 239, 223, 191}; -int Lugar = 0; // Definen el punto en el cual va el programa -int i = 0, j = 0; -int pos = 0; // Reloj:0, Alarma1:1, Alarma2:2, ... , Alarma7:7 -uint8_t state_alarms = 0, pos_alarm = 0, alarma = 0; - -//irda -int header = 0; //tiempo de cabecera pulso abajo -const int head_H = 4532; //+20% medida con osciloscopio en microsegundos -const int head_L = 4494;//-20% medida con osciloscopio -int g = 0, h = 0, count = 0; -const int T_alto = 1600;//ponga su tiempo de la prueba -const int T_bajo = 485;//ponga su tiempo de la prueba -const int num_bits = 32;//ponga su numero de bits -int num[num_bits];//cadena para almacenar todos los tiempos que conforman los bits de datos -int sec[num_bits];//cadena para almacenar la cadena codificada en binario -int dato; // tiempo de cada dato que se lee -int boton_sel = 10; -int boton[10][32]= {{1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,1,1,0,1,1,0}, //0 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,0,0,0,0,0,1,1,0,1,1,1,1,0}, //1 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,1,1,1,0}, //2 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,0,0,0,0,0,1,0,0,1,1,1,1,0}, //3 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,0,1,1,1,0,1,1,1,0}, //4 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,0,1,0,0,0,0,0,1,1,0,1,1,1,0}, //5 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,0,1,0,0,0,0,1,0,1,0,1,1,1,0}, //6 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1,1,1,0}, //7 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,1,0,1,1,0,0,0,0,0,1,0,0,1,1,1,0}, //8 - {1,1,1,0,0,0,0,0,1,1,1,0,0,0,0,0,0,1,1,1,0,0,0,0,1,0,0,0,1,1,1,0}}; //9 +PwmOut U_pwm(PTE29); +AnalogOut U_analog(PTE30); +AnalogIn Y(A0); +DigitalOut pwm_analog(PTC6); int main() { + int C1 = 0x0C; + int m = 0; + int Lugar = 0; // Definen el punto en el cual va el programa + int i = 0; + int pos = 0; + int Kp = 1, Ki = 1, Kd = 1, Sp = 0; + float sp_temp = 0; + float T1 = 0.1, T2 = 0.1, T3 = 0.1; + int flag_pwm = 0; + float periodo; + float Frecuencia = 2000; + float pid = 0,ai = 0,ad = 0,ap = 0,med = 0,err = 0; + float err_v; + int tiempo = 0, sec = 0, sec_ant = 0; + Rtc_Ds1307::Time_rtc tm = {}; - Rtc_Ds1307::Time_rtc Alarm[7] = {}; lcd.cls(); lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD lcd.locate(0,0); + rtc.getTime(tm); periodo=(1/Frecuencia); - Sonido.period(periodo); - rtc.getTime(tm); //lee el tiempo del DS1307 - Sonido.write(255); - + U_pwm.period(periodo); + U_pwm.pulsewidth(0); + U_analog = 0.0; + pwm_analog = 0; + while(1) { switch (Lugar) { - case 0: - - rtc.getTime(tm); + case 0: // Seleccionar Configuracion m = wheel.getPulses(); if(m != 0) { @@ -76,478 +57,433 @@ m = 0; lcd.cls(); } - if(pos > 7) - { - pos = -1; - } - if(pos < -1) - { - pos = 7; - } - if(pos == 0) - { - lcd.locate(0,0); - lcd.printf("Time: "); - lcd.locate(8,0); - lcd.printf("%02d:",tm.hour); - lcd.printf("%02d:",tm.min); - lcd.printf("%02d",tm.sec); - lcd.locate(0,1); - lcd.printf("%02d/",tm.mon); - lcd.printf("%02d/",tm.date); - lcd.printf("%02d",tm.year); - wait(0.1); - } + if(pos > 3){pos = 0;} + if(pos < 0){pos = 3;} - if(pos == -1) - { - lcd.locate(0,0); - lcd.printf("Alarm Setup IRDA"); - wait(0.1); - } - - - if(pos > 0) + switch(pos) { - lcd.locate(0,0); - lcd.printf("Alarm %d", pos); - lcd.locate(8,0); - lcd.printf("%02d:",Alarm[pos - 1].hour); - lcd.printf("%02d:",Alarm[pos - 1].min); - lcd.printf("%02d",Alarm[pos - 1].sec); - lcd.locate(0,1); - lcd.printf("%02d/",Alarm[pos - 1].mon); - lcd.printf("%02d/",Alarm[pos - 1].date); - lcd.printf("%02d",Alarm[pos - 1].year); - lcd.locate(13,1); - if((state_alarms&(pot[pos - 1])) == pot[pos - 1]) - { - lcd.printf("On "); - } - else - { - lcd.printf("Off"); - } - - wait(0.1); - } - for(j=0;j<7;j++) - { - if( (tm.date==Alarm[j].date)&&(tm.mon==Alarm[j].mon)&&(tm.year==Alarm[j].year)&&(tm.hour==Alarm[j].hour)&&(tm.min==Alarm[j].min)&&(tm.sec==Alarm[j].sec)&&((state_alarms&(pot[j])) == pot[j])) - { - Lugar = 2; - lcd.cls(); + case 0: + lcd.locate(0,0); + lcd.printf("Kp: %03d", Kp); + lcd.locate(8,0); + lcd.printf("Ki: %03d", Ki); + lcd.locate(0,1); + lcd.printf("Kd: %03d", Kd); + lcd.locate(8,1); + lcd.printf("Sp: %03d", Sp); + wait(0.1); + break; + case 1: lcd.locate(0,0); - lcd.printf("Active Alarm%d!!!",(j+1)); + lcd.printf("T1: %0.1f", T1); + lcd.locate(8,0); + lcd.printf("T2: %0.1f", T2); + lcd.locate(0,1); + lcd.printf("T3: %0.1f", T3); + lcd.locate(8,1); + lcd.printf("(min)"); + wait(0.1); + break; + case 2: + lcd.locate(0,0); + lcd.printf("Setup Out"); lcd.locate(0,1); - lcd.printf("->Disable "); - lcd.locate(10,1); - lcd.printf("--5min"); - pos_alarm = j; - } + if(flag_pwm == 0) + { + lcd.printf("-> Pwm -- Analog"); + } + else + { + lcd.printf("-- Pwm -> Analog"); + } + break; + case 3: + lcd.locate(0,0); + lcd.printf("Start PID"); + break; } if (button_enco.falling()) //si se pulsa boton encoder { - if(pos == -1) - {Lugar = 3; - lcd.cls();} - else - {Lugar = 1;} - + if(pos == 0) + { + Lugar = 1; + i = 0; + lcd.cls(); + lcd.locate(0,0); + lcd.printf("Kp: "); + } + if(pos == 1) + { + Lugar = 2; + i = 0; + lcd.cls(); + lcd.locate(0,0); + lcd.printf("T1: "); + } + if(pos == 2) + { + Lugar = 3; + } + if(pos == 3) + { + Lugar = 4; + lcd.cls(); + tm.min = 0; + tm.sec = 0; + tm.hour = 1; + tm.mon = 1; + tm.date = 1; + tm.year = 2018; + rtc.setTime(tm, false, false); + + rtc.startClock(); + lcd.locate(0,1); + lcd.printf("Time: "); + } } break; - case 1: + case 1: // Configurar Constantes switch(i) - { - case 0: - if(pos == 0) - { - lcd.cls(); - lcd.locate(0,0); - lcd.printf("Time Setup"); - } - - if(pos > 0) - { - lcd.cls(); - lcd.locate(0,0); - lcd.printf("Alarm %d Setup", pos); - } - wait(1); - i++; - lcd.cls(); - lcd.locate(0,0); - lcd.printf("Day: "); - break; - - case 1: + { + case 0: // Establecer Kp m = wheel.getPulses(); if (m != 0) { - tm.date = tm.date + m; - if(tm.date > 31) + Kp = Kp + m; + if(Kp > 99) { - tm.date = 1; + Kp = 0; } - if(tm.date < 1) + if(Kp < 0) { - tm.date = 31; + Kp = 99; } wheel.reset(); m = 0; } - lcd.locate(5,0); - lcd.printf("%02d",tm.date); + lcd.locate(4,0); + lcd.printf("%03d",Kp); if (button_enco.falling()) { i++; lcd.cls(); lcd.locate(0,0); - lcd.printf("Month: "); + lcd.printf("Ki: "); } break; - case 2: + case 1: // Establecer Ki m = wheel.getPulses(); if (m != 0) { - tm.mon = tm.mon + m; - if(tm.mon > 12) + Ki = Ki + m; + if(Ki > 99) { - tm.mon = 1; + Ki = 0; } - if(tm.mon < 1) + if(Ki < 0) { - tm.mon = 12; + Ki = 99; } wheel.reset(); m = 0; } - lcd.locate(7,0); - lcd.printf("%02d",tm.mon); + lcd.locate(4,0); + lcd.printf("%03d",Ki); if (button_enco.falling()) { i++; lcd.cls(); lcd.locate(0,0); - lcd.printf("Year: "); + lcd.printf("Kd: "); } break; - case 3: + case 2: // Establecer Kd m = wheel.getPulses(); if (m != 0) { - tm.year = tm.year + m; - if(tm.year < 2000) + Kd = Kd + m; + if(Kd > 99) { - tm.year = 2000; + Kd = 0; + } + if(Kd < 0) + { + Kd = 99; } wheel.reset(); m = 0; } - lcd.locate(6,0); - lcd.printf("%02d",tm.year); - - if (button_enco.falling()) - { - i++; - lcd.cls(); - lcd.locate(0,0); - lcd.printf("Hours: "); - } - break; - - case 4: - m = wheel.getPulses(); - if (m != 0) - { - tm.hour = tm.hour + m; - if(tm.hour > 23) - { - tm.hour = 0; - } - if(tm.hour < 0) - { - tm.hour = 23; - } - wheel.reset(); - m = 0; - } - lcd.locate(7,0); - lcd.printf("%02d",tm.hour); + lcd.locate(4,0); + lcd.printf("%03d",Kd); if (button_enco.falling()) { i++; lcd.cls(); lcd.locate(0,0); - lcd.printf("Minutes: "); + lcd.printf("Sp: "); } - break; - case 5: + case 3: // Establecer Sp m = wheel.getPulses(); if (m != 0) { - tm.min = tm.min + m; - if(tm.min > 59) + Sp = Sp + m*1; + if(Sp > 100) { - tm.min = 0; + Sp = 0; } - if(tm.min < 0) + if(Sp < 0) { - tm.min = 59; + Sp = 100; } - wheel.reset(); m = 0; } - lcd.locate(9,0); - lcd.printf("%02d",tm.min); + lcd.locate(4,0); + lcd.printf("%03d",Sp); + + if (button_enco.falling()) + { + lcd.cls(); + lcd.locate(0, 0); + lcd.printf("Parameters Set"); + wait(1); + i = 0; + Lugar = 0; + lcd.cls(); + } + + break; + } + break; + + + case 2: // Configurar Tiempos + switch(i) + { + case 0: // Establecer T1 + m = wheel.getPulses(); + if (m != 0) + { + T1 = T1 + m*0.1; + if(T1 > 5.0) + { + T1 = 0.1; + } + if(T1 < 0.1) + { + T1 = 5.0; + } + wheel.reset(); + m = 0; + } + lcd.locate(4,0); + lcd.printf("%0.1f (min)",T1); if (button_enco.falling()) { i++; lcd.cls(); lcd.locate(0,0); - lcd.printf("Seconds: "); + lcd.printf("T2: "); + T2 = T1 + 0.1; } break; - - case 6: + case 1: // Establecer T2 m = wheel.getPulses(); if (m != 0) { - tm.sec = tm.sec + m; - if(tm.sec > 59) + T2 = T2 + m*0.1; + if(T2 > 5.0) { - tm.sec = 0; + T2 = T1 + 0.1; } - if(tm.sec < 0) + if(T2 < (T1 + 0.1)) { - tm.sec = 59; + T2 = 5.0; } wheel.reset(); m = 0; } - lcd.locate(9,0); - lcd.printf("%02d",tm.sec); + lcd.locate(4,0); + lcd.printf("%0.1f (min)",T2); if (button_enco.falling()) { - if(pos==0) + i++; + lcd.cls(); + lcd.locate(0,0); + lcd.printf("T3: "); + T3 = T2 + 0.1; + } + break; + + case 2: // Establecer T3 + m = wheel.getPulses(); + if (m != 0) + { + T3 = T3 + m*0.1; + if(T3 > 5.0) { - rtc.setTime(tm, false, false); - rtc.startClock(); + T3 = T2 + 0.1; + } + if(T3 < (T2 + 0.1)) + { + T3 = 5.0; + } + wheel.reset(); + m = 0; + } + lcd.locate(4,0); + lcd.printf("%0.1f (min)",T3); + + if (button_enco.falling()) + { lcd.cls(); lcd.locate(0, 0); lcd.printf("Time Set"); wait(1); i = 0; Lugar = 0; - lcd.cls(); - } - if(pos > 0) - { - i++; - lcd.cls(); - lcd.locate(0,0); - lcd.printf("Enable: Off"); - } - } - break; - - case 7: - m = wheel.getPulses(); - if (m != 0) - { - if(flag == 0) - { - lcd.locate(8,0); - lcd.printf("On "); - flag = 1; //se activa la alarma - } - else - if(flag == 1) - { - lcd.locate(8,0); - lcd.printf("Off"); - flag = 0; //se desactiva la alarma - } - wheel.reset(); - m = 0; + lcd.cls(); } - if (button_enco.falling()) - { - if(flag == 1) - { - state_alarms = state_alarms | pot[(pos - 1)]; - } - if(flag == 0) - { - state_alarms = state_alarms & pot1[(pos - 1)]; - } - Alarm[pos - 1] = tm; - lcd.cls(); - lcd.locate(0,0); - lcd.printf("Alarm %d Set", pos); - wait(1); - i = 0; - Lugar = 0; - flag = 0; - lcd.cls(); - } break; } break; - case 2: - Sonido.write(0.5); - wait(0.2); - Sonido.write(255); - wait(0.2); - Sonido.write(0.5); - wait(0.2); - Sonido.write(255); - wait(0.2); - + case 3: // Configurar salida + m = wheel.getPulses(); - - if(alarma == 0) //pos_alarm + if(flag_pwm == 0) { if(m != 0) { - alarma = 1; + flag_pwm = 1; wheel.reset(); m = 0; lcd.locate(1,1); lcd.printf("-"); - lcd.locate(11,1); + lcd.locate(8,1); lcd.printf(">"); } } - if(alarma == 1) + if(flag_pwm == 1) { if(m != 0) { - alarma = 0; + flag_pwm = 0; wheel.reset(); m = 0; lcd.locate(1,1); lcd.printf(">"); - lcd.locate(11,1); + lcd.locate(8,1); lcd.printf("-"); } } if (button_enco.falling()) { - if(alarma == 0) - { - wheel.reset(); - m=0; - Sonido.write(255); - lcd.cls(); - wait(0.5); - - } - if(alarma==1) - { - rtc.getTime(tm); - if(tm.min >= 55) - { - Alarm[pos_alarm].min = (tm.min + 5) - 60; - Alarm[pos_alarm].hour = tm.hour + 1; - } - else - { - Alarm[pos_alarm].min = tm.min + 5; - } - lcd.cls(); - alarma=0; - - } + lcd.cls(); + lcd.locate(0, 0); + lcd.printf("Out Set"); + if(flag_pwm == 1){pwm_analog = 1;} + else{pwm_analog = 0;} + + wait(1); Lugar = 0; + lcd.cls(); } + break; - case 3: - lcd.locate(0,0); - lcd.printf("Waiting IRDA"); - header = 0; - header = irda.read_low_us(); //funcion para leer un pulso de caida o bajo - if (header > head_L && header < head_H)//verificar que este en la tolerancia +-20% + + case 4: // CICLO PRINCIPAL CONTROLADOR PID +lop1: rtc.getTime(tm); + lcd.locate(0,0); + lcd.printf("%Y : %0.0f ", med); + lcd.locate(6,1); + lcd.printf("%02d:",tm.min); + lcd.printf("%02d",tm.sec); + + tiempo = tm.sec + tm.min*60; + sec = tm.sec; + + if(sec != sec_ant) { - //leo los datos de la trama y se meten a un arreglo - wait_us(2000); - for(g = 0; g<(num_bits-1); g++) // POR OSCILOSCOPIO se determina que llegan (num_bits),datos + sec_ant = sec; + if(tiempo <= (T1*60)) { - dato = irda.read_high_us(); //leer un bit de datos que es pulso arriba en este control - num[g]=dato; - wait_us(332); + sp_temp = sp_temp + Sp/(T1*60); } - for(g = 0; g<num_bits; g++) // guardo la secuancia en binario - { - if(num[g] > ((T_alto+T_bajo)/2)){sec[g]=1;} - else {sec[g]=0;} - } - for(h = 0; h < 8; h++) + + if( (tiempo > (T2*60)) && (tiempo < (T3*60)) ) { - for(g = 0; g < 32; g++) - { - if(sec[g]==boton[h][g]) //en caso de que un bit no coincida se descarta el boton 1 - { - count++; - if(count==32) - { - boton_sel = h - 1; - lcd.cls(); - lcd.locate(0,0); - lcd.printf("Alarm %d: ",(boton_sel+1)); - if(boton_sel >= 0) - { - if((state_alarms&(pot[boton_sel])) == pot[boton_sel]) - { - state_alarms = state_alarms & pot1[boton_sel]; - lcd.locate(10,0); - lcd.printf("Off"); - wait(1.5); - lcd.cls(); - } - else - { - state_alarms = state_alarms | pot[boton_sel]; - lcd.locate(10,0); - lcd.printf("On "); - wait(1.5); - lcd.cls(); - } - } - else - { - Lugar = 0; - pos = 0; - lcd.cls(); - } - } - } - } - count = 0; + sp_temp = sp_temp + ((10)-Sp)/((T3*60)-(T2*60)); } + //if(tiempo > (T3*60)) + //{ + //sp_temp = 0; + //} + } + med = Y.read()*100.0; + err = (sp_temp-med); //se calcula el error + ap = Kp*10*err*0.01f; //se calcula la accion proporcinal + ai =(Ki*10*err*0.01f)+ai; //calculo de la integral del error + ad = Kd*10*(err-err_v)*0.01f; //calculo de la accion derivativa + pid = (ap+ai+ad); + // se verifica que pid sea positivo ************************************** + if(pid<0) + { + pid = 0; } - + + // se verifica que pid sea menor o igual la valor maximo ***************** + if (pid > 100) + { + pid = 100; + } + + //Normalizacion de la salida + // se actualizan las variables ******************************************* + err_v = err; + U_analog = pid/100; + U_pwm.pulsewidth(U_analog*periodo); + // se envia el valor pid a puerto analogico de salida (D/A) ************** + // se repite el ciclo + if (button_enco.falling()) + { + lcd.cls(); + lcd.locate(0, 0); + lcd.printf("PID Stop"); + wait(1); + Lugar = 0; + lcd.cls(); + U_analog = 0.0; + U_pwm.pulsewidth(0); + sec = 0; + sec_ant = 0; + } + else + { + wait_ms(300); + goto lop1; + } + + + break; - break; } } -} +} \ No newline at end of file