App PID

Dependencies:   mbed

main.cpp

Committer:
Cam53
Date:
2019-07-24
Revision:
0:379fd298c42a

File content as of revision 0:379fd298c42a:

//PROGRAMA PARA CONTROLAR EL VOLTAJE DE UN CAPACITOR EN UN CIRCUITO RC DESDE DISPOSITIVO ANDROID
//ENVIAR LOS VALORES SEPARADOS POR COMAS
#include "mbed.h"              
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

//Variables y parametros del control PID
float Kp=0,Ki=0,Kd=0,x=0,anchop=0;
float Sp=0;//set point
float ai,ek,ad,ap,err_v,o,yT,uk=0,Ts=0.01;
float duty=0,med=0,an=0;


AnalogIn   Vc(PTB0);//voltaje condensador
PwmOut  uc(PTE20); //accion de control
AnalogOut  u(PTE30);
Serial MR_ROBOT(PTE0,PTE1);  //puertos del xDM para el modulo BLUETOOTH
Serial pc(USBTX,USBRX); //puertos del PC
char buffer[60];// TAMAÑO DEL BUFER
Timer t;   //VALOR DEL TIEMPO
int count;
int i = 0;
int c=0;
int num,ii,j,k;
char r[]=""; 
DigitalOut LedRojo(LED1);
DigitalOut LedVerde(LED2);
DigitalOut LedAzul(LED3);

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 (MR_ROBOT.readable()) {
            char c = MR_ROBOT.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
        }
        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();
            break;
        }
    }
     return 0;
}
 
