Aplicación para un controlador PID con Interfaz en AppInventor

Dependencies:   mbed

Revision:
1:608758dfdcfd
Parent:
0:53194b344442
--- a/main.cpp	Thu Jun 13 21:20:06 2019 +0000
+++ b/main.cpp	Wed Jul 24 18:58:25 2019 +0000
@@ -1,38 +1,63 @@
+/*Práctica 3 - Procesadores 2019-1
+   Giovani Cardona Sánchez
+   Mateo Valencia Diaz
+   Verónica Ríos Vargas
+   Juan Esteban Rodriguez Oquendo 
+   Juan Camilo Pérez Estrada
+*/
+
 #include "mbed.h"
 #include "string.h"
 
 AnalogIn y(PTB3);//entrada analoga
-AnalogOut u(PTE30);//salida analoga OJO solo se le pueden drenar 1.5mA en circuitos use un Buffer
-//si se ignora esto se arruina la FRDMKL25Z
-//Serial HC06(USBTX, USBRX, "HC06");
+AnalogOut u(PTE30);//salida analoga 
+Serial pc(USBTX, USBRX, "pc");
 Serial HC06(PTE0,PTE1);
+PwmOut out(PTC3);
 
-char buffer[128];
+
+char buffer[30];
 char c;
 int readptr = 0;
 int Kp, Ki, Kd, Sp;
-float pid,o,ai,ad,ap,med,err;
-float err_v;
-int checker1, checker2, checker3, checker4;
+float pid,o,ai,ad,ap,med,err,err_v,d;
+
+Timer t;   //VALOR DEL TIEMPO
+Timer t2; 
+int count;
+int j,k;
+int mode = -1, val;
+char masc,b;
+int duty;
 
