TODOPIC

Microcontroladores PIC => * PROYECTOS * => Mensaje iniciado por: pantera en 28 de Septiembre de 2006, 12:10:39

Título: PID DISCRETO.
Publicado por: pantera en 28 de Septiembre de 2006, 12:10:39
Hola compañeros he revisado y hay informacion acerca de PID discretos en el foro. Pero pues me gustaria compartir con ustedes este proyecto que necesito hacer para la materia de control digital

Aqui pondre el progreso del mismo para los interesados

Hoy lo primero que voy a hacer es ir a la escuela y sacar la funcion de transferencia de mi sistema.

Tengo dos sistemas un motor de DC y uno de temperatura. haber cual es el que jala mejor y cual es mas facil de obtener la funcion de transferencia

Título: Re: PID DISCRETO.
Publicado por: LETAL en 29 de Septiembre de 2006, 19:15:33
Hola pantera:

Yo quiero hacer algo muy parecido a lo que tu pretendes, pero programando en basic. De hecho ahora mismo estoy renegando con eso.
Podríamos ayudarnos mutuamente.
Título: Re: PID DISCRETO.
Publicado por: 5GTT en 29 de Septiembre de 2006, 19:37:46
Yo me apunto si se me permite, estoy muy interesado en aprender a implementar un PID y si avanzamos entre varios nos sera mas facil a todos. Podriamos trabajar los que nos apuntemos sobre el sistema que propones.

Lo primero seria disponer de la FDT, dices que tienes la respuesta ante el escalon. Esto me hace suponer que aun no tienes el modelo matematico del sistema.
Podriamos empezar por un primer ajuste mediante metodos experimentales como los de Ziegler-Nichols y cuando obtengamos un modelo matematico serio ya podriamos utilizar otras tecnicas analiticas como las basadas en LDR o de compensacion en frecuencia.

Ya nos contaras que forma tiene esa respuesta al escalon, si se parece a una "S" vamos por buen camino.
Título: Re: PID DISCRETO.
Publicado por: pantera en 30 de Septiembre de 2006, 01:28:56
Hola ya porfin tengo las graficas al escalon. Bueno la respuesta finalmente sera de un motor de DC ahora no tengo el motor ya que esta en el Lab de la escuela. Pero bueno ya le tomare una foto.

El motor en si ya tiene la instrumentacion me parece que tiene un Tacometro. Me entrega la señal en la flecha en DC. Eso es genial, ya que facilitara algo de la electronica.

