PID programable con control remoto

Dependencies:   BufferedSerial Pulse1 TextLCD mbed

Committer:
andJdmat
Date:
Wed Nov 30 02:10:05 2016 +0000
Revision:
0:81638ee0ad32
PID programable con control remoto

Who changed what in which revision?

UserRevisionLine numberNew contents of line
andJdmat 0:81638ee0ad32 1 #include "mbed.h"
andJdmat 0:81638ee0ad32 2 #include <Pulse1.h>
andJdmat 0:81638ee0ad32 3 #include <string.h>
andJdmat 0:81638ee0ad32 4 #include "TextLCD.h"
andJdmat 0:81638ee0ad32 5 #include "iostream"
andJdmat 0:81638ee0ad32 6 #include "stdio.h"
andJdmat 0:81638ee0ad32 7 #include "string"
andJdmat 0:81638ee0ad32 8 #include "stdlib.h"
andJdmat 0:81638ee0ad32 9 #include <BufferedSerial.h>
andJdmat 0:81638ee0ad32 10
andJdmat 0:81638ee0ad32 11 TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5, TextLCD::LCD20x4); // rs, e, d4-d7 Teclado
andJdmat 0:81638ee0ad32 12 //asignamos el puerto a cada interruptor
andJdmat 0:81638ee0ad32 13 AnalogIn y(PTB3);//entrada analoga
andJdmat 0:81638ee0ad32 14 AnalogOut u(PTE30);//salida analoga OJO solo se le pueden drenar 1.5mA en circuitos use un Buffer
andJdmat 0:81638ee0ad32 15 //si se ignora esto se arruina la FRDMKL25Z
andJdmat 0:81638ee0ad32 16 DigitalOut led1(LED1);
andJdmat 0:81638ee0ad32 17 DigitalOut led2(LED2);
andJdmat 0:81638ee0ad32 18 DigitalOut led3(LED3);
andJdmat 0:81638ee0ad32 19
andJdmat 0:81638ee0ad32 20 DigitalIn button3(PTC16);//cambia ingreso de los 4 parametros
andJdmat 0:81638ee0ad32 21 DigitalIn button4(PTC17);//termina y consolida valores de 4 parametros y sale del loop
andJdmat 0:81638ee0ad32 22
andJdmat 0:81638ee0ad32 23
andJdmat 0:81638ee0ad32 24 //device.baud(115200);
andJdmat 0:81638ee0ad32 25
andJdmat 0:81638ee0ad32 26
andJdmat 0:81638ee0ad32 27 //codigos movimiento del curzor
andJdmat 0:81638ee0ad32 28
andJdmat 0:81638ee0ad32 29 //int C1=0x0E; // solo muestra el curzor
andJdmat 0:81638ee0ad32 30 int C2=0x18; // desplaza izquierda
andJdmat 0:81638ee0ad32 31 int C3=0x1A; // desplaza derecha
andJdmat 0:81638ee0ad32 32 int C4=0x0C; // quito cursor bajo
andJdmat 0:81638ee0ad32 33 int C1=0x0F;
andJdmat 0:81638ee0ad32 34
andJdmat 0:81638ee0ad32 35 int cambio=0, diferencia=0;
andJdmat 0:81638ee0ad32 36
andJdmat 0:81638ee0ad32 37 // se cambio de float a entero
andJdmat 0:81638ee0ad32 38 float pid,o,ai,ad,ap,med,err;
andJdmat 0:81638ee0ad32 39 float err_v;
andJdmat 0:81638ee0ad32 40
andJdmat 0:81638ee0ad32 41 //
andJdmat 0:81638ee0ad32 42
andJdmat 0:81638ee0ad32 43 // fin del cambio
andJdmat 0:81638ee0ad32 44 int spnum=0,kinum=0,kpnum=0,kdnum=0,pos=1;
andJdmat 0:81638ee0ad32 45 char buffer[128];
andJdmat 0:81638ee0ad32 46 char buffer2[128];
andJdmat 0:81638ee0ad32 47 char salidas[32];
andJdmat 0:81638ee0ad32 48 char err_s[3];
andJdmat 0:81638ee0ad32 49 char spnum_s[3];
andJdmat 0:81638ee0ad32 50 char med_s[3];
andJdmat 0:81638ee0ad32 51 char co_s[3];
andJdmat 0:81638ee0ad32 52 Timer t;
andJdmat 0:81638ee0ad32 53 int l;
andJdmat 0:81638ee0ad32 54 //control remoto videobeam aula
andJdmat 0:81638ee0ad32 55 PulseInOut irda(PTD5);// en este puerto se pone el sensor infrarrojo
andJdmat 0:81638ee0ad32 56 Serial pc(USBTX, USBRX);
andJdmat 0:81638ee0ad32 57 //PwmOut pwmLed(LED1);
andJdmat 0:81638ee0ad32 58
andJdmat 0:81638ee0ad32 59 int header =0;
andJdmat 0:81638ee0ad32 60 const int head_H = 2880; //+20% medida con osciloscopio en microsegundos
andJdmat 0:81638ee0ad32 61 const int head_L = 1920;//-20% medida con osciloscopio
andJdmat 0:81638ee0ad32 62 int i=0,k=0;
andJdmat 0:81638ee0ad32 63 const int T_alto=567;//ponga su tiempo de la prueba
andJdmat 0:81638ee0ad32 64 const int T_bajo=1170;//ponga su tiempo de la prueba
andJdmat 0:81638ee0ad32 65 const int num_bits = 21;//ponga su numero de bits
andJdmat 0:81638ee0ad32 66 int num[num_bits];//cadena para almacenar todos los tiempos que conforman los bits de datos
andJdmat 0:81638ee0ad32 67 int aux[21];
andJdmat 0:81638ee0ad32 68 int vec[4] = {0,0,0,0};
andJdmat 0:81638ee0ad32 69 int dato;
andJdmat 0:81638ee0ad32 70
andJdmat 0:81638ee0ad32 71 int SubirCanal[] = {0,0,0,0,1,0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1}; //Boton para subir el parámetro en la pantalla
andJdmat 0:81638ee0ad32 72 int BajarCanal[] = {1,0,0,0,1,0,0,1,0,0,0,0,1,1,0,0,0,1,0,0,1}; //Boton para bajar el parámetro en la pantalla
andJdmat 0:81638ee0ad32 73 int SubirVolumen[] = {0,1,0,0,1,0,0,1,0,0,0,0,1,0,1,0,0,1,0,0,1};//Boton para saltar de parámetro a parámetro
andJdmat 0:81638ee0ad32 74 int BajarVolumen[] = {1,1,0,0,1,0,0,1,0,0,0,0,1,1,1,0,0,1,0,0,1};//Boton para iniciar el PID
andJdmat 0:81638ee0ad32 75
andJdmat 0:81638ee0ad32 76 int main(){
andJdmat 0:81638ee0ad32 77 //pwmLed=0;
andJdmat 0:81638ee0ad32 78
andJdmat 0:81638ee0ad32 79
andJdmat 0:81638ee0ad32 80 // inicio
andJdmat 0:81638ee0ad32 81 lcd.locate(0,1);
andJdmat 0:81638ee0ad32 82 lcd.printf("**Control PID**");
andJdmat 0:81638ee0ad32 83 wait(2);
andJdmat 0:81638ee0ad32 84 lcd.cls(); // Borrar Pantalla
andJdmat 0:81638ee0ad32 85
andJdmat 0:81638ee0ad32 86 // lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD
andJdmat 0:81638ee0ad32 87
andJdmat 0:81638ee0ad32 88 lcd.locate(8,0);
andJdmat 0:81638ee0ad32 89 lcd.printf("Kp=%d",kpnum);
andJdmat 0:81638ee0ad32 90 lcd.locate(0,1);
andJdmat 0:81638ee0ad32 91 lcd.printf("Ki=%d",kinum);
andJdmat 0:81638ee0ad32 92 lcd.locate(8,1);
andJdmat 0:81638ee0ad32 93 lcd.printf("Kd=%d",kdnum);
andJdmat 0:81638ee0ad32 94 lcd.locate(0,0);
andJdmat 0:81638ee0ad32 95 lcd.printf("Sp=%d",spnum);
andJdmat 0:81638ee0ad32 96
andJdmat 0:81638ee0ad32 97 while(1)
andJdmat 0:81638ee0ad32 98 {
andJdmat 0:81638ee0ad32 99 //lcd.locate(8,0);
andJdmat 0:81638ee0ad32 100 //lcd.printf("Kp=%d",encoder.getPulses());
andJdmat 0:81638ee0ad32 101 //wait(.5);
andJdmat 0:81638ee0ad32 102
andJdmat 0:81638ee0ad32 103 ini1:
andJdmat 0:81638ee0ad32 104 fflush( stdin );
andJdmat 0:81638ee0ad32 105 header=0;
andJdmat 0:81638ee0ad32 106 //l1=1;
andJdmat 0:81638ee0ad32 107 header = irda.read_low_us(); //funcion para leer un pulso de caida o bajo
andJdmat 0:81638ee0ad32 108 if (header > head_L && header < head_H) goto seguir;//verificar que este en la tolerancia +-20%
andJdmat 0:81638ee0ad32 109 else goto ini1;
andJdmat 0:81638ee0ad32 110
andJdmat 0:81638ee0ad32 111 seguir:
andJdmat 0:81638ee0ad32 112 wait_us(333);
andJdmat 0:81638ee0ad32 113 //l1=0;
andJdmat 0:81638ee0ad32 114 for(i=0;i<=(num_bits-1);++i){ // POR OSCILOSCOPIO se determina que llegan (num_bits),datos
andJdmat 0:81638ee0ad32 115 dato = irda.read_low_us(); //leer un bit de datos que es pulso arriba en este control
andJdmat 0:81638ee0ad32 116 num[i]=dato;
andJdmat 0:81638ee0ad32 117 wait_us(333);
andJdmat 0:81638ee0ad32 118 }
andJdmat 0:81638ee0ad32 119
andJdmat 0:81638ee0ad32 120 wait(0.5); //espero un poquito antes de leer todo el arreglo y ponerlo en pantalla
andJdmat 0:81638ee0ad32 121 //pc.printf(",%d",header);
andJdmat 0:81638ee0ad32 122
andJdmat 0:81638ee0ad32 123 for(i=0;i<=(num_bits-1);++i){
andJdmat 0:81638ee0ad32 124 // pc.printf(",%d",num[i]);
andJdmat 0:81638ee0ad32 125 }
andJdmat 0:81638ee0ad32 126
andJdmat 0:81638ee0ad32 127 wait(0.1); //espero
andJdmat 0:81638ee0ad32 128 pc.printf("\n\n");//imprimo en binario
andJdmat 0:81638ee0ad32 129 for(i=0;i<=(num_bits-1);++i){
andJdmat 0:81638ee0ad32 130 if(num[i] > ((T_alto+T_bajo)/2)){
andJdmat 0:81638ee0ad32 131 // pc.printf("1");
andJdmat 0:81638ee0ad32 132 aux[i]=1;
andJdmat 0:81638ee0ad32 133 }
andJdmat 0:81638ee0ad32 134 else {
andJdmat 0:81638ee0ad32 135 //pc.printf("0");
andJdmat 0:81638ee0ad32 136 aux[i]=0;
andJdmat 0:81638ee0ad32 137 }
andJdmat 0:81638ee0ad32 138 }
andJdmat 0:81638ee0ad32 139 // pc.printf("%d",aux[0]);
andJdmat 0:81638ee0ad32 140 if ( aux[0]==SubirCanal[0]&&aux[1]==SubirCanal[1]&&aux[2]==SubirCanal[2]&&aux[3]==SubirCanal[3]&&aux[4]==SubirCanal[4]){
andJdmat 0:81638ee0ad32 141 diferencia=10 ;
andJdmat 0:81638ee0ad32 142 pc.printf("sumo");
andJdmat 0:81638ee0ad32 143 }
andJdmat 0:81638ee0ad32 144 else if (aux[0]==BajarCanal[0]&&aux[1]==BajarCanal[1]&&aux[2]==BajarCanal[2]&&aux[3]==BajarCanal[3]&&aux[4]==BajarCanal[4]){
andJdmat 0:81638ee0ad32 145 diferencia=-1;
andJdmat 0:81638ee0ad32 146 pc.printf("resto");
andJdmat 0:81638ee0ad32 147 }
andJdmat 0:81638ee0ad32 148
andJdmat 0:81638ee0ad32 149 i=pos;
andJdmat 0:81638ee0ad32 150 vec[i-1] = vec[i-1]+diferencia;
andJdmat 0:81638ee0ad32 151
andJdmat 0:81638ee0ad32 152 for(k=0;k<=3;k++){
andJdmat 0:81638ee0ad32 153 if(vec[k]<=0)
andJdmat 0:81638ee0ad32 154 vec[k]=0;
andJdmat 0:81638ee0ad32 155 if(vec[k]>=999)
andJdmat 0:81638ee0ad32 156 vec[k]=999;
andJdmat 0:81638ee0ad32 157 }
andJdmat 0:81638ee0ad32 158
andJdmat 0:81638ee0ad32 159 diferencia = 0;
andJdmat 0:81638ee0ad32 160 spnum = vec[0];
andJdmat 0:81638ee0ad32 161 kpnum = vec[1];
andJdmat 0:81638ee0ad32 162 kinum = vec[2];
andJdmat 0:81638ee0ad32 163 kdnum = vec[3];
andJdmat 0:81638ee0ad32 164
andJdmat 0:81638ee0ad32 165
andJdmat 0:81638ee0ad32 166 switch (pos){
andJdmat 0:81638ee0ad32 167 case 1:
andJdmat 0:81638ee0ad32 168 lcd.locate(3,0);
andJdmat 0:81638ee0ad32 169 lcd.printf(" ");
andJdmat 0:81638ee0ad32 170 lcd.locate(3,0);
andJdmat 0:81638ee0ad32 171 lcd.printf("%d", spnum);
andJdmat 0:81638ee0ad32 172 case 2:
andJdmat 0:81638ee0ad32 173 lcd.locate(11,0);
andJdmat 0:81638ee0ad32 174 lcd.printf(" ");
andJdmat 0:81638ee0ad32 175 lcd.locate(11,0);
andJdmat 0:81638ee0ad32 176 lcd.printf("%d", kpnum);
andJdmat 0:81638ee0ad32 177 case 3:
andJdmat 0:81638ee0ad32 178 lcd.locate(3,1);
andJdmat 0:81638ee0ad32 179 lcd.printf(" ");
andJdmat 0:81638ee0ad32 180 lcd.locate(3,1);
andJdmat 0:81638ee0ad32 181 lcd.printf("%d", kinum);
andJdmat 0:81638ee0ad32 182 case 4:
andJdmat 0:81638ee0ad32 183 lcd.locate(11,1);
andJdmat 0:81638ee0ad32 184 lcd.printf(" ");
andJdmat 0:81638ee0ad32 185 lcd.locate(11,1);
andJdmat 0:81638ee0ad32 186 lcd.printf("%d", kdnum);
andJdmat 0:81638ee0ad32 187 }
andJdmat 0:81638ee0ad32 188 // lcd.writeCommand(C1);
andJdmat 0:81638ee0ad32 189 if (aux[0]==SubirVolumen[0]&&aux[1]==SubirVolumen[1]&&aux[2]==SubirVolumen[2]&&aux[3]==SubirVolumen[3]&&aux[4]==SubirVolumen[4]) //cambia la posicion de ingreso de parametros
andJdmat 0:81638ee0ad32 190 {
andJdmat 0:81638ee0ad32 191 pc.printf("salto");
andJdmat 0:81638ee0ad32 192 led3 =!led3;
andJdmat 0:81638ee0ad32 193
andJdmat 0:81638ee0ad32 194 if (pos == 4)
andJdmat 0:81638ee0ad32 195 {
andJdmat 0:81638ee0ad32 196 pos=1;
andJdmat 0:81638ee0ad32 197 lcd.locate(3,0);
andJdmat 0:81638ee0ad32 198 lcd.printf("%d", spnum);
andJdmat 0:81638ee0ad32 199
andJdmat 0:81638ee0ad32 200 }
andJdmat 0:81638ee0ad32 201 else if (pos == 1)
andJdmat 0:81638ee0ad32 202 {
andJdmat 0:81638ee0ad32 203 pos = 2;
andJdmat 0:81638ee0ad32 204 lcd.locate(11,0);
andJdmat 0:81638ee0ad32 205 lcd.printf("%d", kpnum);
andJdmat 0:81638ee0ad32 206 }
andJdmat 0:81638ee0ad32 207 else if(pos == 2)
andJdmat 0:81638ee0ad32 208 {
andJdmat 0:81638ee0ad32 209 pos = 3;
andJdmat 0:81638ee0ad32 210 lcd.locate(3,1);
andJdmat 0:81638ee0ad32 211 lcd.printf("%d", kinum);
andJdmat 0:81638ee0ad32 212 }
andJdmat 0:81638ee0ad32 213 else if(pos == 3)
andJdmat 0:81638ee0ad32 214 {
andJdmat 0:81638ee0ad32 215 pos = 4;
andJdmat 0:81638ee0ad32 216 lcd.locate(11,1);
andJdmat 0:81638ee0ad32 217 lcd.printf("%d", kdnum);
andJdmat 0:81638ee0ad32 218 }
andJdmat 0:81638ee0ad32 219 wait(0.25);
andJdmat 0:81638ee0ad32 220
andJdmat 0:81638ee0ad32 221 }
andJdmat 0:81638ee0ad32 222 if (aux[0]==BajarVolumen[0]&&aux[1]==BajarVolumen[1]&&aux[2]==BajarVolumen[2]&&aux[3]==BajarVolumen[3]&&aux[4]==BajarVolumen[4])
andJdmat 0:81638ee0ad32 223 {
andJdmat 0:81638ee0ad32 224 break; //sale del bucle si pisan suiche4
andJdmat 0:81638ee0ad32 225 }
andJdmat 0:81638ee0ad32 226 wait(0.1);
andJdmat 0:81638ee0ad32 227
andJdmat 0:81638ee0ad32 228 }
andJdmat 0:81638ee0ad32 229
andJdmat 0:81638ee0ad32 230
andJdmat 0:81638ee0ad32 231
andJdmat 0:81638ee0ad32 232 pc.printf("sp:%d kp:%d ki:%d kd:%d",spnum,kpnum,kinum,kdnum);
andJdmat 0:81638ee0ad32 233 //Transicion
andJdmat 0:81638ee0ad32 234 lcd.writeCommand(C4);//escribimos un comando segun el manual del modulo LCD para quitar cursor bajo
andJdmat 0:81638ee0ad32 235 lcd.cls(); //borra la pantalla
andJdmat 0:81638ee0ad32 236 lcd.printf(" GUARDADOS!");
andJdmat 0:81638ee0ad32 237 wait(1);
andJdmat 0:81638ee0ad32 238 lcd.cls();
andJdmat 0:81638ee0ad32 239 lcd.printf(" INICIA EL PID");
andJdmat 0:81638ee0ad32 240 wait(1);
andJdmat 0:81638ee0ad32 241 // se imprimen los parches del control *****************************************
andJdmat 0:81638ee0ad32 242 lcd.cls();
andJdmat 0:81638ee0ad32 243 lcd.printf("Er=%3.0f",err);
andJdmat 0:81638ee0ad32 244 lcd.locate(8,0);
andJdmat 0:81638ee0ad32 245 lcd.printf("Me=%3.0f",med);
andJdmat 0:81638ee0ad32 246 lcd.locate(0,1);
andJdmat 0:81638ee0ad32 247 lcd.printf("Sp=%3.0f",spnum);
andJdmat 0:81638ee0ad32 248 lcd.locate(8,1);
andJdmat 0:81638ee0ad32 249 lcd.printf("Co=%3.0f",pid);
andJdmat 0:81638ee0ad32 250 wait(1);
andJdmat 0:81638ee0ad32 251
andJdmat 0:81638ee0ad32 252 // CICLO PRINCIPAL CONTROLADOR PID
andJdmat 0:81638ee0ad32 253 lop1: med = y.read()*999;
andJdmat 0:81638ee0ad32 254 err = (spnum-med); //se calcula el error
andJdmat 0:81638ee0ad32 255 ap = kpnum*err*0.01f; //se calcula la accion proporcinal
andJdmat 0:81638ee0ad32 256 ai =(kinum*err*0.01f)+ai; //calculo de la integral del error
andJdmat 0:81638ee0ad32 257 ad = kdnum*(err-err_v)*0.01f; //calculo de la accion derivativa
andJdmat 0:81638ee0ad32 258 pid = (ap+ai+ad);
andJdmat 0:81638ee0ad32 259 // se verifica que pid sea positivo **************************************
andJdmat 0:81638ee0ad32 260 if(pid<=0)
andJdmat 0:81638ee0ad32 261 {
andJdmat 0:81638ee0ad32 262 pid=0;
andJdmat 0:81638ee0ad32 263 }
andJdmat 0:81638ee0ad32 264
andJdmat 0:81638ee0ad32 265 // se verifica que pid sea menor o igual la valor maximo *****************
andJdmat 0:81638ee0ad32 266 if (pid > 999)
andJdmat 0:81638ee0ad32 267 {
andJdmat 0:81638ee0ad32 268 pid=999;
andJdmat 0:81638ee0ad32 269 }
andJdmat 0:81638ee0ad32 270
andJdmat 0:81638ee0ad32 271
andJdmat 0:81638ee0ad32 272 //se muestran las variables******************************************
andJdmat 0:81638ee0ad32 273 lcd.locate(3,0);
andJdmat 0:81638ee0ad32 274 lcd.printf(" ");
andJdmat 0:81638ee0ad32 275 lcd.locate(3,0);
andJdmat 0:81638ee0ad32 276 lcd.printf("%3.0f",err);
andJdmat 0:81638ee0ad32 277 lcd.locate(11,0);
andJdmat 0:81638ee0ad32 278 lcd.printf(" ");
andJdmat 0:81638ee0ad32 279 lcd.locate(11,0);
andJdmat 0:81638ee0ad32 280 lcd.printf("%3.0f",med);
andJdmat 0:81638ee0ad32 281 lcd.locate(3,1);
andJdmat 0:81638ee0ad32 282 lcd.printf(" ");
andJdmat 0:81638ee0ad32 283 lcd.locate(3,1);
andJdmat 0:81638ee0ad32 284 lcd.printf("%d",spnum);
andJdmat 0:81638ee0ad32 285 lcd.locate(11,1);
andJdmat 0:81638ee0ad32 286 lcd.printf(" ");
andJdmat 0:81638ee0ad32 287 lcd.locate(11,1);
andJdmat 0:81638ee0ad32 288 lcd.printf("%3.0f",pid);
andJdmat 0:81638ee0ad32 289
andJdmat 0:81638ee0ad32 290
andJdmat 0:81638ee0ad32 291
andJdmat 0:81638ee0ad32 292 // Fin de la modificacion
andJdmat 0:81638ee0ad32 293
andJdmat 0:81638ee0ad32 294 //Normalizacion de la salida
andJdmat 0:81638ee0ad32 295 // se actualizan las variables *******************************************
andJdmat 0:81638ee0ad32 296 err_v = err;
andJdmat 0:81638ee0ad32 297 o = pid/999;
andJdmat 0:81638ee0ad32 298 u.write(o);
andJdmat 0:81638ee0ad32 299 // se envia el valor pid a puerto analogico de salida (D/A) **************
andJdmat 0:81638ee0ad32 300
andJdmat 0:81638ee0ad32 301 // se repite el ciclo
andJdmat 0:81638ee0ad32 302 wait_ms(300);
andJdmat 0:81638ee0ad32 303 goto lop1;
andJdmat 0:81638ee0ad32 304 }