Jaime Osorio / Mbed 2 deprecated Tarea2_IRDA_PID

Dependencies:   Pulse1 TextLCD mbed

Fork of PID_ENCODER_OK by Gustavo Ramirez

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers main.cpp Source File

main.cpp

00001 /*
00002 PROCESADORES - 2016-03
00003 TAREA 2.  
00004     A partir del código de PID+TECLADO, utilizar un sensor IRDA para programar los 
00005     parámetros del PID (spnum, kp, ki y kd) en la FRDM-KL25Z. Observar todos estos 
00006     datos y configuraciones en una LCD
00007 PRESENTADO POR:
00008     Jaime Alonso Osorio Palacio
00009     David Fuertes Chaguezac         
00010     Wilson Anibal Ortega Andrade
00011     John Wilmer Ruiz López
00012 */
00013 
00014 #include "mbed.h" 
00015 #include "TextLCD.h"    // LCD 
00016 #include <Pulse1.h>
00017 #include "math.h" 
00018 #include "stdio.h"      //printf, etc
00019 #include "string.h"
00020 #include "stdlib.h"     // atoi
00021 #include "stdint.h"
00022 #include <assert.h>
00023 
00024 //****************** CONFIGURACIÓN DE PUERTOS DE COMUNICACIÓN ******************
00025 
00026 PulseInOut irda(PTD0);// en este puerto se pone el sensor infrarrojo
00027 Serial pc(USBTX, USBRX);        //configuro puerto serial
00028 
00029 TextLCD lcd(PTB10, PTB11, PTE2, PTE3, PTE4, PTE5); // rs, e, d4-d7
00030 AnalogIn y(PTB3);//entrada analoga
00031 AnalogOut u(PTE30);//salida analoga OJO solo se le pueden drenar 1.5mA en circuitos use un Buffer
00032 //si se ignora esto se arruina la FRDMKL25Z
00033 DigitalOut led1(LED1);
00034 DigitalOut led2(LED2);
00035 DigitalOut led3(LED3);
00036 
00037 //********************************* PARÁMETROS *********************************
00038 
00039 //codigos movimiento del cursor
00040 //int C1=0x0E; // solo muestra el curzor
00041 int C2=0x18; // desplaza izquierda
00042 int C3=0x1A; // desplaza derecha
00043 int C4=0x0C; // quito cursor bajo
00044 int C1=0x0F;
00045 int cambio=0, diferencia=0;
00046 float pid,o,ai,ad,ap,med,err;
00047 float err_v;
00048 int spnum=0,kinum=0,kpnum=0,kdnum=0,pos=1;
00049 int i=0,ii=0;
00050 int numero;
00051 char tecla1[1], tecla2[1],tecla3[1];
00052 int valor1=0, valor2=0, valor3=0;
00053 int valornum=0;
00054 int flag1=0, flag2=0, flag3=0;
00055 int conteo=0;
00056 
00057 //****************************** DATOS CONTROL IR ******************************
00058 
00059 const int head_H = 2880;    //+20% medida con osciloscopio en microsegundos
00060 const int head_L = 1920;    //-20%  medida con osciloscopio
00061 const int T_alto=567;       //ponga su tiempo de la prueba
00062 const int T_bajo=1170;      //ponga su tiempo de la prueba
00063 const int num_bits = 21;    //ponga su numero de bits
00064 int header =0;              //tiempo de cabecera pulso abajo
00065 int num[num_bits];          //cadena para almacenar todos los tiempos que conforman los bits de datos
00066 int aux[21];                //variable donde se concatenarán la trama de "bits"
00067 int binM[20];               // arreglo para dar valor a cada bit en decimal
00068 int dato;                   //tiempo de cada dato que se lee
00069 
00070 // DATOS DE PRUEBA CONTROL SONY RM-Y173 (SIRVE PARA SONY TRINITRON KV-21ME42/8)
00071 int uno=4224;       int UNO[]   ={0,0,0,0,0,0,0,1,0,0,0,0,1,0,0,0,0,0,0,0};
00072 int dos=12417;      int DOS[]   ={1,0,0,0,0,0,0,1,0,0,0,0,1,1,0,0,0,0,0,0};
00073 int tres=20610;     int TRES[]  ={0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
00074 int cuatro=28803;   int CUATRO[]={0,1,0,0,0,0,0,1,0,0,0,0,1,0,1,0,0,0,0,0};
00075 int cinco=36996;    int CINCO[] ={0,0,1,0,0,0,0,1,0,0,0,0,1,0,0,1,0,0,0,0};
00076 int seis=45189;     int SEIS[]  ={1,0,1,0,0,0,0,1,0,0,0,0,1,1,0,1,0,0,0,0};
00077 int siete=53382;    int SIETE[] ={0,1,1,0,0,0,0,1,0,0,0,0,1,0,1,1,0,0,0,0};
00078 int ocho=61575;     int OCHO[]  ={1,1,1,0,0,0,0,1,0,0,0,0,1,1,1,1,0,0,0,0};
00079 int nueve=69768;    int NUEVE[] ={0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0};
00080 int cero=77961;     int CERO[]  ={1,0,0,1,0,0,0,1,0,0,0,0,1,1,0,0,1,0,0,0};
00081 int power=176277;   int POWER[] ={1,0,1,0,1,0,0,1,0,0,0,0,1,1,0,1,0,1,0,0};
00082 int enter=94347;    int ENTER[] ={1,1,0,1,0,0,0,1,0,0,0,0,1,1,1,0,1,0,0,0};
00083 
00084 //******************************************************************************
00085 //******************************* CICLO PRINCIPAL ******************************
00086 //******************************************************************************
00087 
00088 int main(){
00089     lcd.locate(0,1);
00090     lcd.printf("**Control PID**");
00091     wait(2);
00092     lcd.cls(); // Borrar Pantalla
00093     lcd.writeCommand(C1);//escribimos un comando segun el manual del modulo LCD
00094 
00095     lcd.locate(8,0);                // necesariamente (columna, fila)
00096     lcd.printf("Kp=%d",kpnum);
00097     lcd.locate(0,1);
00098     lcd.printf("Ki=%d",kinum);
00099     lcd.locate(8,1);
00100     lcd.printf("Kd=%d",kdnum);
00101     lcd.locate(0,0);
00102     lcd.printf("Sp=%d",spnum);
00103     
00104     binM[0]=1;      // se crea un arreglo con los valores de cada bit en decimal
00105     for(i=1;i<(num_bits-1);++i){
00106         binM[i]=binM[i-1]*2;   }   // printf("%i",aux[i]);     
00107     
00108     while(1) { 
00109     diferencia=0, conteo=0; valor1=0, valor2=0, valor3=0;
00110     char valor[10] = {0};  strcpy(tecla1, ""); strcpy(tecla2, ""); strcpy(tecla3, "");
00111 ini1: 
00112         int header=0;
00113         led2=1;
00114         led1=1;
00115         header = irda.read_low_us();    //funcion para leer un pulso de caida o bajo
00116         if (header > head_L && header < head_H) goto seguir1;//verificar que este en la tolerancia +-20%
00117         else goto ini1;
00118 seguir1:
00119         wait_us(333);         //duración aproximada de tiempo muerto antes de comenzar la trama
00120         led2=0;               //enciendo un LED para indicar que pasó el header y ya se van a recibir datos
00121         for(i=0;i<(num_bits-1);++i){ // POR OSCILOSCOPIO se determina que llegan (num_bits),datos
00122             dato = irda.read_low_us(); //leer un bit de datos que es pulso bajo en este control
00123             num[i]=dato;      //guarda cada dato en el arreglo num
00124             wait_us(333);   
00125         }
00126         
00127         /*
00128         wait(0.1); //espero un poquito antes de leer todo el arreglo y ponerlo en pantalla 
00129         pc.printf("Duracion de cabecera = %d\n", header);
00130         pc.printf("Duracion de cada bit de llegada=");
00131         for(i=0;i<(num_bits-1);++i){
00132             pc.printf("%d,",num[i]);
00133         }
00134         wait(0.1);  //espero e imprimo en binario 
00135         pc.printf("\n");
00136         pc.printf("En binario =");
00137         */
00138         for(i=0;i<(num_bits-1);++i){
00139             if(num[i] > ((T_alto+T_bajo)/2)){
00140                 pc.printf("1");
00141                 aux[i]=1;
00142             }
00143             else{
00144                 pc.printf("0");
00145                 aux[i]=0;
00146             }
00147         }
00148         // strcpy(tecla, "");
00149         // printf("\t\t\t Tecla presionada: %s\n",tecla);
00150         
00151         // convierto a decimal la tecla presionada
00152         numero=0;
00153         for(i=0;i<(num_bits-1);++i){
00154             numero=numero+(binM[i]*aux[i]);
00155         }
00156         // printf("\n");
00157         // printf("Convertido a decimal=%d \n",numero);
00158 
00159         if      (numero==uno)   {strcpy(tecla1, "1");}
00160         else if (numero==dos)   {strcpy(tecla1, "2");}
00161         else if (numero==tres)  {strcpy(tecla1, "3");}
00162         else if (numero==cuatro){strcpy(tecla1, "4");}
00163         else if (numero==cinco) {strcpy(tecla1, "5");}
00164         else if (numero==seis)  {strcpy(tecla1, "6");}
00165         else if (numero==siete) {strcpy(tecla1, "7");}
00166         else if (numero==ocho)  {strcpy(tecla1, "8");}
00167         else if (numero==nueve) {strcpy(tecla1, "9");}
00168         else if (numero==cero)  {strcpy(tecla1, "0");}
00169         else if (numero==power) {strcpy(tecla1, "P");}
00170         else if (numero==enter) {strcpy(tecla1, "E");}
00171         else {goto ini1;}
00172         pc.printf("\t\t\t Tecla presionada: %s\n",tecla1);
00173         valor1=100*atoi(tecla1);
00174         
00175 CONTEO:
00176         conteo++;
00177         
00178         if (conteo == 1) {
00179             if (strcmp(tecla1, "P")!=0){
00180                 if (strcmp(tecla1, "E")!=0){
00181                     // strcpy(valor,tecla1);
00182                     pc.printf("VALOR en conteo=1 es %s \n",valor);
00183 ini2:               header=0; led2=1; led1=1;
00184                     header = irda.read_low_us();    //funcion para leer un pulso de caida o bajo
00185                     if (header > head_L && header < head_H) goto seguir2;//verificar que este en la tolerancia +-20%
00186                     else goto ini2;
00187 seguir2:            wait_us(333);         //duración aproximada de tiempo muerto antes de comenzar la trama
00188                     led2=0;               //enciendo un LED para indicar que pasó el header y ya se van a recibir datos
00189                     for(i=0;i<(num_bits-1);++i){ // POR OSCILOSCOPIO se determina que llegan (num_bits),datos
00190                         dato = irda.read_low_us(); //leer un bit de datos que es pulso bajo en este control
00191                         num[i]=dato;      //guarda cada dato en el arreglo num
00192                         wait_us(333);   
00193                     }
00194                     
00195                     for(i=0;i<(num_bits-1);++i){
00196                         if(num[i] > ((T_alto+T_bajo)/2)){
00197                             pc.printf("1");
00198                             aux[i]=1;
00199                         }
00200                         else{
00201                             pc.printf("0");
00202                             aux[i]=0;
00203                         }
00204                     }
00205                     
00206                     // convierto a decimal la tecla presionada
00207                     numero=0;
00208                     for(i=0;i<(num_bits-1);++i){
00209                         numero=numero+(binM[i]*aux[i]);
00210                     }
00211                     // printf("\n");
00212                     // printf("Convertido a decimal=%d \n",numero);
00213             
00214                     if      (numero==uno)   {strcpy(tecla2, "1");}
00215                     else if (numero==dos)   {strcpy(tecla2, "2");}
00216                     else if (numero==tres)  {strcpy(tecla2, "3");}
00217                     else if (numero==cuatro){strcpy(tecla2, "4");}
00218                     else if (numero==cinco) {strcpy(tecla2, "5");}
00219                     else if (numero==seis)  {strcpy(tecla2, "6");}
00220                     else if (numero==siete) {strcpy(tecla2, "7");}
00221                     else if (numero==ocho)  {strcpy(tecla2, "8");}
00222                     else if (numero==nueve) {strcpy(tecla2, "9");}
00223                     else if (numero==cero)  {strcpy(tecla2, "0");}
00224                     else if (numero==power) {strcpy(tecla2, "P");}
00225                     else if (numero==enter) {strcpy(tecla2, "E");}
00226                     else {goto ini2;}
00227                     pc.printf("\t\t\t Tecla presionada: %s\n",tecla2);
00228                     valor2=10*atoi(tecla2);
00229                     goto    CONTEO;
00230                     
00231                 } //if (strcmp(tecla1, "E")!=0){
00232                 else if(strcmp(tecla1, "E")==0){
00233                     {diferencia = valor1; goto siguiente;}
00234                 }
00235             }  //if (strcmp(tecla1, "P")!=0){
00236         }  //if (conteo == 1) {
00237 ////////////////////////////////////////////////////////////////////////////////
00238         if (conteo == 2) {
00239             if (strcmp(tecla2, "P")!=0){
00240                 if (strcmp(tecla2, "E")!=0){
00241                     // strcpy(valor,tecla2);
00242 ini3:               header=0; led2=1; led1=1;
00243                     header = irda.read_low_us();    //funcion para leer un pulso de caida o bajo
00244                     if (header > head_L && header < head_H) goto seguir3;//verificar que este en la tolerancia +-20%
00245                     else goto ini3;
00246 seguir3:            wait_us(333);         //duración aproximada de tiempo muerto antes de comenzar la trama
00247                     led2=0;               //enciendo un LED para indicar que pasó el header y ya se van a recibir datos
00248                     for(i=0;i<(num_bits-1);++i){ // POR OSCILOSCOPIO se determina que llegan (num_bits),datos
00249                         dato = irda.read_low_us(); //leer un bit de datos que es pulso bajo en este control
00250                         num[i]=dato;      //guarda cada dato en el arreglo num
00251                         wait_us(333);   
00252                     }
00253                     
00254                     for(i=0;i<(num_bits-1);++i){
00255                         if(num[i] > ((T_alto+T_bajo)/2)){
00256                             pc.printf("1");
00257                             aux[i]=1;
00258                         }
00259                         else{
00260                             pc.printf("0");
00261                             aux[i]=0;
00262                         }
00263                     }
00264                     
00265                     // convierto a decimal la tecla presionada
00266                     numero=0;
00267                     for(i=0;i<(num_bits-1);++i){
00268                         numero=numero+(binM[i]*aux[i]);
00269                     }
00270                     // printf("\n");
00271                     // printf("Convertido a decimal=%d \n",numero);
00272             
00273                     if      (numero==uno)   {strcpy(tecla3, "1");}
00274                     else if (numero==dos)   {strcpy(tecla3, "2");}
00275                     else if (numero==tres)  {strcpy(tecla3, "3");}
00276                     else if (numero==cuatro){strcpy(tecla3, "4");}
00277                     else if (numero==cinco) {strcpy(tecla3, "5");}
00278                     else if (numero==seis)  {strcpy(tecla3, "6");}
00279                     else if (numero==siete) {strcpy(tecla3, "7");}
00280                     else if (numero==ocho)  {strcpy(tecla3, "8");}
00281                     else if (numero==nueve) {strcpy(tecla3, "9");}
00282                     else if (numero==cero)  {strcpy(tecla3, "0");}
00283                     else if (numero==power) {strcpy(tecla3, "P");}
00284                     else if (numero==enter) {strcpy(tecla3, "E");}
00285                     else {goto ini3;}
00286                     pc.printf("\t\t\t Tecla presionada: %s\n",tecla3);
00287                     valor3=1*atoi(tecla3);
00288                     goto    CONTEO;
00289                 } //if (strcmp(tecla2, "E")!=0){
00290                 else if(strcmp(tecla2, "E")==0){
00291                     {goto siguiente;}
00292                 }
00293             }  //if (strcmp(tecla1, "P")!=0){
00294         }  //if (conteo == 1) {
00295 ////////////////////////////////////////////////////////////////////////////////
00296         if (conteo == 3){
00297             goto siguiente;
00298         }
00299     
00300  siguiente:       
00301         
00302         // diferencia=encoder.getPulses()-cambio;
00303         // cambio=encoder.getPulses();
00304         
00305         diferencia=valor1+valor2+valor3;
00306         
00307         if (strcmp(tecla1, "P")==0) 
00308         {
00309             pc.printf("Comienza el PID por presionar POWER");
00310             break;     // si se presiona el botón POWER se sale de la configuración y comienza el PID
00311         }
00312         
00313         if (diferencia==0)
00314         {
00315             //nada
00316         }
00317         else if(diferencia>0)
00318         {
00319             if(pos==1)
00320             {
00321                 if(diferencia>=999)
00322                 {
00323                     spnum=999;
00324                     lcd.locate(3,0);
00325                     lcd.printf("    ");
00326                     lcd.locate(3,0);
00327                     lcd.printf("%d", spnum);
00328                 }
00329                 else
00330                 {
00331                     spnum=diferencia;
00332                     lcd.locate(3,0);
00333                     lcd.printf("%d", spnum);
00334                 }
00335             } //else if(pos==1)
00336             else if(pos==2)
00337             {
00338                 if(diferencia>=999)
00339                 {
00340                     kpnum=999;
00341                     lcd.locate(11,0);
00342                     lcd.printf("    ");
00343                     lcd.locate(11,0);
00344                     lcd.printf("%d", kpnum);
00345                 }
00346                 else
00347                 {
00348                     kpnum=diferencia;
00349                     lcd.locate(11,0);
00350                     lcd.printf("%d", kpnum);
00351                 }
00352             } //else if(pos==2)
00353             else if(pos==3)
00354             {
00355                 if(diferencia>=999)
00356                 {
00357                     kinum=999;
00358                     lcd.locate(3,1);
00359                     lcd.printf("    ");
00360                     lcd.locate(3,1);
00361                     lcd.printf("%d", kinum);
00362                 }
00363                 else
00364                 {
00365                     kinum=diferencia;
00366                     lcd.locate(3,1);
00367                     lcd.printf("%d", kinum);
00368                 }
00369             } //else if(pos==3)
00370             else if(pos==4)
00371             {
00372                 if(diferencia>=999)
00373                 {
00374                     kdnum=999;
00375                     lcd.locate(11,1);
00376                     lcd.printf("    ");
00377                     lcd.locate(11,1);
00378                     lcd.printf("%d", kdnum);
00379                 }
00380                 else
00381                 {
00382                     kdnum=diferencia;
00383                     lcd.locate(11,1);
00384                     lcd.printf("%d", kdnum);
00385                 }
00386             }   //else if(pos==4)
00387         } // else if(diferencia>0)
00388         
00389 
00390         if (strcmp(tecla1, "E")==0)  //cambia la posicion de ingreso de parametros si se presiona en botón ENTER
00391         {
00392             pc.printf("Cambio de posicion por presionar ENTER");
00393             led3 =!led3;
00394             if(pos==4)
00395             {
00396                 pos=1;
00397                 lcd.locate(3,0);
00398                 lcd.printf("%d", spnum);
00399             }
00400             else if (pos==1)
00401             {
00402                 pos++;
00403                 lcd.locate(11,0);
00404                 lcd.printf("%d", kpnum);
00405             }
00406             else if(pos==2)
00407             {
00408                 pos++;
00409                 lcd.locate(3,1);
00410                 lcd.printf("%d", kinum);
00411             }
00412             else if(pos==3)
00413             {
00414                 pos++;
00415                 lcd.locate(11,1);
00416                 lcd.printf("%d", kdnum);
00417             }
00418             wait(0.25);
00419 
00420         } //if (strcpy(tecla, "E")==0)
00421 
00422 
00423         wait(0.1);        
00424     }
00425 
00426 
00427 //Transicion
00428     lcd.writeCommand(C4);//escribimos un comando segun el manual del modulo LCD para quitar cursor bajo
00429     lcd.cls(); //borra la pantalla
00430     lcd.printf("   GUARDADOS!");
00431     wait(1);
00432     lcd.cls();
00433     lcd.printf(" INICIA EL PID");
00434     wait(1);
00435 // se imprimen los parches del control  *****************************************
00436     lcd.cls();
00437     lcd.printf("Er=%3.0f",err);
00438     lcd.locate(8,0);
00439     lcd.printf("Me=%3.0f",med);
00440     lcd.locate(0,1);
00441     lcd.printf("Sp=%3.0f",spnum);
00442     lcd.locate(8,1);
00443     lcd.printf("Co=%3.0f",pid);
00444     wait(1);
00445 
00446 // CICLO PRINCIPAL CONTROLADOR PID
00447  lop1:  med = y.read()*999;
00448         err = (spnum-med);  //se calcula el error
00449         ap = kpnum*err*0.01f;     //se calcula la accion proporcinal
00450         ai =(kinum*err*0.01f)+ai;    //calculo de la integral del error
00451         ad = kdnum*(err-err_v)*0.01f; //calculo de la accion derivativa
00452         pid = (ap+ai+ad);
00453         // se verifica que pid sea positivo **************************************
00454         if(pid<=0) {
00455             pid=0; }
00456         // se verifica que pid sea menor o igual la valor maximo *****************
00457         if (pid > 999) {
00458             pid=999;   }
00459         //se muestran las variables******************************************
00460             lcd.locate(3,0);    lcd.printf("    ");
00461             lcd.locate(3,0);    lcd.printf("%3.0f",err);
00462             lcd.locate(11,0);   lcd.printf("   ");
00463             lcd.locate(11,0);   lcd.printf("%3.0f",med);
00464             lcd.locate(3,1);    lcd.printf("   ");
00465             lcd.locate(3,1);    lcd.printf("%d",spnum);
00466             lcd.locate(11,1);   lcd.printf("   ");
00467             lcd.locate(11,1);   lcd.printf("%3.0f",pid);
00468            
00469         //Normalizacion de la salida
00470         // se actualizan las variables *******************************************
00471         err_v = err;
00472         o = pid/999;
00473         u.write(o);    //  se envia el valor pid a puerto analogico de salida (D/A) **************
00474         
00475         //  se repite el ciclo
00476         wait_ms(300);
00477         goto lop1;
00478 }