Aqui pongo las respuesta al escalon del motor, La cual adquiri mediante un osciloscopio el cual cuenta con un modulo de almacenamiento de datos y los transforma a archivos CSV.  Lo cual facilmente se podria implementar con Labview y con un PIC. Pero como cuento con la herramienta lo he hecho asi.
Título: Re: PID DISCRETO.
Publicado por: vszener en 30 de Septiembre de 2006, 09:35:46
Para tu proyecto te servirá las notas que ofrece Microchip para el controlador PID
La AN964 (http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf) (Software PID Control of an Inverted Pendulum Using the PIC16F684)
La AN937 (http://ww1.microchip.com/downloads/en/AppNotes/00937a.pdf) (Implementing a PID Controller Using a PIC18 MCU)

En la página de Microchip podrás encontrar más.


Suerte!!! :wink:
Título: Re: PID DISCRETO.
Publicado por: pantera en 30 de Septiembre de 2006, 23:16:44
Hola  VSZENER gracias por la informacion pero ahora me encuentro analizando la funcion de transferencia.

Título: Re: PID DISCRETO.
Publicado por: 5GTT en 01 de Octubre de 2006, 01:01:13
Como dije podiamos utilizar el modelo de Ziegler-Nichols para obtener una funcion de transferencia aproximada pero util para trabajar sobre ella a partir de su respuesta ante el escalon, dependia esto de si el sistema tenia una salida en forma de S, es decir si se aproxima a un comportamiento sobreamortiguado como se muestra en la imagen.

De lo que se trata este metodo para modelar la planta es en asemejarla a un sistema de primer orden mas un retardo puro.

G(s)=(k/1+sT)*e^sR   siendo el parentesis la FDT de un sistema de primer orden con k la gancia y T la constante de tiempo y la exponecial el retardo, con R el tiempo de ese retardo.

El problema de introducir este retardo puro es que no es lineal y por lo tanto debemos recurri a una aproximacion como la de Padé:

e^sR=(1-s(R/2))/(1+s(R/2))

Aunque a simple vista parzca mucho calculo en realidad el metodo se resuleve graficamente, te pongo la imagen en negro va la señal que has obtenido con el sociloscopio ante el escalon y en rojo la que resulta, solo debes trazar la tangente en el punto de inflexion de la grafica y tomar valores.

(http://img213.imageshack.us/img213/7276/zner1.th.jpg) (http://img213.imageshack.us/my.php?image=zner1.jpg)
Título: Re: PID DISCRETO.
Publicado por: pantera en 04 de Octubre de 2006, 12:25:11
Hola

Pues como ven algo ando atrasado no logro encontrar una funcion de transferencia para mi sistema ya que las constantes del PID las voy a calcular desde MATLAB.

Pero pues ando muy atorado. Sigo intentando metodos pero la ecuacion que saque no se parece en nada a la respuesta del sistema.

Si alguien tiene la amabilidad de ayudarme o tiene algo de experiencia aqui dejo el archivo de excel de la respuesta al escalon para una salida de 5 volts.
Título: Re: PID DISCRETO.
Publicado por: pantera en 04 de Octubre de 2006, 12:28:43
El archivo anterior es extencion TEK00000.CSV pero no me dejaban subirlo asi simplemente hay que presionar f2 y renombrar el archivo con la extencion CSV en excel cuando se este abriendo hay que ponerle en ver todos los archivos y en la pantalla que aparece hay que ponerle que esta separado por una coma asi se podria graficar la señal bien.

Título: Re: PID DISCRETO.
Publicado por: pantera en 05 de Octubre de 2006, 15:28:29
Hola veo que hay unos pocos interesados en mi proyecto.  Pero bueno a lo que venia.

YA TENGO LA FUNCION DE TRANSFERENCIA

Bueno los problemas que tenia respecto al metodo fueron cosa de tontos pero bueno, Antes de empezar a hacer cuentas y toda la cosa tenia que llevar los datos que extraje del osciloscopio ya que como bien se sabe la tranformada de Laplace toma valores iniciales en cero asi que pues realmente estaba mal todo lo que habia hecho.

Puero bueno entonces lo primero era llevar la funcion a cero y de ahi comenzar a analisar.

El metodo que utilice para analizar la funcion lo tengo que reportar asi que nada mas lo termino y lo subo.

por el momento dejo el programa de Matlab que hice para visualizar los datos:

Código: Matlab M
  1. % x,y => Respuesta al escalon limitada en tiempo
  2.  
  3.  
  4. A=4.89;
  5. B=-2.45;
  6. p1=-11.1739965;
  7. C=-(A+B);
  8. p2=-70;
  9.  
  10. K =A*p1*p2
  11.  
  12. t=0:0.001:0.5;
  13. f=A+B*exp(p1*t)+C*exp(p2*t);
  14.  
  15. plot(t,f,'-')
  16. %plot(x,y,'-',t,f,'-')

los vectores x and y simplemente son un copy paste de Excel a Matlab.

y esta es la respuesta final del sistema:

Título: Re: PID DISCRETO.
Publicado por: pantera en 05 de Octubre de 2006, 15:34:15
Respecto al analisis de datos todo sale bien salvo el polo en p2=-70 ya que realmente el que por analisis deveria de salir sale positivo y por analisis basicos del lugar de las raices de un sistema eso es inestabilidad.

Asi con esta problematica realmente la desicion de tomar p2 = -70 fue en base graficar y verificar y pues no creo que sea mucho problema ya que es el polo menos significativo. Tiene que esta mas asi la izquierda del plano s

¿Algun comentario respecto a esto ultimo, me gustaria saber que piensan respecto de esto? :

Pero bueno ya estamos listos para seguir con el programa en el microcontrolador :
EL PID DISCRETO
Título: Re: PID DISCRETO.
Publicado por: pantera en 05 de Octubre de 2006, 15:57:41
ANALISIS DE DATOS EN EXCEL

Hola nose como puedo subir un archivo mas grande de lo que me deja normalmente simpre jalo el URL por medio de yahoo en el GEOCITIES pero tampoco me deja subir el archivo para que de ahi lo puedan descargar pero bueno si alguien quiere la informacion, no hay problema.

¿TEK00002.XLT ?


Título: Re: PID DISCRETO.
Publicado por: maunix en 05 de Octubre de 2006, 16:58:08
ANALISIS DE DATOS EN EXCEL

Hola nose como puedo subir un archivo mas grande de lo que me deja normalmente simpre jalo el URL por medio de yahoo en el GEOCITIES pero tampoco me deja subir el archivo para que de ahi lo puedan descargar pero bueno si alguien quiere la informacion, no hay problema.

¿TEK00002.XLT ?


Comprímelo en formato ZIP, RAR o 7z. 

Sobre todo los 2 primeros, son los más comunes

Título: Re: PID DISCRETO.
Publicado por: pantera en 06 de Octubre de 2006, 01:09:37
si ya intente eso pero el problema es que el archivo es de 372 KB ya en archivo .rar
Título: Re: PID DISCRETO.
Publicado por: Chaly29 en 06 de Octubre de 2006, 01:38:03
Hola pantera, con el WinRar comprimilos y que se separen en 2 archivos menores, estos luego los pones en el foro por separado.

Un saludo.

Atte. CARLOS.
Título: Re: PID DISCRETO.
Publicado por: pantera en 06 de Octubre de 2006, 01:54:27
El principal problema es que es solo un archivo no podria separalo en varios chiquitos, si te refieres a eso, verdad?
Título: Re: PID DISCRETO.
Publicado por: Chaly29 en 06 de Octubre de 2006, 11:31:33
Hola pantera, ya me habia imaguinado que era solo un harchivo, pero el WinRar tiene una función que tu le colocas el tamaño máximo que deseas para los archivos y eso es lo que hace, los divide en tantos archivos sea necesario para no superar el tamaño que as definido. Por lo tanto no importaría que solo sea un archivo el que deseas comprimir.

Un saludo.

Atte. CARLOS.
Título: Re: PID DISCRETO.
Publicado por: pantera en 06 de Octubre de 2006, 15:21:44
PARTE 1 y 2
Título: Re: PID DISCRETO.
Publicado por: pantera en 06 de Octubre de 2006, 15:22:33
Parte 3 y 4
Título: Re: PID DISCRETO.
Publicado por: 5GTT en 06 de Octubre de 2006, 19:33:51
Respecto al analisis de datos todo sale bien salvo el polo en p2=-70 ya que realmente el que por analisis deveria de salir sale positivo y por analisis basicos del lugar de las raices de un sistema eso es inestabilidad.

Asi con esta problematica realmente la desicion de tomar p2 = -70 fue en base graficar y verificar y pues no creo que sea mucho problema ya que es el polo menos significativo. Tiene que esta mas asi la izquierda del plano s

¿Algun comentario respecto a esto ultimo, me gustaria saber que piensan respecto de esto? :

Pero bueno ya estamos listos para seguir con el programa en el microcontrolador :
EL PID DISCRETO


Lo primero, me encantaria ver como has obtenido finalmente la FDT, yo basandome en la señal de respuesta suelo hacer el metodo que comente. Pero si conoces otro me gustaria saberlo a mi tambien. Ha quedado de 10 y sin retardo inical como con mi metodo, asi que me parece muy interesante.

Respecto a lo que comentas del problema con el polo en -70 no entiendo que quieres decir, si el polo esta en el semiplano negativo el sistema es estable, el problema seria que fuera 70. De hecho si el sistema no fuera estable se hubiera visto en la respuesta al escalon ya que no habria sido como la que mostro el osciloscopio.

Saludos.
Título: Re: PID DISCRETO.
Publicado por: pantera en 07 de Octubre de 2006, 00:36:50
ok
 
a lo que me referia con respecto al polo de -70 es que ese lo saque  a prueba y error ya que mediante el metodo que realice este calculo no da un resultado rasonable.

A con respecto al metodo que te cuento, mira necesito hacer un reporte asi que eso no lo dudes. Si voy a explicar como lo hice. Tambien quiero escanear escanear el libro del cual lo saque pero no tengo escaner :(
Título: Re: PID DISCRETO.
Publicado por: pantera en 07 de Octubre de 2006, 19:37:44
Hola este es el motor de DC. El motor ya tiene un tacometro incorporado. Justo ahora voy a crear el  programa el cual priero mida la velocidad del motor.
Título: Re: PID DISCRETO.
Publicado por: pantera en 07 de Octubre de 2006, 21:47:16
Primero para hacer el programa se necesita verificar la linealidad del sensor. Ya que la velocidad de salidad del sistema será la velocidad del motor (RPM).

Donde los datos estan en el archivo, XSL.

Y la respuesta del sistema es la siguiente. Donde se puede observar que el sensor quizas no sea tan lineal. Donde a mi parecer hay algo raro ya que si se ve la relacion lineal. Asi que quizas sea necesario volver a realizar las mediciones para crear el programa en el PIC.
Título: Re: PID DISCRETO.
Publicado por: pantera en 15 de Octubre de 2006, 00:37:39
Hola he estado ya trabajando en el codigo del microcontrolador y hasta el momento ya tengo unas rutinas para un teclado matricial y para la LCD.  El microcontrolador por el canal ADC0 toma la señal del tacometro que tiene el motor.

Microcontrolador:
       Las rutinas programadas hasta el momento son:

       El teclado matricial  4X4 por medio de interrupcion por cambio en el puerto B
       El LCD
       Mide la velocidad por medio del microcontrolador. PIC18F4550.
       PWM para la activar el Motor de DC, por medio de  un MOSFET.

El programa ya se probo  con respecto al patro y esta midiendo bien en un rango de +- 10 %.

El programa contara con las siguientes caracteristicas, por medio de los botones:
Detener el Motor:
Decrementar Kp:
Incrementar Kp:
Establecer Kp:
Decrementar Ki:
Incrementar Ki:
Establecer Ki:
Decrementar Kd:
Incrementar Kd:
Establecer Kd:
Establecer velocidad:
Calibrar Motor DC:
Decrementos 10 RPM:
Incrementos 10 RPM:
Decrementos 100 RPM:
Incrementos 100 RPM:

Velocidad.h

Código: Matlab M
  1. #include <18F4550.h>
  2. #device adc=10
  3.  
  4. #FUSES NOPROTECT
  5. #FUSES PUT
  6. #FUSES NOLVP
  7. #FUSES NOBROWNOUT
  8. #FUSES NOWDT
  9. #FUSES HSPLL
  10. #FUSES NODEBUG
  11. #FUSES PLL3
  12. #FUSES USBDIV
  13. #FUSES CPUDIV1
  14. #FUSES VREGEN
  15.  
  16. #use delay(clock=48000000)
  17.  
  18. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
  19.  
  20. #include <LCD.C>
  21.  
  22. #use fast_io(A)
  23. #use fast_io(B)
  24. #use fast_io(C)
  25.  
  26.  
  27. #byte PUERTOB   = 0xF81
  28. #bit  BEEP      = 0xF83.3
  29.  
  30. byte LSB=0b11111110;
  31. byte tecla,tecla1,tecla2;
  32.  
  33. long  value=0,contB=0;
  34. float Velocidad,Voltaje, Calibracion = 1.4208 ;
  35. int16 Proporcion=1;
  36. float Acomulado=0;
  37.  
  38. Corrimiento(){
  39.         PUERTOB=LSB;
  40.         rotate_left( &LSB, 1);
  41.         if(LSB==0b11101111)
  42.         LSB=0b11111110;
  43.  
  44. }
  45.  
  46. #int_TIMER1
  47. TIMER1_isr(){
  48. Corrimiento();
  49. }
  50.  
  51. Revote(){
  52.         if (tecla!=16){
  53.                 while(tecla1==PUERTOB)
  54.      BEEP=1;
  55.         delay_ms(200);
  56.      BEEP=0;
  57.         }
  58. }
  59.  
  60. Revote2(){
  61.         while(tecla2==PUERTOB)
  62.      BEEP=1;
  63.         delay_ms(200);
  64.      BEEP=0;
  65. }
  66.  
  67. int Entero(){
  68.         tecla=PUERTOB;
  69.         tecla1=PUERTOB;
  70.         switch (tecla) {
  71.           case 0xEE : tecla=15;         break;
  72.           case 0xED : tecla=9 ;              break;
  73.           case 0xEB : tecla=8 ;         break;
  74.           case 0xE7 : tecla=7 ;         break;
  75.           case 0xDE : tecla=14;         break;
  76.           case 0xDD : tecla=6 ;         break;
  77.           case 0xDB : tecla=5 ;         break;
  78.           case 0xD7 : tecla=4 ;         break;
  79.           case 0xBE : tecla=13;         break;
  80.           case 0xBD : tecla=3 ;         break;
  81.           case 0xBB : tecla=2 ;         break;
  82.           case 0xB7 : tecla=1 ;         break;
  83.           case 0x7E : tecla=12;         break;
  84.           case 0x7D : tecla=11;         break;
  85.           case 0x7B : tecla=10;         break;
  86.           case 0x77 : tecla=0 ;         break;
  87.           default       : tecla=16;             break; }
  88.         return tecla;
  89. }
  90.  
  91.  
  92. float Get_Numero( float Actual){
  93.         float decimal=1;
  94.         int     Bandera=0;
  95.  
  96.         Proporcion=1;
  97.         Acomulado=0;
  98.      lcd_gotoxy(1,2);
  99.      printf(lcd_putc,"Actual: %f    ",Actual);
  100.         Revote();
  101.  
  102.         Do{
  103.                 Corrimiento();
  104.                 Entero();
  105.                 delay_ms(50);
  106.         } while(tecla2!=PUERTOB);
  107.         lcd_gotoxy(1,2);
  108.         printf(lcd_putc,"Nuevo: %f             ",Acomulado);
  109.         Revote2()       ;
  110.  
  111.         Do{
  112.  
  113.                 Corrimiento();
  114.                 Entero();
  115.                 delay_ms(50);
  116.  
  117.                 if(tecla==10)
  118.                         Bandera=1;
  119.  
  120.                 if(tecla<10 && Bandera==0){
  121.                         Acomulado = Acomulado*10+tecla;
  122.                         lcd_gotoxy(1,2);
  123.                         printf(lcd_putc,"Nuevo: %f             ",Acomulado);
  124.                         Revote();
  125.                 }
  126.  
  127.           if(tecla<10 && Bandera==1){
  128.                   decimal=decimal*0.1;
  129.                   Acomulado = Acomulado+tecla*decimal;
  130.                   lcd_gotoxy(1,2);
  131.                   printf(lcd_putc,"Nuevo: %f             ",Acomulado);
  132.                   Revote();
  133.           }
  134.  
  135.         } while(tecla2!=PUERTOB);
  136.  
  137.  
  138.         Revote2();
  139.  
  140.         lcd_gotoxy(1,1);
  141.         printf(lcd_putc," \f ");
  142.  
  143.         return Acomulado;
  144. }
  145.  
  146.  
  147. #int_RB
  148. RB_isr(){
  149.         Entero();
  150.         tecla2=tecla1;
  151.  
  152.         lcd_gotoxy(1,1);
  153.         switch (tecla) {
  154.  
  155.                 case 0  :
  156.                         printf(lcd_putc,"Detener el Motor:   ");
  157.                         Revote();
  158.                         break;
  159.  
  160.                 case 1  :
  161.                         printf(lcd_putc,"Decrementar Kp:     ");
  162.                         Revote();
  163.                         break;
  164.  
  165.                 case 2  :
  166.                         printf(lcd_putc,"Incrementar Kp:     ");
  167.                         Revote();
  168.                         break;
  169.  
  170.                 case 3  :
  171.                         printf(lcd_putc,"Establecer Kp:      ");
  172.                         Revote();
  173.                      break;
  174.  
  175.  
  176.                 case 4  :
  177.                         printf(lcd_putc,"Decrementar Ki:     ");
  178.                         Revote();
  179.                         break;
  180.  
  181.                 case 5  :
  182.                         printf(lcd_putc,"Incrementar Ki:     ");
  183.                         Revote();
  184.                         break;
  185.  
  186.                 case 6  :
  187.                         printf(lcd_putc,"Establecer Ki:      ");
  188.                         Revote();
  189.                      break;
  190.  
  191.  
  192.                 case 7  :
  193.                         printf(lcd_putc,"Decrementar Kd:     ");
  194.                         Revote();
  195.                         break;
  196.  
  197.                 case 8  :
  198.                         printf(lcd_putc,"Incrementar Kd:     ");
  199.                         Revote();
  200.                         break;
  201.  
  202.                 case 9  :
  203.                         printf(lcd_putc,"Establecer Kd:      ");
  204.                         Revote();
  205.                      break;
  206.  
  207.                 case 10  :
  208.                         printf(lcd_putc,"Establecer velocidad");
  209.                         Revote();
  210.                break;
  211.  
  212.                 case 11  :
  213.                         printf(lcd_putc,"Calibrar Motor DC:  ");
  214.                         Calibracion=Get_Numero(Calibracion);
  215.  
  216.                         break;
  217.  
  218.                 case 12 :
  219.                         printf(lcd_putc,"Decrementos 10 RPM: ");
  220.                         Revote();
  221.                         break;
  222.  
  223.                 case 13 :
  224.                         printf(lcd_putc,"Incrementos 10 RPM: ");
  225.                         Revote();
  226.                         break;
  227.  
  228.                 case 14 :
  229.                         printf(lcd_putc,"Decrementos 100 RPM:");
  230.                         Revote();
  231.                         break;
  232.  
  233.                 case 15 :
  234.                         printf(lcd_putc,"Incrementos 100 RPM:");
  235.                         Revote();
  236.                      break;
  237.  
  238.                 default   :              ;   break; }
  239.  
  240.  
  241. }
  242.  
  243.  
  244. void inicializar(){
  245.         lcd_init();
  246.  
  247.         set_tris_b(0b11110000);              // Inicializacion del Teclado
  248.         set_tris_c(0x00);
  249.  
  250.         port_b_pullups(TRUE);
  251.         LSB=0b11111110;
  252.         PUERTOB=LSB;
  253.  
  254.         setup_adc_ports(AN0|VSS_VDD);        // Inicializacion del ADC
  255.         setup_adc(ADC_CLOCK_DIV_8);
  256.         set_adc_channel( 0 );
  257.  
  258.         setup_timer_1(T1_INTERNAL|T1_DIV_BY_8);
  259.         setup_timer_3(T3_INTERNAL|T3_DIV_BY_8);
  260.  
  261.         enable_interrupts(INT_TIMER1);
  262.         enable_interrupts(INT_TIMER3);
  263.  
  264.         enable_interrupts(INT_RB);
  265.         EXT_INT_EDGE(1,H_TO_L);
  266.         port_b_pullups(TRUE);
  267.  
  268.         enable_interrupts(GLOBAL);
  269.  
  270.         setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
  271.         setup_timer_2(T2_DIV_BY_16, 127, 1);
  272.  
  273.         //   setup_ccp1(CCP_PWM_FULL_BRIDGE|CCP_SHUTDOWN_AC_L|CCP_SHUTDOWN_BD_L);
  274.  
  275. }

velocidad.c
Código: Matlab M
  1. #include "velocidad.h"
  2.  
  3. #int_TIMER3
  4. TIMER3_isr()
  5. {
  6. //      lcd_gotoxy(1,1);
  7. //      printf(lcd_putc,"Valor del ADC0  %lu     ",value);
  8.  
  9. }
  10.  
  11.  
  12. void main()
  13. {
  14.         inicializar();
  15.  
  16.         while (true){
  17.         value   = read_adc();
  18.         Velocidad       = Calibracion*value;
  19.         Voltaje         = 0.0048828125*value;
  20.  
  21.         lcd_gotoxy(1,1);
  22.         printf(lcd_putc,"Vel : %.3f RPM        \nADC0: %.1f volts        ",Velocidad,Voltaje);
  23.  
  24.      set_pwm1_duty(value);          // This sets the time the pulse is
  25.  
  26.         }
  27. }
Título: Re: PID DISCRETO.
Publicado por: pantera en 15 de Octubre de 2006, 16:49:29
Hola lo que resta es analizar la función del controlador PID. Lo primero que se debe de tener desde mi punto de vista es obtener la función del PID pero en la variable Z posterior de ahí hacer el análisis de la respuesta pero con el programa MATLAB.

Bueno creo que ya he excedido el up load que el servidor me permite pero pues mediante el siguiente enlace se tendrá a un archivo PDF donde se explica la función de transferencia en Z del controlador PID.

Discretización_PID (http://www.geocities.com/jeoart_1982/PID_ITQ.PDF)
Título: Re: PID DISCRETO.
Publicado por: pantera en 15 de Octubre de 2006, 17:02:38
En otro post he subido el esquematico y el proyecto de protel DXP del teclado matricial que estoy utilizando.

Teclado_Matricial (http://www.todopic.com.ar/foros/index.php?topic=14228.0)
Título: Re: PID DISCRETO.
Publicado por: pantera en 17 de Octubre de 2006, 14:25:11
Hola el programa base del Controlador ya esta terminado.

Consiste en general de:

Obtencion del numero entero mediante el teclado matricial
Los datos se despliegan mediante un corrimiento en el LCD ya que no cuento con un LCD muy grande .

velocidad.h
Código: Matlab M
  1. #include <18F4550.h>
  2. #device adc=10
  3.  
  4. #FUSES NOPROTECT
  5. #FUSES PUT
  6. #FUSES NOLVP
  7. #FUSES NOBROWNOUT
  8. #FUSES NOWDT
  9. #FUSES HSPLL
  10. #FUSES NODEBUG
  11. #FUSES PLL3
  12. #FUSES USBDIV
  13. #FUSES CPUDIV1
  14. #FUSES VREGEN
  15.  
  16. #use delay(clock=48000000)
  17.  
  18. #use rs232(baud=9600,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
  19. #priority RB,TIMER3,TIMER1
  20. #include <LCD.C>
  21. #include <string.h>
  22.  
  23.  
  24. #use fast_io(A)
  25. #use fast_io(B)
  26. #use fast_io(C)
  27. #use fast_io(E)
  28.  
  29. #byte PUERTOB   = 0xF81
  30. #bit  BEEP      = 0xF83.3
  31. #bit  BOTON1    = 0xF84.0
  32.  
  33. #opt 11
  34.  
  35.  
  36. byte LSB=0b11111110;
  37. byte tecla,tecla1,tecla2;
  38.  
  39. int8 i,No_Caracter,Array_length,Offset,Prescaler=20,text_array[80];      //Corrimiento
  40.  
  41. int16 Proporcion=1;
  42. long  value=0,contB=0;
  43. float Acomulado=0,Velocidad=500,VelocidadMedida,Voltaje, Calibracion = 1.45 ;
  44. float Kp=0,Ki=0,Kd=0;
  45. float a0,a1,a2;
  46. byte BanderaB;
  47.  
  48. Corrimiento(){
  49.                 PUERTOB=LSB;
  50.                 rotate_left( &LSB, 1);
  51.                 if(LSB==0b11101111)
  52.                 LSB=0b11111110;
  53. }
  54.  
  55. #int_TIMER1
  56. TIMER1_isr(){
  57. Corrimiento();
  58. }
  59.  
  60. #int_TIMER3
  61. TIMER3_isr(){
  62. Prescaler++;
  63. }
  64.  
  65. Revote(){
  66.         if (tecla!=16){
  67.                 while(tecla1==PUERTOB)
  68.                 while(tecla==tecla2);
  69.                 BEEP=1;
  70.                 delay_ms(100);
  71.              BEEP=0;
  72.         }
  73. }
  74.  
  75. int Entero(){
  76.         tecla=PUERTOB;
  77.         tecla1=PUERTOB;
  78.         switch (tecla) {
  79.           case 0xEE : tecla=15;         break;
  80.           case 0xED : tecla=9 ;              break;
  81.           case 0xEB : tecla=8 ;         break;
  82.           case 0xE7 : tecla=7 ;         break;
  83.           case 0xDE : tecla=14;         break;
  84.           case 0xDD : tecla=6 ;         break;
  85.           case 0xDB : tecla=5 ;         break;
  86.           case 0xD7 : tecla=4 ;         break;
  87.           case 0xBE : tecla=13;         break;
  88.           case 0xBD : tecla=3 ;         break;
  89.           case 0xBB : tecla=2 ;         break;
  90.           case 0xB7 : tecla=1 ;         break;
  91.           case 0x7E : tecla=12;         break;
  92.           case 0x7D : tecla=11;         break;
  93.           case 0x7B : tecla=10;         break;
  94.           case 0x77 : tecla=0 ;         break;
  95.           default       : tecla=16;             break; }
  96.         return tecla;
  97. }
  98.  
  99. float Get_Numero( float Actual){
  100.         float Decimal=1;
  101.         int      Bandera=0;
  102.         int      Decimas=1;
  103.  
  104.         Proporcion=1;
  105.         Acomulado=0;
  106.      lcd_gotoxy(1,2);
  107.         if(Actual==0)
  108.              printf(lcd_putc,"Actual: %.0f            ",Actual);
  109.         else
  110.              printf(lcd_putc,"Actual: %f              ",Actual);
  111.         Revote();
  112.         Do{
  113.                 Corrimiento();
  114.                 Entero();
  115.                 delay_ms(40);
  116.                 if(tecla==15)
  117.                 goto FIN1;
  118.         } while(tecla2!=PUERTOB);
  119.  
  120.         lcd_gotoxy(1,2);
  121.         printf(lcd_putc,"Nuevo: %.0f             ",Acomulado);
  122.         Revote();      
  123.  
  124.         Do{
  125.                 Corrimiento();
  126.                 Entero();
  127.                 delay_ms(30);
  128.                 if(tecla==10 && Bandera==0){
  129.                         lcd_gotoxy(1,2);
  130.                         printf(lcd_putc,"Nuevo: %.0f.             ",Acomulado);
  131.                         Bandera=1;
  132.                         Revote();
  133.                 }
  134.                 if(tecla==14){
  135.                         Acomulado=0;
  136.                         lcd_gotoxy(1,2);
  137.                         printf(lcd_putc,"Nuevo: %.0f              ",Acomulado);
  138.                         Bandera=0;
  139.                         Revote();
  140.                 }
  141.                 if(tecla<10 && Bandera==0){
  142.                         Acomulado = Acomulado*10+tecla;
  143.                         lcd_gotoxy(1,2);
  144.                         printf(lcd_putc,"Nuevo: %.0f             ",Acomulado);
  145.                         Revote();
  146.                 }
  147.           if(tecla<10 && Bandera==1 && Decimas<=4){
  148.                   decimal=decimal*0.1;
  149.                   Acomulado = Acomulado+tecla*decimal;
  150.                   lcd_gotoxy(1,2);
  151.                   switch (Decimas) {
  152.                     case 1 : printf(lcd_putc,"Nuevo: %.1f          ",Acomulado);break;
  153.                     case 2 : printf(lcd_putc,"Nuevo: %.2f          ",Acomulado);break;
  154.                     case 3 : printf(lcd_putc,"Nuevo: %.3f          ",Acomulado);break;
  155.                     case 4 : printf(lcd_putc,"Nuevo: %.4f          ",Acomulado);break;
  156.                         }
  157.                         Decimas++;
  158.                   Revote();
  159.                 }
  160.                 if(Decimas>4) goto FIN;
  161.         }while(tecla!=12);
  162.  
  163.         FIN:
  164.                 Revote();      
  165.                 lcd_gotoxy(1,1);
  166.                 printf(lcd_putc," \f ");
  167.                 return Acomulado;
  168.        
  169.         FIN1:
  170.                 Revote();      
  171.                 return Actual;
  172. }
  173.  
  174. Impresion_LCD(){
  175.         lcd_gotoxy(1,1);
  176.         printf(lcd_putc,"Velocidad:%.1f RPM     ",VelocidadMedida);
  177.         if(BOTON1==1)
  178.                 sprintf(text_array,"P:%.2f I:%.2f D:%.2f ",Kp,Ki,Kd);
  179.         if(BOTON1==0){
  180.                 sprintf(text_array,"%.1f_RPM %.3f_volts %lu_Bits ",Velocidad,Voltaje,value);
  181.                 Array_length=strlen(text_array);
  182.                 lcd_gotoxy(1,2);
  183.                 Offset--;
  184.                 for(i=0,No_Caracter=Offset;i<20;i++,No_Caracter++){
  185.                         if(No_Caracter>=Array_length)
  186.                                 No_Caracter=0;
  187.                         lcd_putc(text_array[No_Caracter]);
  188.                 }
  189.                 Offset++;
  190.         }
  191.         if(Prescaler>20){
  192.                 Array_length=strlen(text_array);
  193.                 lcd_gotoxy(1,2);
  194.                 Prescaler=0;
  195.                 for(i=0,No_Caracter=Offset;i<20;i++,No_Caracter++){
  196.                         if(No_Caracter>=Array_length)
  197.                                 No_Caracter=0;
  198.                         lcd_putc(text_array[No_Caracter]);
  199.                 }
  200.                 Offset++;
  201.                 if(Offset>=Array_length)
  202.                 Offset=0;
  203.         }
  204. }
  205.  
  206.  
  207. #int_RB
  208. RB_isr(){
  209.         Entero();
  210.         tecla2=tecla1;
  211.  
  212.         lcd_gotoxy(1,1);
  213.         switch (tecla) {
  214.                 case 0  :
  215.                      set_pwm1_duty(0);
  216.                         Revote();
  217.                         break;
  218.                 case 1  :
  219.                         Kp-=0.01;
  220.                         BEEP=1;
  221.                         delay_ms(100);
  222.                         break;
  223.                 case 2  :
  224.                         Kp+=0.01;
  225.                         BEEP=1;
  226.                         delay_ms(100);
  227.                         break;
  228.                 case 3  :
  229.                         printf(lcd_putc,"Establecer Kp:      ");
  230.                         Kp=Get_Numero(Kp);
  231.                      break;
  232.                 case 4  :
  233.                         Ki-=0.01;
  234.                         BEEP=1;
  235.                         delay_ms(100);
  236.                         break;
  237.                 case 5  :
  238.                         Ki+=0.01;
  239.                         BEEP=1;
  240.                         delay_ms(100);
  241.                         break;
  242.                 case 6  :
  243.                         printf(lcd_putc,"Establecer Ki:      ");
  244.                         Ki=Get_Numero(Ki);
  245.                      break;
  246.                 case 7  :
  247.                         Kd-=0.01;
  248.                         BEEP=1;
  249.                         delay_ms(100);
  250.                         break;
  251.                 case 8  :
  252.                         Kd+=0.01;
  253.                         BEEP=1;
  254.                         delay_ms(100);
  255.                         break;
  256.                 case 9  :
  257.                         printf(lcd_putc,"Establecer Kd:      ");
  258.                         Kd=Get_Numero(Kd);
  259.                      break;
  260.                 case 10  :
  261.                         printf(lcd_putc,"Establecer velocidad");
  262.                         velocidad=Get_Numero(velocidad);
  263.                break;
  264.                 case 11  :
  265.                         printf(lcd_putc,"Calibrar Motor DC:  ");
  266.                         Calibracion=Get_Numero(Calibracion);
  267.                         break;
  268.                 case 12 :
  269.                         velocidad-=10;
  270.                         BEEP=1;
  271.                         delay_ms(100);
  272.                         break;
  273.                 case 13 :
  274.                         velocidad+=10;
  275.                         BEEP=1;
  276.                         delay_ms(100);
  277.                         break;
  278.                 case 14 :
  279.                   lcd_gotoxy(1,2);
  280.                         velocidad-=100;
  281.                         BEEP=1;
  282.                         delay_ms(100);
  283.                         break;
  284.                 case 15 :
  285.                   lcd_gotoxy(1,2);
  286.                         velocidad+=100;
  287.                         BEEP=1;
  288.                         delay_ms(100);
  289.                         break;
  290.                 default   :              ;   break; }
  291.                 if(velocidad<=0)
  292.                 velocidad=0;           
  293.                 sprintf(text_array,"P:%.2f I:%.2f D:%.2f ",Kp,Ki,Kd);
  294.                 Array_length=strlen(text_array);
  295.                 lcd_gotoxy(1,2);
  296.                 Offset--;
  297.                 for(i=0,No_Caracter=Offset;i<20;i++,No_Caracter++){
  298.                         if(No_Caracter>=Array_length)
  299.                                 No_Caracter=0;
  300.                         lcd_putc(text_array[No_Caracter]);
  301.                 }
  302.                 Offset++;
  303.                 BEEP=0;
  304. }
  305.  
  306.  
  307. void inicializar(){
  308.         lcd_init();
  309.  
  310.         set_tris_b(0b11110000);
  311.         set_tris_c(0b10010001);
  312.         set_tris_e(0xff);
  313.  
  314.         port_b_pullups(TRUE);
  315.         LSB=0b11111110;
  316.         PUERTOB=LSB;
  317.  
  318.         setup_adc_ports(AN0|VSS_VDD);        // Inicializacion del ADC
  319.         setup_adc(ADC_CLOCK_DIV_8);
  320.         set_adc_channel( 0 );
  321.  
  322.         setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
  323.         setup_timer_3(T3_INTERNAL|T3_DIV_BY_8);
  324.  
  325.         enable_interrupts(INT_TIMER1);
  326.         enable_interrupts(INT_TIMER2);
  327.         enable_interrupts(INT_TIMER3);
  328.  
  329.  
  330.  
  331.         enable_interrupts(INT_RB);
  332.         EXT_INT_EDGE(1,H_TO_L);
  333.         port_b_pullups(TRUE);
  334.  
  335.         enable_interrupts(GLOBAL);
  336.  
  337.         setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
  338.         setup_timer_2(T2_DIV_BY_16, 127, 1);   
  339. }

y el programa principal es:
velocidad.c

Código: Matlab M
  1. #include "velocidad.h"
  2.  
  3.  
  4.  
  5. void main()
  6. {
  7.         Impresion_LCD();
  8.         inicializar();
  9.  
  10.         while (true){
  11.                 value            = read_adc();
  12.                 VelocidadMedida = Calibracion*value;
  13.                 Voltaje                  = 0.0048828125*value;
  14.                 Impresion_LCD();
  15.              set_pwm1_duty(value);          // This sets the time the pulse is
  16.         }
  17. }
Título: Re: PID DISCRETO.
Publicado por: pantera en 17 de Octubre de 2006, 14:38:16
Ahora la idea es programar un PWM para cargar la señal de control, u(k).

La bronca es que nose muy bien como pordria hacerle,  la idea que tengo es:

Hechar a jalar el PWM, lo que no entiendo bien es si el PWM comienza en alto o en bajo, lo ideal es que comiense en bajo. Cuando caiga el PWM que active una interrupcion en el timer2, donde programaré los calculos del algoritmo PWM despues de ahi obtener el valor u(k) y cargarlo en el tiempo de trabajo.

Por lo tanto si la señal de control es Cero pues cargo cero al dutu time + La señal de control anterior.

Espero que alguien pueda darme una ayuda en este punto ya que es lo mas importante del tema.

 
Título: Re: PID DISCRETO.
Publicado por: LETAL en 17 de Octubre de 2006, 15:52:53
Suponiendo que cuando las acciones den un resultado igual o menor a 0, asumas como salida 0%.
Entonces simplemente cuando salida sea 0% tu dutycicle será 0 y cuando sea 100% será 255.

Yo en los cálculos lo trabajo en porcentaje por eso en caso de usar pwm debería hacer
(salida en %)*255/100=dutycicle.
Obvio que si haces los cálculos en valor absoluto sería más directa la cosa, solo deberías limitar el valor maximo y mínimo de salida y ese sería tu duty.
Título: Re: PID DISCRETO.
Publicado por: pantera en 17 de Octubre de 2006, 15:57:39
Ok me late tu consejo tomar en cuenta el maximo error y cargarle ese valor al PWM en el duty_cicly ya de ahi para los otros simplemente son proporciones.

Título: Re: PID DISCRETO.
Publicado por: Mario en 17 de Octubre de 2006, 16:22:21
 :x%#%@#%$#@%$$@%$#^ :evil:%^%@%@%$@%$^$^&%@#%@%$  :evil: :x 
Había escrito un montón y adjuntado una imagen y me dice que está lleno el upload o algo asi y me borró todo :5] :5] :5] :5]

No puedes generar una interrupción cuando el PWM caiga. Al parecer la única interrupción se genera cuando PR2=TMR2, y ésto ocurre cuando se produce la totalidad de la frecuencia.
(observa la imagen el PWM en tu manual, donde te dice cada parte de la señal).

Si quieres hacerlo de esa manera (PWM baja) deberás colocar una interrupción externa en la salida del PWM y hacer que se active de alto a bajo (mi recomendación, la única que se me ocurre ahora después de que el #$@$#^%$^%$#%^@#$ servidor me sacara).


Es recomendable que fijes límites, tal y como Letal propone.

Como le mencioné a Letal, yo utilizaré esta información:
http://abrobotics.tripod.com/ControlLaws/singlemotor.htm

Vete hasta lo del PWM, ahí tendrás una idea de lo que se te plantea.


$%%#$@%%$#@$#%#%^$#@$#@%^@%$#@%$@#%^$^%#^%@#^%@#%$@$^%$@#$%@%$#@$#@%$#@%#@%$#@%$ servidor.
Título: Re: PID DISCRETO.
Publicado por: pantera en 17 de Octubre de 2006, 16:32:57
Creo que tengo que desaogar un poco la INFORMACION que tengo posteada .

Título: Re: PID DISCRETO.
Publicado por: Mario en 17 de Octubre de 2006, 16:42:57
 :D
Título: Re: PID DISCRETO.
Publicado por: pantera en 17 de Octubre de 2006, 17:42:20
Hola por el momento necesito aclarar lo del PWM y la interrpcion para general la seña de control u(k)

Creo que seria mejor tratar este tema en el siguiente enlace de los foros:

PWM e Interrupcion en el TIMER2 (http://www.todopic.com.ar/foros/index.php?topic=14366.msg86780#msg86780)
Título: Re: PID DISCRETO.
Publicado por: pantera en 18 de Octubre de 2006, 01:52:25
Gracias Mario me parece muy interesante y objetivo tu consejo. Realmente tienes razon no es necesario que haga una señal de control como lo estoy pensando.

Mañana el plan es:

                     Rezar para que funcione el PWM y la rutina de interrupcion del Timer2. y el MOSFET.

                     Calcular las constantes del PID asi obteniendo los parametros KP, KI, KD ideales.(Con ayuda de MATLAB)

                     Programar la ecuacion de diferencias en el microcontrolador.

                     Probar las constantes PID en el microcontrolador.


Asi que mañana Mario y Letal no los veo mucho. Ya que andaré en el laboratorio de electronica del ITQ.

Desenme Suerte
Título: Re: PID DISCRETO.
Publicado por: Mario en 18 de Octubre de 2006, 03:38:16
Rezar para que funcione el PWM y la rutina de interrupcion del Timer2. y el MOSFET.

 :D


Desenme Suerte

No creo que la necesites. Al parecer tienes todo bajo control  8).


Si no te llegara a funcionar el PWM, revisa esto en la sección de PWM:
http://www.interq.or.jp/japan/se-inoue/e_pic7_4.htm

Y esto, que es el programa que utilizaré para hacer el PWM (está en Basic):
http://www.microengineeringlabs.com/resources/samples/pbp/hardpwm.bas

Espero te salga el proyecto.
Título: Re: PID DISCRETO.
Publicado por: I3iT en 18 de Octubre de 2006, 08:15:12
Hola a to2.

Igual este post antiguo te puede ayudar en algo:
http://www.todopic.com.ar/foros/index.php?topic=5058.0

Suerte !!!  :)

Título: Re: PID DISCRETO.
Publicado por: pantera en 19 de Octubre de 2006, 03:12:25
Hola pues ya fui al laboratorio y pues creo que por el momento el PWM ya jalo chido. Pero con un par de detalles primero que nada ya entendi que onda del PRS que tanto me lamentaba.

Todo esta es esto para la programacion del PWM

Código: Matlab M
  1. #use delay(clock=48000000)
  2.  
  3. #int_TIMER2
  4. TIMER2_isr(){
  5.         set_pwm1_duty(value_del_ADC0);
  6. }
  7.  
  8.      setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
  9.      setup_timer_2(T2_DIV_BY_16, 255, 1);
  10.      //    (1/48000000)*4*16*255= 2.941 KHZ
  11.  
  12.      enable_interrupts(INT_TIMER2);
  13.      enable_interrupts(GLOBAL);


Todo eso funciono a todo dar pero pues entre en un par de problemas existenciales por que primero que  aterrice bien el concepto de los parametros del PWM

Código: Matlab M
  1. setup_timer_2 (mode, period, postscale)

El period es un valor que va de 1 -255

pero la primera vez le puse un 127 y no me funciona a los dies bits de resolucion del PWM, el duty time se llena a 512 bit,  (9 bits, deberian de ser 10).

Pero pues ya despues busque y busque pero pues nada.

Despues ya le programa otro valor period = 255 y ya jalaban los 10 bits.

Pues bueno eso ya esta solucionado ahora sigue masticar la ecuacion de diferencias

Título: Re: PID DISCRETO.
Publicado por: pantera en 19 de Octubre de 2006, 03:32:01
Ahora lo siguiente que hay que tener bien claro (Lo cual aun esta algo nebuloso) los escalamientos del error la señal de control que propongo es:

Código: Matlab M
  1. #int_TIMER2
  2. TIMER2_isr(){
  3.         Retroalimentacion = read_adc()*Calibracion;
  4.         Error_k2 = error_k1;
  5.         Error_k1 = error_k0;   
  6.         Error_k0 = velocidad - Retroalimentacion;
  7.         uk = a0*Error_k0+a1*Error_k1+a2*Error_k2+uk_anterior;
  8.         uk_anterior= uk;
  9.         set_pwm1_duty(uk);
  10. }

Pero pieso que deberia haber de alguna forma escalar el error. Es decir digamos si el motor esta apagado y quiero la velocidad maxima que es de 1400 RPM (aprox) ese seria el error del 100 [Esta es la forma de Letal me suguiere: :)].