void cleanBuffer(char *buffer, int count)  //esta funcion limpia el bufer
{
    for(int i=0; i < count; i++) {
        buffer[i] = '\0';
    }
}
int main() {
    
       LedVerde=1;
       LedRojo=1;
       LedAzul=1;
       LedRojo=0;
       wait(2);   //PRENDE EL LED ROJO POR 2 SEGUNDOS
       LedRojo=1;
       MR_ROBOT.baud(9600);
       MR_ROBOT.format(8,Serial::None,1); 
       
           
       pc.printf("Enviar los valores Kp,Ki,Kd,Sp          \n");  
     
     
    DEF_CONST: 
        
        
       if (MR_ROBOT.readable()) {
          readBuffer(buffer,30);
          pc.printf("Enviar los valores Kp,Ki,Kd,Sp          \n");
          sscanf( buffer, "%f, %f, %f, %f, %f, %f",&x, &Kp, &Ki, &Kd, &Sp, &anchop);
          pc.printf("%.1f, %.1f, %.1f, %.1f, %.1f, %.1f \n",x,Kp,Ki,Kd,Sp,anchop);
          }
     
   if(Sp==0){
        goto DEF_CONST;}    
    if(x == 1){
        goto PID;
    }if(x == 2){
        goto PWM;
    }
    if(x == 3){
        goto ANALOG;
    }
    if(x==4){
        goto DEF_CONST;} 
     
    
       
    PID: 
    
    
    while(1){
      
      
         
    yT=Vc.read()*3.3;
    ek=Sp-yT;
     
    ap = Kp*ek*0.01f;     //se calcula la accion proporcinal
    ai =(Ki*ek*0.01f)+ai;    //calculo de la integral del error
    ad = Kd*(ek-err_v)*0.01f; //calculo de la accion derivativa
    uk = (ap+ai+ad);
    
    // se verifica que pid sea positivo **************
        if(uk<=0)
        {
            uk=0;
        }
 
        // se verifica que pid sea menor o igual la valor maximo *******
        if (uk > 3.3)
        {
            uk=3.3;
        }
     //Normalizacion de la salida
        // se actualizan las variables ***************
        err_v = ek;
        o = uk/3.3;
        u.write(o);
        //  se envia el valor pid a puerto analogico de salida (D/A) ******
        
                     
        //Mostrando error y salida actual
       // wait_ms(500);
  
        pc.printf("Error= %.2f\t",ek);
        pc.printf("Set Point= %.1f\t",Sp);
        pc.printf("Voltaje Actual= %.1f\n",yT);
        
        
               
                       //leo puerto analogico
       //  wait_ms(500);
       num = yT*303;      //agrando el numero de cero a mil
       if(num<256){           //debo generar dos casos a APP inventor solo me recibe hex asi: 0xhhhh (4 cixas)    
           MR_ROBOT.putc(0);     //si el numero es hasta 255 se le ponen dos ceros adelante a la secuencia de bits
           MR_ROBOT.putc(ii);     //luego la cixa menos significativa
       }
       if(num>255){          //pero si es mayor a 255 las cixas deben ser convertidas a un hex de dos bytes de la siguiente forma   
           j=num/256;       //calculo la cixa mas significativa
           k=num-j*256;     //calculo la cixa menos significativa
           MR_ROBOT.putc(j);   //las envio a la usart para que se las ponga al modulo bluetooth y la lleve al android
           MR_ROBOT.putc(k);   //mas significativa primero, menos despues si no no funciona!!! y con la orden PUTC solo asi le envia binarios
       }
       
       readBuffer(buffer,30);
        sscanf( buffer, "%f, %f, %f, %f, %f, %f",&x, &Kp, &Ki, &Kd, &Sp,&anchop);
        
        if(x == 4){
        goto DEF_CONST;
    }
              
        }
        
        PWM:
        while(1){
        yT=Vc.read()*3.3;
        
        duty=(anchop/4);
        uc.period_ms(200);
        uc.pulsewidth_ms(duty);
        
        //wait_ms(500);
        
        pc.printf("Ancho de pulso PWM(T=2000ms)= %.1f\t",duty);
        pc.printf("Voltaje Actual= %.1f\n",yT);
        
        // se repite el ciclo
        //wait_ms(500);
            
            num = yT*303; 
            if(num<256){           //debo generar dos casos a APP inventor solo me recibe hex asi: 0xhhhh (4 cixas)    
           MR_ROBOT.putc(0);     //si el numero es hasta 255 se le ponen dos ceros adelante a la secuencia de bits
           MR_ROBOT.putc(ii);     //luego la cixa menos significativa
       }
       if(num>255){          //pero si es mayor a 255 las cixas deben ser convertidas a un hex de dos bytes de la siguiente forma   
           j=num/256;       //calculo la cixa mas significativa
           k=num-j*256;     //calculo la cixa menos significativa
           MR_ROBOT.putc(j);   //las envio a la usart para que se las ponga al modulo bluetooth y la lleve al android
           MR_ROBOT.putc(k);   //mas significativa primero, menos despues si no no funciona!!! y con la orden PUTC solo asi le envia binarios
       }
           
        readBuffer(buffer,30);
        sscanf( buffer, "%f, %f, %f, %f, %f, %f",&x, &Kp, &Ki, &Kd, &Sp,&anchop);
        
        if(x == 4){
        goto DEF_CONST;
    }
    
            }
            
ANALOG:
    while(1){
    yT=Vc.read()*3.3;
    o = Sp/3.3;
    u.write(o);
        //  se envia el valor pid a puerto analogico de salida (D/A) **
        
        //  se repite el ciclo
     //wait_ms(500);
              
        //Mostrando error y salida actual
  
        pc.printf("Set Point= %.1f\t",Sp);
        pc.printf("Voltaje Actual= %.1f\n",yT);
        
        // se repite el ciclo
        //wait_ms(500);
            
            num = yT*303; 
            if(num<256){           //debo generar dos casos a APP inventor solo me recibe hex asi: 0xhhhh (4 cixas)    
           MR_ROBOT.putc(0);     //si el numero es hasta 255 se le ponen dos ceros adelante a la secuencia de bits
           MR_ROBOT.putc(ii);     //luego la cixa menos significativa
       }
       if(num>255){          //pero si es mayor a 255 las cixas deben ser convertidas a un hex de dos bytes de la siguiente forma   
           j=num/256;       //calculo la cixa mas significativa
           k=num-j*256;     //calculo la cixa menos significativa
           MR_ROBOT.putc(j);   //las envio a la usart para que se las ponga al modulo bluetooth y la lleve al android
           MR_ROBOT.putc(k);   //mas significativa primero, menos despues si no no funciona!!! y con la orden PUTC solo asi le envia binarios
       }
           
        readBuffer(buffer,30);
        sscanf( buffer, "%f, %f, %f, %f, %f, %f",&x, &Kp, &Ki, &Kd, &Sp,&anchop);
        
        if(x == 4){
        goto DEF_CONST;
    }
    
            
             
}    
   
 }