Autor Tema: PID, levitador neumático  (Leído 3140 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado Galeazzi

  • PIC10
  • *
  • Mensajes: 3
PID, levitador neumático
« en: 17 de Diciembre de 2017, 15:40:54 »
Muy buen día tengan caballeros, me dirijo a ustedes para poderles solicitar su ayuda sobre un problema que se me presento cuando estábamos trabajando en el PID de nuestro levitador neumático, el cual no esta reflejando el aumento y disminución de nuestro PWM.

Les platico una breve introducción:
Tenemos un tubo de acrílico que funciona como nuestro medio para que un cilindro pueda subir y bajar con la ayuda de un ventilador de 12VCD y este esta situado en la parte inferior del tubo y en la parte superior del tubo cuenta con un ultrasonico para la detección de distancia, por medio de labview mandamos un setpoint, pwm de forma manual y lo presentado en la imagen adjunta.

El método que estamos utilizando es el de oscilaciones sostenidas de Nichols y estasmos usando la siguiente parte de la tabla "PID---0.6*KCR---0.5pCR---0.125PCR".

Nuestra formula ingresada en el código es: controlpid=15+error*Kp_r+integral*Ki_r+derivada*Kd_r; (el 15 es nuestro offset utilizado para que nuestras ganancias estén en cero "Kp_r, Ki_r, Kd_r" nuestro cono apenas este venciendo la gravedad ), a lo cual la formula cumple la ecuación vita en la imagen adjunta.

Les publico el código que estamos utilizando:

unsigned char readbuff[16] absolute 0x500;   // Buffers should be in USB RAM, please consult datasheet
unsigned char writebuff[16] absolute 0x540;
//------------------------Panel de control
#define led      LATD.B5
#define arranque PORTB.B1
//------------------------Datos recibidos de la PC
#define setpoint_r readbuff[3]
#define manual_r readbuff[4]
#define pwm_manual readbuff[5]
#define stop_r    readbuff[6]
//Para poder modificar valores de Ki,p,d desde labview.
#define Ki_r      readbuff[7]
#define Kp_r      readbuff[8]
#define Kd_r      readbuff[9]   
//-----------------------Datos escribir en la PC
#define pwm      writebuff[0]
#define low_bit writebuff[1]
#define high_bit writebuff[2]
#define error_w writebuff[3]
#define errorp_w writebuff[4]
char cnt;
char kk;
//-------------------------Variables del programa
//char low_bit, high_bit;
int Radc=0,cm=0, x=0,mm=0;
float volts=0,cm_float=0;
//float Kp=0, Ki=0, Kd=0;
long integral=0,derivada=0;
int setpoint=0, feedback=0, error_old=0, error=0, controlpid=0, tiempo=0;

void interrupt(){
   USB_Interrupt_Proc();                   // USB servicing is done inside the interrupt
}
void main(void){
//---------------------------inicio de puertos
 PWM2_Init(5000); //Se inicia el módulo PWM
 PWM2_Set_Duty(controlpid);
 PWM2_Start();
 //Entradas
 TRISA.B1=1;//analogica
 TRISB.B1=1;//paro
 TRISB.B2=1;//arranque
 TRISB.B1=1;
 TRISB.B0=1;
 //Salidas
 TRISD.B4=0;
 TRISD.B5=0;
 TRISD.B6=0;
 TRISD.B7=0;
                             // Disable comparators
  HID_Enable(&readbuff,&writebuff);       // Enable HID communication
  while(1){
    while(!HID_Read())
      ;
      //Configuración de sensor
                      Radc=ADC_READ(0);
                      volts=Radc*0.004887585;
                      cm_float=0-11.0654+(15.0769*volts)+(-1.83196*volts*volts)+(0.228028*volts*volts*volts);
                      cm=cm_float;
      if(cm<0)
                      cm=0;
      else{}
      //Enviar datos del sensor al buff
               low_bit=cm;
               high_bit= cm>>8;
               setpoint=setpoint_r;
      //---------------------Parametros del PID sacados por método de oscilaciones sostenidas utilizados cuando no queremos modificarlas
                                        //Kp=1.1;
                                        //Ki=0.13;
                                        //Kd=7.5;
        //--------------------Modo automatico
      if(manual_r==0)
      {
                     //-----------------------------PID
                     feedback=cm;
                     error=setpoint-feedback;
                     derivada=error-error_old;
                     integral=integral+error;
      controlpid=15+error*Kp_r+integral*Ki_r+derivada*Kd_r;
                     error_w=error;
                     errorp_w=(error*100)/35;  //error en porcentaje
      //---------Anti windup
      if(controlpid>255)
      {
                        controlpid=255;
                        integral=integral-error;
      }
      else if (controlpid<0)
      {
                            controlpid=0;
                            integral=integral-error;
      }
      else{}
      //-------PWM------
                        PWM2_Set_Duty(controlpid);
                        pwm=controlpid;
                        error_old=error;
                        delay_ms(10);
      }
      //--------------------Modo manual
      else
      {
          PWM2_Set_Duty(pwm_manual);
          pwm=pwm_manual;
      }
      if(stop_r==1)
      {
                   PWM2_Set_Duty(0);
      }
    while(!HID_Write(&writebuff,16))
      ;
  }
}


Recapitulando "controlpid=15+error*Kp_r+integral*Ki_r+derivada*Kd_r;" es lo que estamos usando para que el PWM tome su valor.
Los errores que tenemos es que el pwm no aumenta cuando esta recibiendo perturbaciones.
Cuando metemos Ki de 1 u valores al azar nos arroja los 255bit de golpe y no trata de compenzar nada, si pudieran ayudarnos se los agradeceríamos mucho, ya llevamos dos días con este problema y no sabemos que estamos haciendo mal o bien.

PD: Gracias por su tiempo.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:PID, levitador neumático
« Respuesta #1 en: 18 de Diciembre de 2017, 18:05:08 »
Bienvenido al foro.

Veo demasiado código y no tengo tiempo de estudiarlo a fondo, de manera que iré preguntando poco a poco algunas cosas.

Si pones una consigna fija controlpid = 0 al ventilador ¿El cilindro cae abajo?

Si pones una consigna fija controlpid = 255 al ventilador (el máximo) ¿El cilindro sube arriba del todo?

Si ambas respuestas son que sí, vamos bien.

¿Funciona en modo controlador proporcional, sin derivativo ni integral?

Un saludo.
« Última modificación: 18 de Diciembre de 2017, 18:09:14 por Picuino »

Desconectado Galeazzi

  • PIC10
  • *
  • Mensajes: 3
Re:PID, levitador neumático
« Respuesta #2 en: 19 de Diciembre de 2017, 14:19:48 »
Gracias,

Si pones una consigna fija controlpid = 0 al ventilador ¿El cilindro cae abajo?
Si, cae el cilindro.

Si pones una consigna fija controlpid = 255 al ventilador (el máximo) ¿El cilindro sube arriba del todo?
Si, sube el maximo

Si ambas respuestas son que sí, vamos bien.

¿Funciona en modo controlador proporcional, sin derivativo ni integral?
Si, funciona.

Me estuvieron asesorando y el problema no es el código del microcontrolador, si no que desde labview no me manda los datos que son cuando los ingreso, se pierden y por eso actuaba de esa forma, ahora el nuevo problema, como no soy muy bueno en labview, es ver como mandar los datos sin que estos se pierdan, la forma en lo cual lo estoy haciendo es como se muestra en la imagen.
Saludos.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re:PID, levitador neumático
« Respuesta #3 en: 19 de Diciembre de 2017, 15:15:25 »
Bien, ahora queda el tema del intervalo de tiempo.

La fórmula que estás utilizando es para tiempo continuo, pero los microcontroladores funcionan en tiempo discreto.
¿Cuál es el intervalo de tiempo entre ejecuciones del algoritmo PID? Ese es el intervalo de tiempo T, tiene que ser siempre igual, tiene que ser pequeño en comparación con el tiempo de repuesta del sistema y tiene que ir en la fórmula.

http://www.picuino.com/es/arduprog/control-pid-digital.html

Creo que ese es el problema.



En cuanto al LabView:
Si crees que el problema está en el labView, prescinde de él para comenzar y una vez que funcione el lazo PID, incorpora el LabView.
Labview sólo debería recibir datos del microcontrolador para graficarlos y enviar consignas al microcontrolador para que modifique su comportamiento dentro de unos límites. El microcontrolador debería porder prescindir del PC sin problema.
Ten en cuenta que los lazos de realimentación suelen ser algo serio, mientras que un PC es algo muy poco serio.  Los PC no responden en tiempo determinista y en ocasiones se cuelgan. Ahora imagina un proceso peligroso o con riesgos para la salud dependientes de un PC, sería una chapuza.
Del USB se podría decir lo mismo. No vale como sistema fiable de comunicación.
El lazo debería funcionar siempre de forma autónoma, independientemente de que el PC o el USB funcionen o no.

Saludos.
« Última modificación: 19 de Diciembre de 2017, 15:45:26 por Picuino »

Desconectado Galeazzi

  • PIC10
  • *
  • Mensajes: 3
Re:PID, levitador neumático
« Respuesta #4 en: 21 de Diciembre de 2017, 19:49:06 »
Ya quedo, de hecho si estaba mal labview y el codigo de PID estaba excelente, nos pemitio entregar en LCD y con teclado matricial y todos nuestros problemas se resolvieron, aunque en estas breves vacaciones estaré estudiando lab porque no me gustaría arrastrar lo mismo en futuros proyectos, gracias por la ayuda.


 

anything