Ok entonces deberia multiplicar el error por la proporcion del 100 porciento del error.
Si tengo cero y el setpoint es de 1400 entonces necesito poner 1024 al PWM que jale todo el motor

ahora si quiero solo el 50% de la velocidad es decir 700 por regla de tres entonces. necesito escribir la mitad, 512 Por sentido comun. Por lo tanto

 Valor_Duty_time= 700_RPM  (1024_bits/1400_RPM) ) = 512 =aprox= 700 * 0.7314_bits = 511.98.

ese seria el valor que tendria que escribir al PWM?

Que les parece mi propuesta. Espero ver si responden a esto antes de partir al laboratorio.

Código: Matlab M
  1. #int_TIMER2
  2. TIMER2_isr(){
  3.  
  4.         Retroalimentacion = read_adc()*Calibracion;
  5.         Error_k2 = error_k1;
  6.         Error_k1 = error_k0;   
  7.         Error_k0 = (velocidad - Retroalimentacion)*0.730714;
  8.         uk = a0*Error_k0+a1*Error_k1+a2*Error_k2+uk_anterior;              
  9.         uk_anterior= uk;
  10.                 if(uk=>1024)
  11.                 uk=1024;
  12.  
  13.                 if(uk=<0)
  14.                 uk=0;
  15.                
  16.         set_pwm1_duty(uk);
  17.  
  18. }