-int conv(){
-    readptr = 0;
-    while( (c = HC06.getc()) != '\n') {
-            buffer[readptr++] = c;
+//------------------------------Funciones----------------------------------------------//
+int readBuffer(char *buffer,int count)   //esta funcion lee un bufer de datos
+{
+    int i=0; 
+    t.start();    //CUENTA EL TIEMPO DE CONEXION E INICIA
+    while(1) {
+        while (HC06.readable()) {
+            char c = HC06.getc();
+            if (c == '\r' || c == '\n') c = '$';//si se envia fin de linea o de caracter inserta $
+            buffer[i++] = c;//mete al bufer el caracter leido
+            if(i > count)break;//sale del loop si ya detecto terminacion
+            //pc.printf("c: %c",c);
+        }
+        if(i > count)break;
+        
+        if(t.read() > 1) {  //MAS DE UN SEGUNDO DE ESPERA SE SALE Y REINICA EL RELOJ Y SE SALE
+            t.stop();
+            t.reset();
+            //pc.printf("\ni: %d",i);
+            //pc.printf("\ncount: %d",count);
+            //pc.printf("\nc: %c",c);
+            break;
+        }
     }
-    buffer[readptr++] = 0;
-    
-    //HC06.printf("buffer= %s\n\r ",buffer);  //imprime el bufer
-    //HC06.printf("buffer= %c  %c\n\r ",buffer[0],buffer[1]);//imprime el cero y el uno
-    
-    char *s1 = buffer;
-    int num = atoi(s1);
-    
-    //HC06.printf("Num: %d", num);
-    
-    return num;
+     return 0;
 }
 
+//-----//
 void cleanBuffer(char *buffer, int count)  //esta funcion limpia el bufer
 {
     for(int i=0; i < count; i++) {
@@ -40,165 +65,129 @@
     }
 }
 
+//-----//
+void PID(int Sp, int Kp, int Ki, int Kd )
+{
+    // CICLO PRINCIPAL CONTROLADOR PID
+    med = y.read()*999;
+    err = (Sp-med);  //se calcula el error
+    ap = Kp*err*0.01f;     //se calcula la accion proporcinal
+    ai =(Ki*err*0.01f)+ai;    //calculo de la integral del error
+    ad = Kd*(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 al valor maximo *****************
+    if (pid > 999){
+        pid=999;
+    }
+    
+    //Normalizacion de la salida
+    // se actualizan las variables *******************************************
+    err_v = err;
+    o = pid/999;
+    u.write(o); //  se envia el valor pid a puerto analogico de salida (D/A) **************
+      
+    if(med<256){           //debo generar dos casos a APP inventor solo me recibe hex asi: 0xhhhh (4 cifras)    
+       HC06.putc(0);     //si el numero es hasta 255 se le ponen dos ceros adelante a la secuencia de bits
+       HC06.putc(med);     //luego la cifra menos significativa
+    }
+    if(med>255){          //pero si es mayor a 255 las cifras deben ser convertidas a un hex de dos bytes de la siguiente forma   
+       j=med/256;       //calculo la cifra mas significativa
+       k=med-j*256;     //calculo la cifra menos significativa
+       HC06.putc(j);   //las envio a la usart para que se las ponga al modulo bluetooth y la lleve al android
+       HC06.putc(k);   //mas significativa primero, menos despues si no no funciona!!! y con la orden PUTC solo asi le envia binarios
+    }
+    //pc.printf("SetPoint\tEntrada\t\tError\t\tSalida\n");
+    //pc.printf("%d\t\t%0.2f\t\t%0.2f\t\t%0.2f\n",Sp,med,err,pid);
+    //pc.printf("%0.2fV\t\t%0.2fV\t\t%0.2fV\t\t%0.2fV\n\n",((Sp*3.3)/1000),((med*3.3)/1000),((err*3.3)/1000),((pid*3.3)/1000));
+    //  se repite el ciclo
+    //wait_ms(100);
+}
+//-----------------------------------------------------------------------------------//
+
 int main(){
     
+    out.period_ms(200);
 // Bluetooth
     HC06.baud(9600);
-    HC06.printf("CONTROLADOR PID BLUETOOTH\n");
-
-// Interfaz para el HC06
-    HC06.printf("***********************************************\n");
-    HC06.printf("CONTROLADOR PID \n");
-    HC06.printf("***********************************************\n");
-    HC06.printf("* Menu para los parametros del controlador PID: \n\n");
-    HC06.printf("* Kp - Ingresar valor de la consotante proporcional \n");
-    HC06.printf("* Ki - Ingresar valor de la consotante integral \n");
-    HC06.printf("* Kd - Ingresar valor de la consotante derivativa \n");
-    HC06.printf("* Sp - Ingresar valor del Set-Point \n\n");
-        
-    while(1){
-        
-        // Analizamos lo que ingresa el usuario
-        while( (c = HC06.getc()) != '\n') {
-            buffer[readptr++] = c;
-        }
-        buffer[readptr++] = 0;
-        
-        //HC06.printf("buffer= %s\n\r ",buffer);  //imprime el bufer
-        //HC06.printf("buffer= %c  %c\n\r ",buffer[0],buffer[1]);//imprime el cero y el uno
-        
-        //////////////////////////////////////////
+    HC06.format(8,Serial::None,1); 
         
-        if (strncmp(buffer, "Kp", 2) == 0) {
-            //Se lee el valor para Kp
-            cleanBuffer(buffer,5);
-            HC06.printf("Ingrese el valor para Kp: ");
-            Kp = conv();
-            checker1=1;
-        }
-        else if (strncmp(buffer, "Ki", 2) == 0) {
-            //Se lee el valor para Ki
-            cleanBuffer(buffer,5);
-            HC06.printf("Ingrese el valor para Ki: ");
-            Ki = conv();
-            checker2=1;
-        }
-        else if (strncmp(buffer, "Kd", 2) == 0) {
-            //Se lee el valor para Kd
-            cleanBuffer(buffer,5);
-            HC06.printf("Ingrese el valor para Kd: ");
-            Kd = conv();
-            checker3=1;
-        }
-        else if (strncmp(buffer, "Sp", 2) == 0) {
-            //Se lee el valor para Sp
-            cleanBuffer(buffer,5);
-            HC06.printf("Ingrese el valor para Sp: ");
-            Sp = conv();
-            if(Sp<=0){Sp=0;}
-            if(Sp > 999){Sp=999;}
-            checker4=1;
-        }
-        else {
-            HC06.printf("Syntax error \n");       
-        }
-        readptr = 0;
-        //buffer[0]='\0';
-        //buffer[1]='\0';
-        //buffer[2]='\0';
+     while(1){ 
+        if (HC06.readable()) {
+            cleanBuffer(buffer,30);
+            readBuffer(buffer,30);
+            sscanf(buffer,"%c %d %d %d %d",&masc,&Sp,&Kp,&Ki,&Kd);
+            pc.printf("%c %d %d %d %d\n",masc,Sp,Kp,Ki,Kd);
+            
+            pc.printf("buffer= %s\n\r ",buffer);  //imprime el bufer
+            //pc.printf("buffer= %c  %c %c\n\r ",buffer[0],buffer[1],buffer[2]);//imprime el cero y el uno
+            
+            t2.start();
+            cleanBuffer(buffer,30);
+            if (masc == 'A'){
+                //sscanf(buffer,"%c %d %d %d %d",&masc,&Sp, &Kp, &Ki, &Kd);
+                //pc.printf("%c %d %d %d %d\n",masc,Sp,Kp,Ki,Kd);
+                if(Sp<=0){Sp=0;}
+                if(Sp > 999){Sp=999;}
+                mode = 0;
+            }
+            else if (masc == 'B'){
+                //sscanf(buffer,"%c %d %d",&masc,&mode,&val);
+                //pc.printf("%c %d %d\n",masc,mode,val);
+                mode = Sp;
+                val = Kp;
+            }
+        }     
         
-        if (checker1 == 1 && checker2 == 1 && checker3 == 1 && checker4 == 1 ){
-            HC06.printf("Parametros listos para iniciar \n");
-            HC06.printf("*************************************\n");
-            HC06.printf("Iniciar ahora (Si/No) \n");
-            
-            //Se lee la elección del usuario
-           while(1){
-                while( (c = HC06.getc()) != '\n') {
-                    buffer[readptr++] = c;
-                }
-                buffer[readptr++] = 0;
+        if (mode == 0){ 
+            if(t2.read_ms() > 300){
+                PID(Sp, Kp, Ki, Kd);
+                t2.reset();
+            }         
+        }   
+        else if(mode == 1){
+            if(t2.read_ms() > 300){
+                med = y.read()*999;
+                duty = (val/4);
+                //pc.printf("\nduty: %d",duty);
+                out.pulsewidth_ms(duty);
                 
-                if (strncmp(buffer, "Si", 2) == 0){
-                    HC06.printf("* Ingrese 'P' si desea cambiar el Set Ponit  \n\n");
-                    HC06.printf("Iniciando... \n\n");
-                    wait_ms(1000);
-                    break;
-                }  
-                else{
-                    HC06.printf("Iniciar ahora (Si/No) \n");
+                if(med<256){           //debo generar dos casos a APP inventor solo me recibe hex asi: 0xhhhh (4 cifras)    
+                   HC06.putc(0);     //si el numero es hasta 255 se le ponen dos ceros adelante a la secuencia de bits
+                   HC06.putc(med);     //luego la cifra menos significativa
                 }
-            readptr = 0;
-            }
-            break;
-        }else{
-            HC06.printf("*************************************\n");
-            HC06.printf("Ingrese los valores restantes \n");
-            HC06.printf("*************************************\n");
-            }
-        HC06.printf("\n");
-    }
-    
-    // CICLO PRINCIPAL CONTROLADOR PID
-    
-    lop1:  
-        med = y.read()*999;
-        err = (Sp-med);  //se calcula el error
-        ap = Kp*err*0.01f;     //se calcula la accion proporcinal
-        ai =(Ki*err*0.01f)+ai;    //calculo de la integral del error
-        ad = Kd*(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 al valor maximo *****************
-        if (pid > 999)
-        {
-            pid=999;
+                if(med>255){          //pero si es mayor a 255 las cifras deben ser convertidas a un hex de dos bytes de la siguiente forma   
+                   j=med/256;       //calculo la cifra mas significativa
+                   k=med-j*256;     //calculo la cifra menos significativa
+                   HC06.putc(j);   //las envio a la usart para que se las ponga al modulo bluetooth y la lleve al android
+                   HC06.putc(k);   //mas significativa primero, menos despues si no no funciona!!! y con la orden PUTC solo asi le envia binarios
+                }
+                t2.reset();
+            }    
         }
-        
-        //Normalizacion de la salida
-        // se actualizan las variables *******************************************
-        err_v = err;
-        o = pid/999;
-        u.write(o); //  se envia el valor pid a puerto analogico de salida (D/A) **************
-        
-        /*HC06.printf("SetPoint\tEntrada\t\tError\t\tSalida\n");
-        HC06.printf("%d\t\t%0.2f\t\t%0.2f\t\t%0.2f\n",Sp,med,err,pid);
-        HC06.printf("%0.2fV\t\t%0.2fV\t\t%0.2fV\t\t%0.2fV\n\n",((Sp*3.3)/1000),((med*3.3)/1000),((err*3.3)/1000),((pid*3.3)/1000));*/
-        
-        HC06.printf("SetPoint: %d       %0.2fV\n\r",Sp,((Sp*3.3)/1000));
-        HC06.printf("Entrada:  %0.2f    %0.2fV\n\r",med,((med*3.3)/1000));
-        HC06.printf("Error:    %0.2f    %0.2fV\n\r",err,((err*3.3)/1000));
-        HC06.printf("Salida:   %0.2f    %0.2fV\n\r",pid,((pid*3.3)/1000));
-        HC06.printf("\n\r");
-        
-        ////-----------------------Nuevo Setpoint-------------------------------------------
-        if(HC06.readable()){
-            if ((c = HC06.getc()) == 'P') {
-                buffer[readptr++] = c;
-            }
-            buffer[readptr++] = 0;
-            //HC06.printf("buffer= %s\n\r ",buffer);  //imprime el bufer
-            //HC06.printf("buffer= %c  %c\n\r ",buffer[0],buffer[1]);//imprime el cero y el uno
+        else if(mode == 2)
+        {   
+            if(t2.read_ms() > 300){
+                med = y.read()*999;
+                d = (val/100.0);
+                u.write(d);
+                
+                if(med<256){           //debo generar dos casos a APP inventor solo me recibe hex asi: 0xhhhh (4 cifras)    
+                   HC06.putc(0);     //si el numero es hasta 255 se le ponen dos ceros adelante a la secuencia de bits
+                   HC06.putc(med);     //luego la cifra menos significativa
+                }
+                if(med>255){          //pero si es mayor a 255 las cifras deben ser convertidas a un hex de dos bytes de la siguiente forma   
+                   j=med/256;       //calculo la cifra mas significativa
+                   k=med-j*256;     //calculo la cifra menos significativa
+                   HC06.putc(j);   //las envio a la usart para que se las ponga al modulo bluetooth y la lleve al android
+                   HC06.putc(k);   //mas significativa primero, menos despues si no no funciona!!! y con la orden PUTC solo asi le envia binarios
+                }
+                t2.reset();
+            } 
         }
-        if (strncmp(buffer, "P", 1) == 0){
-            buffer[0]='\0';
-            HC06.printf("* Ingrese el nuevo SetPoint: ");
-            HC06.scanf("%d", &Sp);
-            if(Sp<=0){Sp=0;}
-            if(Sp > 999){Sp=999;}
-            HC06.printf("Iniciando... \n\n");
-            wait_ms(1000);
-        }  
-
-        readptr = 0;
-        /////------------------------------------------------------------------
-        
-        //  se repite el ciclo
-        wait_ms(500);
-        goto lop1;
-}
+        //cleanBuffer(buffer,30); 
+    }
+}
\ No newline at end of file