Título: Re: PID DISCRETO.
Publicado por: pantera en 19 de Octubre de 2006, 03:38:23
Lo unico que me pregunto que va a programar el compilador y a que son numero flotantes? :s


Hay tengo sueño  :ni)
Título: Re: PID DISCRETO.
Publicado por: Mario en 19 de Octubre de 2006, 04:06:32
Hola.

Si son números flotantes no creo que tengas mayor problema porque lo más seguro es que redondee el programa. Si no lo hace, a la hora de cargar ese valor decimal al registro del µicro quizá sólo cargue el valor entero. Habría que preguntar a las personas que utilizan tu compilador (yo no uso C).

Sobre tu propuesta de control:
Me parece bien sin embargo, creo que no debes colocar el 1024.

Observa esto:

        bits     10      9       8     7    6     5    4   3   2   1
Binario         1       1       1     1     1     1   1   1   1   1
cantidad     512   256   128   64   32   16   8   4   2   1
   TOTAL= 1023

Para 1024 ocupas 11 bits
        bits    11    10      9       8     7    6     5    4   3   2   1
Binario        1      0      0       0      0    0     0   0    0   0   0
cantidad  1024   512   256   128   64   32   16   8   4   2   1

Sería recomendable que observaras eso.


Otra situación:
¿Por qué no revisas si los registros CCPRxL y CCPxCON<5,4> cambian?
Si estás implementando el PWM con alguna instrucción de tu compilador que, como en el caso de PBP te permite 0 (0%), 127 (50%) y 255 (100%) está bien. Pero si quieres mayor resolución, los 10 bits del ancho de pulso, te recomiendo que escribas directamente en los registros.

CCPRxL es el byte de mayor peso y CCPxCON<5,4> son los dos bits de menor peso.
Revisa la dirección que te puse de microengineering labs, quizá te sirva (claro, si quieres 1023 incrementos en lugar de 255).

Ojalá te salga, eres de los pocos que he visto que inician algo y lo terminan (proyecto de escuela).

Muchos quieren que les hagas el trabajo :D

Título: Re: PID DISCRETO.
Publicado por: LETAL en 19 de Octubre de 2006, 09:52:41
Felicitaciones pantera, estas avanzado.

En cuanto a lo del PWM no puedo ayudarte tanto como mario, ya que solo conozco como usarlo en picbasic. Pero te dije lo que estaba seguro que era correcto y te podía servir.
En mi caso pienso usar un dac a la salida.

En cuanto a mi trabajo espero avanzar como tú, pero soy un poco desordenado y trabajo en forma paralela en varios aspectos del trabajo, lo cual a fines de ver funcionar la bestia retrasa el objetivo dinal.

Ya estás cerca.......un último esfuerzo !!!!!!!!!!!

 :-/ :-/ :-)
Título: Re: PID DISCRETO.
Publicado por: pantera en 19 de Octubre de 2006, 10:58:35
Pero como ven lo del error?
Título: Re: PID DISCRETO.
Publicado por: pantera en 19 de Octubre de 2006, 11:20:30
Pus bueno ni modo. Pues ya les platico como me fue en el Laboratorio
Título: Re: PID DISCRETO.
Publicado por: Mario en 19 de Octubre de 2006, 15:17:52
Pantera, creo que ya entendí lo que preguntas..... revisa el tema del PBP en Basic, ahí le contesté algo a Letal.

Sobre lo que comentabas acerca del llenado de 512, es correcto, 512 el el bit 10, por eso te puse la tabla arriba. Recuerda que    (10)   (9) ( 8 )  (7)  (6)  (5)  (4)  (3)  (2)  (1)  (0)
                                         2    = 2    2    2      2      2    2    2     2    2     2


¿Cómo te llamas?

Asi como que "Pantera"... me imagino que te llamas Pancho o algo asi... o te apellidas Rosa. :D
Título: Re: PID DISCRETO.
Publicado por: pantera en 20 de Octubre de 2006, 00:01:22
Hola Mario pues todo fue bueno y todo fue malo.

Malo por que los mosfet se quemaron, era el IRF7410, el problema realmente no es cuando el PWM, a 2.5 Khz, esta al maximo ciclo de trabajo. Ya que ahi el MOSFET no esta dicipando calor. Pero cuando ponemos el motor a un pequeño ciclo de trabajo se comienza a calentar (Tiene su disipador) y el motor se empieza a acelerar. TIPICO. A quien no le ha pasado?

En cuanto a la funcion de tranferencia pues ya tambien es momento de comenzar a analizarla. Lo cual hoy comenzamos pero tubimos unos errores de concideraciones. asi que pienso trabajar en eso parte de la noche.

Ahora otra cosa mas estuve pensando en la parte rutina de atencion del error (TIMER2) y pues esta mal unas consideraciones anteriores o bueno hay que corregir un par de detalles. La primer idea esta bien pero algo que implicitamente esta pensado pero no se esta haciendo es meditar en que el uk es la veriable que se necesita escalar, no el error (Gracias Profe Eulalio).

Código: Matlab M
  1. #int_TIMER2
  2. TIMER2_isr(){
  3.  
  4.         Retroalimentacion = read_adc()*Calibracion;
  5.         Error_k2 = error_k1;
  6.         Error_k1 = error_k0;
  7.         Error_k0 = (velocidad - Retroalimentacion)*0.730714;
  8.         uk = a0*Error_k0+a1*Error_k1+a2*Error_k2+uk_anterior;
  9.         uk_anterior= uk;
  10.  
  11.                 uk=uk*(CALIBRACION_PARA_EL_PWM)
  12.                 if(uk=>1024)
  13.                 uk=1024;
  14.  
  15.                 if(uk=<0)
  16.                 uk=0;
  17.  
  18.         set_pwm1_duty(uk);
  19.  
  20. }

Por lo tanto es ahi donde devemos saber los valores maximo de uk, los cuales van a estar en funcion de las constantes PID. Asi que por eso se necesita comenzar a analizar la funcion de tranferencia que ya se ha calculado y mostrado. Asi consderamos el valor mayor de uk , escalamos y cargamos al PWM.

¿Que les parece todo lo que se realizo hoy?

El plan de mañana es montar el motor ya en el sistema Dinamico (Con carga) ya que los analisis hasta ahorita han sido en analisis Estatico. Haber como queda



Título: Re: PID DISCRETO.
Publicado por: pantera en 20 de Octubre de 2006, 02:00:49
Pues a analizar en MATLAB 6.5 Los venden en cualquier tienda del los tiangis caracteristicos de Mexico. Son tres discos
Uno del programa y los otros discos son ayudas
Título: Re: PID DISCRETO.
Publicado por: Mario en 20 de Octubre de 2006, 03:13:00
Ese es el comentario que se le hacía a Letal en el otro tema.

No importa si tu P es negativo, lo que importa es la exitación total, que es la que debe "escalarse" o acotarse y dicha señal es la que debe ir en el PWM.

Por eso escribí que creí haber entendido tu duda, la cual traté de explicar en el otro tema de PID con PBP.

Es básicamente lo mismo que te dijo tu maestro, regulas la u(k) contigo, allá regulamos la exitación total, que es lo mismo que el término P+I+D que es lo mismo que el cálculo del error por la constante P o I o D.


Lo bueno es que se quemó el material y no el cerebro  :D
Título: Re: PID DISCRETO.
Publicado por: LETAL en 21 de Octubre de 2006, 12:14:35
Hicistes pruebas del controlador en proteus pantera??
Título: Re: PID DISCRETO.
Publicado por: pantera en 21 de Octubre de 2006, 20:21:00
Hola Mario y Letal. Que tal van?

Yo pues lo de los MOSFET lo soluciono hasta el lunes por las tiendas.

Además llevamos a montar el motor con un herrero pensamos acoplarlo a otra polea, por medio de una Banda. La polea estará corriendo sobre un tornillo y vamos a apretar o aflojar la polea con el tornillo, para ejercer la carga.


Estoy ya trabajando en la Discretización de la planta y pues creo que todo va bien. Por el momento ya debo ir buscando las cortantes del controlador solo que todavía me ando peleando un poco con MATLAB. Esperemos las cosas salgan bien y ya las estoy documentando.

LETAL a que  clase de pruebas te refieres? He estado simulando la respuesta pero en MATLAB.
Que clases de pruebas hay en Proteus que me sirvan para lo que he andado haciendo?

¿Suena interesante?
Título: Re: PID DISCRETO.
Publicado por: pantera en 21 de Octubre de 2006, 23:51:39
Estos son algunos LINKs del Programa MATLAB que me han servido un poco:

Laplace (http://ma3.euetib.upc.es/pfc/automatica/Ejemplos/ejemmatlab.htm)

Hola miren esta es la idea, Aqui esta para una frecuencia de muestreo de Ts = 0.01 simplemente baje la frecuencia para que se vea la discretizacion
Título: Re: PID DISCRETO.
Publicado por: Mario en 22 de Octubre de 2006, 01:13:48
Pues yo no he hecho muchos avances, la maestría y el trabajo y la novia y demás situaciones me lo han impedido (avances = 0   :D )


Tengo entendido que puedes simular con un motor de C.C. en proteus (apenas estoy viendo tutoriales).

Si se puede hacer así, creo que pudieras medir la fuerza contraelectromotiz para regular la velocidad; claro que el motor simulado debe presentar esa característica.

Luego que te salga todo, tomas video y demás; en mi correo me dan una página y la voy a usar para µicros, aún no la he echado a volar pero me gustaría incluir tu proyecto ahí :)


Y luego, para colmo de males, mi primo tiene mi PS2 desde hace como un año y ayer me lo trae porque no enciende. Es un "slim" (de los delgados) y al parecer le voló la pista donde conectas la fuente, la pista de voltaje  :(

Quedó una parte de la pista, trataré de soldar para que haga contacto, si no, tendré que cortar la protección y tratar de soldar sobre el cobre (pero tendré que desarmar todo  :()




Título: Re: PID DISCRETO.
Publicado por: pantera en 22 de Octubre de 2006, 13:21:46
Hola en general ya tengo la funcion discreta de la planta, la del controlador PID pero ahora nose bien como debo simular la respuesta del sistema. Como determinar las constantes PID pero en la variable discreta supongo yo que al tener una naturaleza continua deben de ser las mismas, o no ?

Por otro lado alguien sabe alguna herramienta en la cual pudiera analizar el sistema y el controlador. Yo solo conosco el SISOTOOL de MATLAB pero solo me deja variar una ganancia y por lo que he entendido solo sirven para crear compensadores.

Alguien tiene alguna idea?
Título: Re: PID DISCRETO.
Publicado por: LETAL en 22 de Octubre de 2006, 16:48:17
En teoría para diseñar el controlador pid discreto lo primero que debes hacer es identificar la planta experimentalmente. Luego, analizas la respuesta del pid continuo junto con la planta a escalón en matlab.
También sería interesante analizar la respuesta a escalón de las acciones por separado del controlador solo y/o junto con la planta. Otra cosa que me parece útil es analizar la respuesta a una planta tipo 1/s+1 y 1/s+1*s+2, por ejemplo. Más adelante te darás cuenta porque es interesante más allá de uq no sea tu planta.

Después discretizas la estructura pid de tiempo contiuo que usaste, que creo que usaste la del apunte que dejaste en anterior oportunidad(en ese apunte puedes la relación entre las constantes de tiempo continuo y discreto). Una vez obtenida la función discreta analizas la respuesta en matlab de la misma forma que te dije `para el tiempo continuo, y para las misma cttes. , teniendo cuenta la relación del apunte, deberían tener respuesta muy similar.


Luego implementas el algoritmo en el micro, y puedes simular en proteus la respuesta al escalón usando la 1/s+1 y 1/s+1*2s+1 que te dije anteriormente. El proteus tiene unos bloques de transformada de laplace y herraminetas de analisis gráfico.
La repuesta debería ser muy semejante al analisis de matlab.

Por último haces las mismos análisis de respuesta, con la implementación física del pid , y del pid junto con la planta usando una tarjeta de adquisición. Obviamente la respuesta debe asemejarse bastante a la de proteus, que debe también coincidir con la de matlab.


Es decir con matlab analizas el modelado matemático, comn proteus simulas para ver si tu programa es correcto, o sea si  están bien implementadas las ecuaciones y luego pasas a la verificación experimental. La otra opción es pasar directamentre de matlab a experiemntar físicamente.


Otra cosita: recuerda que la forma de un filtro de primer orden pasivo es 1/TS+1 y dos en cascada 1/T1S+1*1/T2S+1, por lo que en la realidad también podrías comparar los resultados con los que obtuviste en la pc.
Título: Re: PID DISCRETO.
Publicado por: pantera en 23 de Octubre de 2006, 01:31:25
Hola LETAL
Código: Matlab M
  1. En teoría para diseñar el controlador pid discreto lo primero que debes hacer es identificar
  2.  la planta experimentalmente. Luego, analizas la respuesta del pid continuo junto con la
  3. planta a escalón en matlab.

LETAL por lo que se no se puede hacer eso que me comentas, No puedes diseñar un control en la variable S y simplemente digitalizarlo e utilizarlo de la misma forma. No es lo mismo tengo un trabajo de un motor de eso y no se puede ya que se toman otra consideraciones diferentes. Y por el hecho de muestrear la señal todo cambia.

Código: Matlab M
  1. También sería interesante analizar la respuesta a escalón de las acciones por separado del
  2. controlador solo y/o junto con la planta. Otra cosa que me parece útil es analizar la
  3. respuesta a una planta tipo  1/s+1 y 1/s+1*s+2, por ejemplo.
  4. Más adelante te darás cuenta porque es interesante más allá de uq no sea tu planta.

Pues si seria interesante pero por falta de tiempo tengo que analizar unicamente en MATLAB encontrar las variables Ki,Kp y Kd para  programarlas en el microcontrolador unicamente de la planta que tengo ademas el rograma proteus casi puede llevarme el mismo tiempo el cual pienso que seria mejor invertir directamente en el Motor. Pero gracias por el consejo, Por cierto que version tienes del proteus.

Por cierto aqui pongo un poco de los avances que tengo en MATLAB y SIMULINK . Ahora necesito ver cuales van hacer las constantes PI, PD y Pk para programarlas en SIMULINK.




Título: Re: PID DISCRETO.
Publicado por: LETAL en 23 de Octubre de 2006, 08:43:42
Por lo que tengo entendido, en cuanto a controladores discretos (sea o no pid), existen metodos de diseño. Uno sería diseñar en S mediante algún método de diseño y luego discrteizar(también hay varias formas distintas de discretizar). La otra variante consiste en utilizar métodos de diseño propios del tiempo discreto, es decir hacer el diseño del controlador desde un principio en Z(también hay varios métodos.)
Según he leído(no pude encontrar donde para mostrarte), es mejor usar un método de diseño discreto directamente que discretizar un controlador en s, pero no significa que no sea una opción (básicamente depende del metodo de discretizacion usado lo bueno de la aproximación) .

En cuanto al PID, vale lo mencionado anteriormente, ya que eso es para todos los controladores discretos.
 En el caso concreto de los pid se suele usan dos algoritmos uno de posicón y otro de velocidad.

Es válida usar algún método de discretización, y tomar consideraciones si hacen falta. 
De hecho el modelado en simulink que haces es una discretización de un controlador PID en S

En cuanto a lo de perder tiempo con proteus, es posible todo depende del apuro, de la metodología de trabajo que te pidan en el instituto y de la disponobilidad del laboratorio.
En mi caso tengo apuro, debo usar el proteus por metología y tengo una disponimilidad muuuuuuy limitada del laboratorio.
Título: Re: PID DISCRETO.
Publicado por: pantera en 27 de Octubre de 2006, 03:27:07
Hola ya tenía un rato atorado en los actuadores.

Nunca  pensé que fuera tan impórtate y determinante estas cosas.

Por que?

Pues bueno la primera cosa que tuvimos que hacer fue opto acoplar, obvio pensaran muchos, Pero la cosa no es tan fácil. Primero que nada por la respuesta que dan a la salida los OPTOS. El diodo interno tarda un poco en prender y tarda mucho más en apagarse. Pues ahí esta el primer retardo. Después va apagándose gradualmente por lo cual tuvimos que poner un comparador, LM311, es lo más apropiado  ya que con los LM741 o TL081 la señal tarda mucho más. Y para colmo por el trabajo efectivo del PWM se queda corto.

Lo que tenemos en el micro y medido son:
Código: Matlab M
  1. setup_ccp1(CCP_PWM);   // Configure CCP1 as a PWM
  2.         setup_timer_2(T2_DIV_BY_16, 255, 1);
  3.                 // (1/48000000)*4*16*255 = 2.941 KHZ
  4.                 // Ts = 1/(2.941 KHZ) =  340 micro segudos

Entonces primera observación tuvimos que buscar y probar varios optos. Ahora no tengo los números, pero finalmente el que hemos decidido todavía tiene un retardo considerable el cual por más que corregimos la comparación no se puede lograr hacer que la señal del PWM sea similar a la del comparador (Por el problema del apagado).

El comparador es importante ya que es necesario trabajar al MOSFET en las zonas correctas en corte y saturación o algo así.

Posteriormente por fin probamos un MOSFET poderoso, IRFP450. El cual pues ya probamos un buen rato y no se ha quemado o fallado. Los cuales fueron algo caros unos 2.5 dólares.

Pues bueno creo que esta semana hemos avanzado algo. Hoy planeamos un plan para antes que programar la rutina del controlador PID probar únicamente un controlador P para ver como responde el sistema en lazo cerrado.

Deséenme suerte el día de mañana al cerrar el lazo.
Título: Re: PID DISCRETO.
Publicado por: Mario en 27 de Octubre de 2006, 18:44:18
Joel, ¿te llegó la información de los motores? ¿cómo determinar la corriente necesaria?
Título: Re: PID DISCRETO.
Publicado por: pantera en 29 de Octubre de 2006, 15:15:59
Hola Mario si me llego la informacion pero ya he solucionado eso, solo que tengo un retardo por parte de los actuadores, como sabes tengo que optoacoplar la potencia del control al meter el optoacoplador tarda un poco en encender el LED interno y tarda mas en apagarse pero pues creo que ya he hecho lo que he podido respecto a eso. Pienso que el control va a compensar eso al final.

Ya tengo rato que no escribia nada

Los avaces que he logrado hasta ahora es por fin  definir la estapa de potencia por medio de un MOSFET bien poderoso quizas muy sobrado. Pero pues bueno ya no ha pasado nada. Ya esta jalando el PWM

Por el momento hemos hecho el plan de programar solo un controlador P de la siguiente forma:

Código: Matlab M
  1. #int_TIMER2
  2. TIMER2_isr(){
  3.  
  4.         Retroalimentacion = read_adc();
  5.         Error_k0 = velocidad - Retroalimentacion;  // velocidad => BITS
  6.         uk = Error_k0*Kp;
  7.         Error=uk;
  8.         set_pwm1_duty(Error);
  9. }

Por fin hemos podido conectar la retroalimentacion como pueden ver.

Por el momento no hemos podido hacer mas ya que se vino el viernes, pero pues el controlador jalo muy bien. Solo que LETAL siempre si habia error negativo en mi motor creo que me falto analizar un poco mas las cosas pero pues ya las vi en el programa del microcontrolador jalando. SI HAY ERROR NEGATIVO.

La unica cosa que se debe hacer el limitar el error a cero cuando sea negativo, al menos voy a tratar eso ademas me suena logico?
Título: Re: PID DISCRETO.
Publicado por: Mario en 29 de Octubre de 2006, 16:22:27
Eso pudiera ser cierto.

Como le comenté a Letal en el otro tema, lo único que sucede cuando es negativo es que la retroalimentación es mayor que la referencia.

Si haces cero tu "error" lo que provocarás es que el motor no funcione, lo cual no es apropiado porque, estarias utilizando un control semi "on-off".

Te sugiero que realices una ecuación (simple regla de 3) en la cual definas tu máximo valor negativo como positivo y ese resultado lo cargues al PWM.

Como se mencionó, si usas 16 bits, estarás usando 15 (16 es el signo); tendrias 32765 incrementos positivos y negativos.
Para el PWM tienes una resolución de 10 bits que es 1023 incrementos.
-32765 es cero en PWM, 0 es 50% en PWM (511), 32765 es 100% (1023).

Lo recomendable es hacer que esos 32765 sean proporcionales a 1023. Con esto "suavisas" la respuesta, caso contrario a como lo quieres hacer de colocar cero en error.

Si tu motor tiene mucha inercia quizá no se observe este fenómeno pero si no es el caso, verás que el motor se para, se prende e incrementa su velocidad, se para cuando sea negativo, se prende cuando sea error positivo, etcétera.

Limitas la vida útil del motor apagándolo y prendiéndolo de esa manera.

Claro que si para tus requerimientos, el utilizar el código de esa manera es suficiente, ni le busques, solo hazlo.

Coméntalo con tus compañeros de equipo ó, simúlalo en Matlab. Coloca varias cantidades en la ecuación que planteas y grafícala. Con una gráfica observarás lo que te digo.

Espero te ayude.

Ando que me lleva la #@$@#!@$@#$%$#!@$%@#$, no he tenido oportunidad de ponerme a fondo a terminar mi PID............. bueno..... si he tenido tiempo pero lo utilizo para dormir  :D
Título: Re: PID DISCRETO.
Publicado por: pantera en 02 de Noviembre de 2006, 01:44:55
Hola perdon por no reportar nada.

El controlador ya esta mario ya esta jalando perfectamente de hecho al ingeniero le latio tanto que quiere que lo metamos de titulacion, estaba muyy contento del comportamiento del PID.

Justo ahora acabo de terminarlo hace un par de horas quedo perfecto.

Por hoy ya estoy muy cansado. los ultimos dias he estado en el laboratorio del amanecer al anochecer. Ni siquiera entre a a ninguna de miss clases (Tambien mis compañeros). Todos los detalles los voy a explicar mario para el espacio que me habias platicado. Y todos los detalles que sean pertinentes comentar Por hoy la estabilidad del Tema llego.

MaÑANA ESPLICO MAS DETALLES.

Título: Re: PID DISCRETO.
Publicado por: Mario en 02 de Noviembre de 2006, 02:23:02
Perfecto.

Luego explicas la opción que tomaste con respecto al PWM. Quiero saber si lo implementaste como te sugerí o hiciste algo diferente.

Es cierto, se puede plantear como tesis. En el Tecnlógico de Mexicali existen 10 opciones; una de ellas es algo relacionado con modélos de investigación o algo así.
Por ser TEC, creo que es lo mismo allá que aquí.

Qué bien que terminaste, justo a tiempo para presentarlo y quitarse de la mente esa materia.
Título: Re: PID DISCRETO.
Publicado por: Mario en 02 de Noviembre de 2006, 03:06:08
Una pregunta que se debió haber hecho desde el principio:
¿Qué compilador en C utilizas?
Título: Re: PID DISCRETO.
Publicado por: pantera en 02 de Noviembre de 2006, 13:37:25
Hola mario el compilador que utilizo es el PICC version 3.249 esta es la ultima version, me parece, ya que las anteriores tienen unos problemas respecto a los tipos de datos long en la impresion del LCD.


Mira por el momento te puedo adelantar la rutina de control.

Código: Matlab M
  1. #int_TIMER2
  2. TIMER2_isr(){
  3.  
  4.         value=read_adc();
  5.  
  6.         Retroalimentacion = value*0.004887585; //retro en volts
  7.  
  8.  
  9.      Error_k0 = Velocidad_Volts - Retroalimentacion;            //Velocidad en Volts y Retro En volts
  10.  
  11.  
  12.         uk = Error_k0*bo+Error_k1*b1+Error_k2*b2+uk_anterior*Anterior;
  13.  
  14.         if(uk<=0){
  15.         uk=0;
  16.         }
  17.      uk_PWM=(long int)uk;
  18.  
  19.     if(uk_PWM>=1023)    uk_PWM=1023;
  20.     if(uk_PWM<=0)        uk_PWM=0;
  21.  
  22.         set_pwm1_duty(uk_PWM);
  23.  
  24. }

Realmente eso fue la ultima programacion en cuanto a los valores de las constantes b0,b1,b2 salieron correspondientemente a la simulacion en MATLAB de la funcion de transferencia.

float b0=8,b1=-8.12,b2=0.386;

Todos estos detalles los voy a comentar en el reporte que tenemos que entregar. El cual pienso subir de la misma forma que subi el anterior.






Título: Re: PID DISCRETO.
Publicado por: Mario en 02 de Noviembre de 2006, 16:58:49
Ooooo.

Si hiciste ese "escalamiento". Que bien que utilizaste los 10 bits del PWM, mejor resolución que los 8 que inicialmente utilizabas.

Te mandé unas fotos y videos de mi tesis pero se me regresó un correo. No sé cuál porque solo se regresa un mensaje que no se pudo entregar, no te dice cuál es.
Título: Re: PID DISCRETO.
Publicado por: pantera en 08 de Noviembre de 2006, 17:01:59
      Hola ya termine el reporte y pues me gustaria saber algo de retroalimentacion.

Control PID (http://us.share.geocities.com/jeoart_1982/PID_PANTERA.pdf)
Título: Re: PID DISCRETO.
Publicado por: Mario en 08 de Noviembre de 2006, 18:29:25
Impresionante  :shock:

Solo tres situaciones:

¿Configuraste el AD para 8 o 10 bits?
Creo que 8 por la configuración; aunque tienes definido un voltaje de conversión como si tomaras los 10 bits.

¿Activaste los 2 módulos de PWM?
Creo que sí; solo ocupas uno.

La última:
En definitiva es material de tesis, solo cuida las faltas de ortografía (tienes muchas).

Que bien que terminaste  :-/.


A seguirle con lo mio  :)

Ya casi salgo del primer periodo de maestría y ese tiempo que se utiliza para ella me vendría muy bien para continuar con todo lo que he dejado.
Título: Re: PID DISCRETO.
Publicado por: Rulo en 08 de Noviembre de 2006, 23:51:34
Citar
   
Hola ya termine el reporte y pues me gustaria saber algo de retroalimentacion.

Reporte de Proyecto PID

       Soy yo, o algo paso con el link????''''


                saludos
Título: Re: PID DISCRETO.
Publicado por: pantera en 09 de Noviembre de 2006, 00:14:59
 Hola Mario .

Siento lo de las faltas de ortografia soy algo malo en eso pero  :-).

Pero mira el ADC si lo configure de 10 bits para mayor resolocion
Código: C++
  1. #Device ADC = 10


Y sip active los dos modulos el modulo CCP1 es el principal para la señal de control UK la otra solo la usaba para cargar el valor del canal ADC0 directo en el Para la realizacion de pruebas cuando pasaba algo irregular en el motor.


Mario como vas tu?

Creo que va hacer algo dificil para ti ya que vas a manejar un motor mas pequeño. Mario Especificamente que es lo que piensas hacer? tienes alguna aplicacion en especial con tus motores ?

He estado revisando el control difuso (Fuzzy) y pienso que es una mejor opcion. Es mas facil y se aprobecha la experiecia del  operador que conoce bien el fenomeno.  Ahora es lo que sigue para mi. Voy a realñizar control difuso con LABVIEW pero no creo proponerlo como proyecto ya que no hay un foro para LABVIEW. Ya que no pienso adquirir los datos por microcontrolador sino por una DAQ de NI.

Y sip creo que hay un problema con el enlace pero a qui esta de nuevo.

http://www.geocities.com/jeoart_1982/PID_ITQ.PDF

Control PID (http://http://www.geocities.com/jeoart_1982/PID_ITQ.PDF)


Título: Re: PID DISCRETO.
Publicado por: pantera en 09 de Noviembre de 2006, 00:17:22
Hola Rulo si hay un problema de link pasa lo mismo con el anterior pero prueba con un copy and paste. y funciona.

Título: Re: PID DISCRETO.
Publicado por: Rulo en 09 de Noviembre de 2006, 00:23:56


         :?  Resuelto


                    Gracias  8), Saludos   :mrgreen:
Título: Re: PID DISCRETO.
Publicado por: Mario en 09 de Noviembre de 2006, 05:47:50
Lo mio es por amor al arte  :D

No tiene fecha de caducidad.

Ya que termine el primer periodo de la maestría me pondré las pilas  :)

Estoy haciendo tarea y revisando exámenes al mismo tiempo  :z)
Título: Re: PID DISCRETO.
Publicado por: Mario en 09 de Noviembre de 2006, 05:56:57
Y a todo esto....... ¿te llegaron las fotos y videos de mi tésis?

No es tan sofisticado como lo tuyo, no hay análisis de frecuencia ni nada por el estilo, solo pura programación y sentido común  :?....... bueno, no mucho sentido común, el estrictamente necesario para no quebrarse la cabeza.
Título: Re: PID DISCRETO.
Publicado por: pantera en 10 de Noviembre de 2006, 14:25:01
Asi ya habia visto tu proyecto y los videos y pues realmente esta muy padre. Y pues creo que funciona totalmente bien. Felicidades por realizar un proyecto de esa indole en Mexico.

Yo ya estoy pronto para solicitar recidencia y espero poder tomar un buen proyecto y espero que me pagen  :-)
Título: Re: PID DISCRETO.
Publicado por: LETAL en 13 de Noviembre de 2006, 14:55:33
Hola a todos.
Volví, estaba con algunocs problemas personales.

Pantera cuando modelaste en simulink: tenes un bloqur con la funcion de transferencia del controlador en Z, y la funcion de la planta que esta en S y forma el bloque a controlar, la pasaste a Z para poder ver la respuesta o el simulink acepta que pongas un bloque en s y otro en Z??
Título: Re: PID DISCRETO.
Publicado por: pantera en 14 de Noviembre de 2006, 12:55:24
Hola Letal pues finalmente el simulink no lo utilice. Ya que no podia simular bien nada. Por otra parte tengo que hacer ahora otro control PID el cual es un control de temperatura y pues espero que quede rapido. Con respecto a la señal de control uk pienso en manejarla de otra forma
Título: Re: PID DISCRETO.
Publicado por: pantera en 18 de Noviembre de 2006, 04:37:52
Hola LETAL como vaz con tu sistema.

El de temperatura que armamos ya esta chido pero tengo una pregunta para ti.

La funcion de tranferencia como la sacaste ya que en este caso las condiciones uniciales no son cero. Que fue lo que hiciste para obtener la funcion de tranferencia
Título: Re: PID DISCRETO.
Publicado por: pantera en 20 de Noviembre de 2006, 23:36:33
Saludos Mario ya armamos otro PID pero ahora de temperatura y ya quedo simplemente ahora estamos sintonizando el PID.

DESCRIPCION DEL SISTEMA:
Consiste en el control de temperatura por medio de un foco y un par de ventiladores.

PROBLEMAS,

Los problemas que tuvimos fue la que letal comentaba.

Para un escalon POSITIVO
Realmente  el concepto del error negativo que Letal comentaba. Si analisamos un escalon positivos estaremos sacando una funcion de tranferencia, con el actuador que es el Foco. En este momento sacarmos la  funcion de tranferencia para el Foco.Pero cuando se encuetre un sobre impulso en ese momento tendran que entrar los ventiladores. Podemos observar que el calentamiento es rapido.

Para un escalon NEGATIVO
Ahora que pasa si damos un escalon negativo (de 50 grados a 30 por decir algo) los ventiladores tendran que entrar pero y comienza a enfriar. Y obviamente no enfria a la misma velocidad a la que enfria lo cual sera un problema por la velocidad de integracion

ANALISIS.

SI comparamos los resultados anteriores a mi parecer se me ocurre que hay dos funciones de transferencia asi que tendriamos que calcular dos controles PID para cuando hay un error negativo y otra para cuando hay un error positivo. SIn embrago la forma dificil que encontramos fue encontrar un equilibrio entre ambos actuadores.

¿Me gustaria saber el comentario de alguien hacerca de esta observacion?


==============================================================================
Título: Re: PID DISCRETO.
Publicado por: pantera en 20 de Noviembre de 2006, 23:47:40
Comparto el codigo

Código: Matlab M
  1. #include <18F4525.h>
  2. #device adc=10
  3. #use delay(clock=32000000)
  4. #use rs232(baud=115200,parity=N,xmit=PIN_C6,rcv=PIN_C7,bits=8)
  5. #include <LCD.C>
  6.  
  7. #FUSES NOWDT                    //No Watch Dog Timer
  8. #FUSES WDT128                   //Watch Dog Timer uses 1:128 Postscale
  9. #FUSES H4                       //High speed osc with HW enabled 4X PLL
  10. #FUSES NOPROTECT                //Code not protected from reading
  11. #FUSES NOIESO                   //Internal External Switch Over mode disabled
  12. #FUSES NOBROWNOUT               //NO Reset when brownout detected
  13. #FUSES BORV21                   //Brownout reset at 2.1V
  14. #FUSES PUT                      //Power Up Timer
  15. #FUSES NOCPD                    //No EE protection
  16. #FUSES NOSTVREN                 //Stack full/underflow will not cause reset
  17. #FUSES NODEBUG                  //No Debug mode for ICD
  18. #FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
  19. #FUSES NOWRT                    //Program memory not write protected
  20. #FUSES NOWRTD                   //Data EEPROM not write protected
  21. #FUSES NOEBTR                   //Memory not protected from table reads
  22. #FUSES NOCPB                    //No Boot Block code protection
  23. #FUSES NOEBTRB                  //Boot block not protected from table reads
  24. #FUSES NOWRTC                   //configuration not registers write protected
  25. #FUSES NOWRTB                   //Boot block not write protected
  26. #FUSES NOFCMEN                          //Fail-safe clock monitor DSIabled
  27. #FUSES NOXINST                          //Extended set extension and Indexed Addressing mode disabled (Legacy mode)
  28. #FUSES NOPBADEN                 //PORTB pins are configured as digital I/O channels on RESET
  29. #FUSES NOLPT1OSC                        //Timer1  configured for high-power operation
  30. #FUSES MCLR                     //Master Clear pin enabled
  31.  
  32.  
  33. #bit     vital  = 0xF82.0
  34. //#bit   fs             = 0xF82.1
  35.  
  36. #bit  boton1    = 0xf81.2
  37. #bit  menos     = 0xf81.4
  38. #bit  mas               = 0xf81.5
  39. #byte port_A    = 0xF80
  40. #byte port_B    = 0xF81
  41. #byte port_C    = 0xF82
  42. #byte port_D    = 0xF83
  43.  
  44. int32   Promedio;
  45. #byte   Promedio      = 0x00F
  46. #byte   Promedio_LOW  = 0x00F
  47. #byte   Promedio_HIGH = 0x010
  48.  
  49.  
  50. int16   control,t=25;
  51.  
  52. int16   PWM_foco;
  53. #byte   PWM_foco      = 0x01f
  54. #byte   PWM_foco_LOW  = 0x01F
  55. #byte   PWM_foco_HIGH = 0x020
  56.  
  57. int32   conteo=0;
  58. float   cal=0.001782991;
  59. float   temperatura,err0=0,err1=0,err2=0;
  60. float   b0=0.0125,b1=-0.0125,b2=0.00059375;
  61. float   setpoint,uk=0;
  62. int32   lectura;
  63.  
  64.  
  65.  
  66. inicializar(){
  67.         setup_adc_ports(AN0|VSS_VREF);
  68.         setup_adc(ADC_CLOCK_INTERNAL);
  69.         set_adc_channel(0);
  70.  
  71.         setup_timer_1(T1_INTERNAL|T1_DIV_BY_4);
  72.         setup_timer_2(T2_DIV_BY_16,255,1);
  73. //      enable_interrupts(INT_TIMER2);
  74.         enable_interrupts(INT_EXT);
  75.         enable_interrupts(GLOBAL);
  76.  
  77.         port_b_pullups(true);
  78.         setup_ccp2(CCP_PWM);
  79.         lcd_init();
  80.  
  81.         set_tris_a(0xff);
  82.         set_tris_b(0xf7);
  83.         set_tris_c(0x90);
  84.         control=0;
  85.         conteo =0;
  86.  
  87. }
  88.  
  89. #int_EXT
  90. void ZCD(){
  91. // SET POINT  ULTIMA GRABACION ===============
  92.         float controlf,controlv;
  93.         setup_ccp1(CCP_COMPARE_CLR_ON_MATCH);
  94.         CCP_1=0;
  95.  
  96.         set_timer1(0);
  97.  
  98.         lectura=read_adc();
  99.         temperatura=lectura*0.178005;
  100.  
  101.         err0=setpoint-temperatura;
  102.        
  103.         uk = uk+err0*b0+err1*b1+err2*b2;
  104.  
  105.         if(uk>5)uk=5;
  106.         else if(uk<-5)uk=-5;
  107.                
  108.         controlf=15000-uk*3000;
  109.  
  110.         if(uk<0)
  111.         controlv=300-uk*144.6;
  112.         else
  113.         controlv=0;
  114.        
  115.         CCP_1=(long int)controlf;
  116.         setup_ccp1(CCP_COMPARE_SET_ON_MATCH);
  117.         set_timer1(0);
  118.         set_pwm2_duty ((long int)controlv);
  119.         err2=err1;
  120.         err1=err0;
  121.        
  122.         }
  123.  
  124. /*
  125. #int_TIMER2
  126. void muestreo(){
  127.         lectura=read_adc();
  128.         promedio=lectura+promedio;
  129.         conteo++;
  130.  
  131.         if (conteo==100){
  132.                 fs=1;
  133.                 promedio=promedio*.01;
  134.                 conteo=0;
  135.                 putc(Promedio_LOW);
  136.                 putc(Promedio_HIGH);
  137.                 PWM_foco=control;
  138.                 putc(PWM_foco_LOW);
  139.                 putc(PWM_foco_HIGH);
  140.                 putc('\n');
  141.                 promedio=0;
  142.                 fs=0;
  143.                 }
  144.         }
  145. */
  146.  
  147. void main() {
  148.         int16 cont=0;
  149.         inicializar();
  150.  
  151.         while(true){
  152.                 lcd_gotoxy(1,1);
  153.                 printf(lcd_putc,"Sp:%lu uk:%.3f          \nFb:%.0f            ",t,uk,temperatura);
  154.                 vital=0;
  155.  
  156.                 if(Boton1){
  157.                 while(Boton1);
  158.                 lcd_gotoxy(1,1);
  159.                 printf(lcd_putc,"Nuevo sp:            ");
  160.                
  161.                 while(!Boton1){
  162.                 lcd_gotoxy(1,2);
  163.                 printf(lcd_putc,"%lu            ",t);
  164.                 cont=0;
  165.  
  166.                         if(menos){
  167.                                 vital=1;
  168.                                 t--;
  169.                                 while(menos && (cont<=65000))
  170.                                         cont++;
  171.                         }
  172.        
  173.                         if(mas){
  174.                                 vital=1;
  175.                                 t++;
  176.                                 while(mas && (cont<=65000))
  177.                                         cont++;
  178.                         }
  179.                 }
  180.                 while(Boton1);
  181.                
  182.                 }
  183.                 setpoint=t;
  184.                
  185.  
  186.  
  187.                 }
  188.         }
Título: Re: PID DISCRETO.
Publicado por: Mario en 21 de Noviembre de 2006, 01:26:21
Muy interesante.



Simplemente no encuentro razón para implementar un PID en un sistema de temperatura. La razón de cambio es muy lenta como para tratar de seguirla con un PID, inclusive con un P.
Por eso, casi nunca (salvo el PDF de parallax) he visto un código de PID para temperatura, simplemente se realiza por histérisis, asignando un máximo y un mínimo (como los termómetros de las refrigeraciones).

Esto es parte de lo que le mencioné a LETAL:
Lo que pides es algo complicado de explicar para mi. He visto que has preguntado en el foro y al parecer necesitas hacer un PID para temperatura. Te mencioné que te fueras a parallax.com y buscaras las descargas  o vete directo aqui:
http://www.parallax.com/html_pages/downloads/siccurriculum/documentation_sic_curriculum.asp#spanish

y baja industrial control. Este PDF tiene un ejemplo de PID para temperatura; aunque es para Basic Stamp, es casi lo mismo.

Revísalo si tienes tiempo, está en BASIC pero es una fuente de información que tiene un PID para temperatura.
Título: Re: PID DISCRETO.
Publicado por: pantera en 21 de Noviembre de 2006, 13:27:27
A gracias mario pero pues creo que con eso que tengo ya esta bien realmente tienes razon de lo de la histeresis. Pero pues creo que esta bien.
Título: Re: PID DISCRETO.
Publicado por: Geo en 23 de Noviembre de 2006, 20:05:34
Qué tal, primero que nada un agradecimiento a pantera por compartir su trabajo y a todos los demás por compartir su conocimiento :).

Ahora, yo tengo que implementar tres controles PID:

El primero ya está casi terminado en cuanto a diseño, tras eso solo me faltará implementar el circuito. La función de transferencia de la fuente no la obtuve yo (ya es conocida la de una topología reductora).

Mi principal problema es el análisis para la obtención de la función de transferencia de las plantas, es algo de lo que de plano no tengo idea :oops: (además de eso ando bastante oxidado por dejar la escuela unos años :P). Me gustaría saber si conocen algún libro/sitio/apunte en el que pueda encontrar información al respecto.

Para sensar el nivel del tanque de agua vamos a utilizar un sistema flotador/potenciómetro, ¿cómo debo proceder para modelar el sistema?

Por último, creo que mejor abro otro post porque no voy a utilizar ningún PIC :P.
Título: Re: PID DISCRETO.
Publicado por: JavierPIC18 en 16 de Julio de 2007, 17:58:38
Bueno spy nuevo en este foro y en el moemento estoy realizando un control PID con un Pic 18f452, estube revisando el foro y me han servido  muchas cosas de el, pero me doy cuenta que no siguieron hablando desde el  año pasado, me gustaria retomer nuevamente el tema, si alguien esta interesado o sabe si se translado el tema a otra sección por favor escriban.

Gracias.
Título: Re: PID DISCRETO.
Publicado por: fa61an en 18 de Agosto de 2007, 13:44:02
Yo tambien quisiera retomar ya que me parece que quedaron cosas sin aclarar, me he leido todos los post y me quedo la duda de como se soluciono cuando el error era negativo. Se que cada bloque de control debe tener una ganancia o un Bias, que en ultimas es una constante que se le sumaria a la salida de la accion de control, ¿ Fue asi como se soluciono el problema del error negativo? y si fue asi como se calculo ese valor de la constante o de lo contrario como lo hiciste.

En algun post de este tema se mencionaba hacer de la funcion de transferencia del control, que si era en Z o S y la forma de la ecuacion en el micro, creo que hay que aclarar que cualquiera que se elija en el microcontrolador se debe usar una ecuacion discreta. Es cierto que en el dominio Z dependiendo de la frecuencia de muestreo la funcion cambia, pero tambien es cierto que debido a las altas frecuencias de muestreo que hoy podemos obtener gracias al avance tecnologico, analizar un sistema en Z ya no es tan necesario, pues con una alta frecuencia de muestreo para el analisis se puede interpretar como un sistema continuo que seria en el dominio de S. Entonces creo que pantera la aplico en Z bueno la pregunta es la frecuencia con se capturo la señal del tacometro como se relaciono con la ecuacion en Diferencias (discreta) del controlador PID, segun veo en ningun momento si le cambias la frecuencia con que se lee esa señal afecte la ecuacion discreta del PID.

Si me contestan publicare mis otras que tengo

Gracias
Título: Re: PID DISCRETO.
Publicado por: Mario en 18 de Agosto de 2007, 17:00:45
Yo tambien quisiera retomar ya que me parece que quedaron cosas sin aclarar, me he leido todos los post y me quedo la duda de como se soluciono cuando el error era negativo. Se que cada bloque de control debe tener una ganancia o un Bias, que en ultimas es una constante que se le sumaria a la salida de la accion de control, ¿ Fue asi como se soluciono el problema del error negativo? y si fue asi como se calculo ese valor de la constante o de lo contrario como lo hiciste.


Quizá te sirvan estos enlaces:
http://www.todopic.com.ar/foros/index.php?topic=14248.0
http://www.todopic.com.ar/foros/index.php?topic=3635.60
http://abrobotics.tripod.com/ControlLaws/singlemotor.htm   <----- Este último te servirá para entender cómo se realizó la acotación negativa

Ya tendré tiempo para enfocarme de lleno a este proyectillo dejado a la mitad.
Título: Re: PID DISCRETO.
Publicado por: fa61an en 18 de Agosto de 2007, 20:42:40
Trate de leer los dos primeros enlace pero no me alcanzo el tiempo, así que el lunes los leo mejor.

De todas maneras lo poco que leí aun no me convence, en resumen lo que entendí que propones es hacer un limite a la salida del PID eso es claro, pero ese limite debería oscilar entre un rango a < x < b , en donde a es un numero negativo y b es numero positivo, se me ocurre a mi opinen.

Ese rango de valores es el que debe limitar la salida de la acción de Control sea P, PI, PD o PID, porque he notado en algunos post que han intentado limitar pero antes de la acción de control, en donde comparan si el valor del error es negativo o positivo, a mi me parece que ahí no debe haber ninguna limitación, la limitación se debe hacer en el resultado que arroje el controlador.

En el caso de un motor DC, de por ejemplo 6 V y se quiera hacer un control para mejorar la respuesta a un escalón se debería hacer lo siguiente, primero hacer un lazo abierto, me explico, fijar un pwm y por medio del sensor que se desee usar, ya sea tacogenerador, encoder, efecto hall.... realizar un sensor Indicador y anotar con dicho ancho de pulso que velocidad se obtiene, y realizar una tabla de por lo menos unos 5 datos, luego hacer el control de lazo cerrado, si por ejemplo (caso hipotético) con un PWM del 80 % obtuve son el sensor indicador 700 rpm del primera paso, y con el lazo cerrado fijo un set point de 700 rpm... es obvio que la salida del controlador debería oscilar entre 80 % de PWM cuando permanezca en estado estable... eso quiere decir que cuando el error sea cero la salida del PID debería  tener un valor de PWM cercano al 80 % y no de un valor de 0 % como han propuesto...


La pregunta que hay que hacerse es como diseño el limitador, que rangos debo ponerle al limitador, se me ocurre que lo adecuado es obtener la función de transferencia, pero todos sabemos que eso aveces es engorroso, y no vayan a decir que usar el metodo de Ziger - nicols para obtener la función de transferencia, porque eso es falso,  el método de Ziger, es cuando no se puede obtener la función de transferencia y se desea realizar un control casi optimo por un metodo experimental hecho por ellos.


Título: Re: PID DISCRETO.
Publicado por: hard8507 en 02 de Mayo de 2009, 13:32:51


aki les pongo una paguina de microchip el cual dan todo para hcer un pendulo invertido

http://ww1.microchip.com/downloads/en/AppNotes/00964A.pdf

y el codigo fuente lo encuentran aki

http://www.microchip.com/stellent/idcplg?IdcService=SS_GET_PAGE&nodeId=1824&appnote=en021807

si alguien lo prueba y nos indica q tal funciona seria mejor
Título: Re: PID DISCRETO.
Publicado por: pantera en 23 de Junio de 2011, 23:04:21
Hola chicos que tal.. en verdad he estado super desaparecido ya egrese de la carrera hace cuatro años actualmente me encuentro trabajando con controloes CNC y la verdad son la neta...

Saludos de mexico
Título: Re: PID DISCRETO.
Publicado por: Mario en 24 de Junio de 2011, 17:23:02
¡qué bueno!  por fin de regreso.


Yo también he andado fuera, espero recuperarme en las lecturas del foro.
Título: Re: PID DISCRETO.
Publicado por: gab163 en 25 de Mayo de 2013, 15:46:32
Hola a todos existe tambien el PID Takagachi-chan-auslander es un controlador pid en forma discreta el cual esta descrito por
Uk=DeltaUk+Uk-1
donde DeltaUk=Kp(yk-1-yk)+KI(refk-yk)+KD(2yk-1-yk-2-yk)

Donde KP, KI y KD son las ganancias del controlador, ref la referencia, yk salida del sistema en ese instante, yk-1 la salida del sistema un instante anterior y yk-2 la salida del sistema dos instantes antes. siendo Uk la entrada de control suministrada al sistema.
 para un controlador PI:

     KP=0.9/(R*(L+(Tm/2)))-1/2*(KI),                       KI=0.27Tm/(R*(L+(T/2))^2)
para un controlador PID:

    KP=1.2/(R*(L+Tm))-1/2*KI,              KI=0.6T/(R*(L+(Tm/2))^2)                   KD=0.6/(R*Tm)

donde Tm es el tiempo de muestreo


donde R=K/T    ,     K es la ganancia del sistema(ojo no es la del controlador) y T (es el tiempo de subida del intervalo mostrado en la imagen)
nota: no confundir T con Tm son diferentes.

(https://www.google.com.mx/search?q=sintonizacion%20ziegler%20nichols&um=1&ie=UTF-8&hl=es-419&tbm=isch&source=og&sa=N&tab=wi&ei=oAKhUd-qIuOU0QG9yoG4Aw&biw=1280&bih=699&sei=pQKhUdStJMf00QHHn4GoAg#facrc=_&imgrc=iNCaNwurmM-AgM%3A%3BvKRQY1E47pRSaM%3Bhttp%253A%252F%252Fwww.scielo.org.co%252Fimg%252Frevistas%252Ftecn%252Fv15n30%252Fv15n30a03fig2.jpg%3Bhttp%253A%252F%252Fwww.scielo.org.co%252Fscielo.php%253Fpid%253DS0123-921X2011000300003%2526script%253Dsci_arttext%3B453%3B205)