Autor Tema: velocidad constante en motores DC ante cambios bruscos de carga con PIC...  (Leído 39345 veces)

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

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #60 en: 11 de Febrero de 2012, 09:21:41 »
OK picuino... hare las modificaciones en el codigo de mi programa y comentare resultados  :-/ :-/ :-/

saludos

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #61 en: 11 de Febrero de 2012, 10:33:41 »
Hola amyver.
El programa que he publicado y que estás probando tiene un problema:

oscila mucho

El problema viene de lo siguiente:

   El muestreo back-emf se realiza cada 10ms (100 veces por segundo)
   El motor tiene una constante de tiempo de 10ms.

Como resultado este programa no puede responder suficientemente rápido a las modificaciones de velocidad del motor y da "saltos"

Se recomienda que como mínimo un sistema digital tome muestras 5 o 10 veces más rápido que la constante de tiempo del sistema controlado.
Esto es imposible en este caso porque estaríamos todo el tiempo muestreando y el motor estaría todo el tiempo apagado.


Una solución es controlar el motor con compensación de corriente:
La corriente se puede medir cada 1ms sin apagar el motor y se puede corregir el ciclo PWM para que el motor no oscile.


Otra solución es hacer el control mucho más lento:
con una constante integral KI muy pequeña, por ejemplo cambiando la línea:

212.      Vo = Vref + Integ/64;


El motor responderá lento pero sin 'saltos'.
Te dejo el código modificado:

Código: C
  1. /****************************************************************************
  2.    DC MOTOR SPEED CONTROL
  3.    PICUINO APPLICATION BOARD
  4.    https://sites.google.com/site/picuino
  5.  ****************************************************************************/
  6.  
  7. #include <p18cxxx.h>
  8. #include <stdio.h>
  9.  
  10. #define  FOSC 20000000
  11. #define  BAUD 57600
  12.  
  13.  
  14. #define DCMOT_TRIS_AN0     TRISAbits.TRISA0
  15.  
  16. #define DCMOT_TRIS_ENABLE  TRISCbits.TRISC0
  17. #define DCMOT_ENABLE       LATCbits.LATC0
  18.  
  19. #define DCMOT_TRIS_MOT1    TRISCbits.TRISC1
  20. #define DCMOT_MOT1         LATCbits.LATC1
  21.  
  22. #define DCMOT_TRIS_MOT2    TRISCbits.TRISC2
  23. #define DCMOT_MOT2         LATCbits.LATC2
  24.  
  25.  
  26. /****************************************************************************
  27.       INTERRUPTS
  28.  ****************************************************************************/
  29. #define TMR0_COUNT      (FOSC/((unsigned long)4*4*250*1000))      // Number of carrys per second
  30.  
  31. unsigned char milli_second, sys_clk;
  32.  
  33. void isr_main(void);
  34.  
  35. #pragma code HIGH_INTERRUPT_VECTOR = 0x0008
  36. void High_ISR (void) {
  37.    _asm goto isr_main _endasm
  38. }
  39.  
  40. #pragma interrupt isr_main
  41. void isr_main(void) {
  42.    if (INTCONbits.TMR0IF==1)  {        // if TIMER0 overflow interrupt
  43.       INTCONbits.TMR0IF = 0;           // Clear Timer0 interrupt flag
  44.       TMR0L += 6+3;
  45.       sys_clk--;
  46.       if (sys_clk==0) {
  47.          sys_clk = TMR0_COUNT;
  48.          milli_second++;
  49.       }
  50.    }
  51. }
  52.  
  53.  
  54. /*
  55.    Initialize isr routine and Timer0
  56. */
  57. void isr_init(void) {
  58.    INTCON = 0b11100000;  // Enable interrupts
  59.    T0CON =  0b11000001;  // Prescaler = 4  
  60.    TMR0L = 6+3;
  61.    sys_clk = TMR0_COUNT;
  62.    milli_second = 0;
  63. }
  64.  
  65.  
  66. /****************************************************************************
  67.     ADC FUNCTIONS
  68.  ****************************************************************************/
  69. /*
  70.   Read Analog Input AN0 or AN1
  71. */
  72. unsigned short adc_read(unsigned char channel) {
  73.    union {
  74.       struct {
  75.           unsigned char lob;
  76.           unsigned char hib;
  77.       };
  78.       unsigned short word;
  79.    } adc_val;
  80.  
  81.    // Configure ADC
  82.    ADCON0 = 0b00000001 + (channel<<2);   // ADC on
  83.    ADCON1 = 0b00001101;   // Analog inputs = AN0, AN1
  84.    ADCON2 = 0b10010101;   // TAD
  85.  
  86.    // Make an ADC conversion
  87.    ADCON0bits.GO = 1;        // ADC Hold and Start conversion
  88.    while (ADCON0bits.GO==1); // Conversion
  89.  
  90.    // Configure ADC
  91.    ADCON0 = 0b00000000;   // ADC off
  92.    ADCON1 = 0b00001111;   // All pins to digital inputs
  93.  
  94.    // Return ADC conversion
  95.    adc_val.lob = ADRESL;
  96.    adc_val.hib = ADRESH;
  97.    return adc_val.word;
  98. }
  99.  
  100.  
  101. /****************************************************************************
  102.       RS232 FUNCTIONS
  103.  ****************************************************************************/
  104.  
  105. /*
  106.   Initialize USART for RS232 comunications
  107. */
  108. void rs232_init(void) {
  109.    PIE1bits.TXIE = 0;               // Disable RS232 interrupts
  110.    BAUDCONbits.BRG16 = 0;             // BRG16: 16-Bit Baud Rate Register Enable bit
  111.    SPBRGH = 0;
  112.    SPBRG = (FOSC/(16*BAUD))-1;        // Real Baud = FOSC/(16*(SPBRG+1))
  113.    TXSTA = 0b00100110;
  114.    RCSTA = 0b10010000;
  115.    TRISCbits.TRISC6 = 0;            // Enable TX output
  116. }
  117.  
  118.  
  119. /*
  120.    Send char to USART with pooling
  121. */
  122. int rs232_puts(char *buff, char pos) {
  123.    if (buff[pos] == 0)
  124.       return -1;
  125.    if (PIR1bits.TXIF == 1) {
  126.       TXREG = buff[pos];
  127.       return pos+1;
  128.    }
  129.    else
  130.       return pos;
  131. }
  132.  
  133.  
  134. /****************************************************************************
  135.       PWM FUNCTIONS
  136.  ****************************************************************************/
  137.  
  138. /*
  139.   Sets PWM module
  140.   D = Duty cycle in range 0 .. 1000
  141. */
  142. void pwm1_set(int D) {
  143.    if (D > 1000) D = 1000;
  144.    if (D<0) {
  145.       D = 0;
  146.    }
  147.    DCMOT_MOT1 = 1;
  148.    CCP1CON = 0b00001100;
  149.    if (D & 1) CCP1CON |= (1<<4);
  150.    if (D & 2) CCP1CON |= (1<<5);
  151.    D = D>>2;
  152.    CCPR1L = D;
  153. }
  154.  
  155.  
  156. /*
  157.   Initialize and configure PWM module
  158. */
  159. void pwm1_init(void) {
  160.    T2CON = 0b00000100;    // Timer2 on, prescaler = 1
  161.    PR2 = 250;             // PWM Period = [(PR2) + 1] &#8226; TCY &#8226;(TMR2 Prescale Value)]
  162.  
  163.    DCMOT_MOT1 = 0;
  164.    DCMOT_MOT2 = 0;
  165.    DCMOT_ENABLE = 0;
  166.  
  167.    DCMOT_TRIS_MOT1 = 0;
  168.    DCMOT_TRIS_MOT2 = 0;
  169.    DCMOT_TRIS_ENABLE = 0;
  170. }
  171.  
  172.  
  173. /****************************************************************************
  174.       PID CONTROL
  175.  ****************************************************************************/
  176. #define KP  1.0
  177. #define KI  0.2
  178.  
  179. signed int Vref, Vmot, Err, Err_old, Integ, Vo;
  180.  
  181. void pid_control(void) {
  182.    char sample;
  183.    if (milli_second == 10) {
  184.        milli_second = 0;
  185.    }
  186.  
  187.    //*********************************
  188.    // BACK EMF SENSE
  189.    //*********************************
  190.    while (milli_second == 0) {
  191.       DCMOT_ENABLE = 0;
  192.       sample = 0;
  193.    }
  194.    if (milli_second == 1 && sample == 0) {
  195.       Vmot = adc_read(0);
  196.       DCMOT_ENABLE = 1;
  197.       sample = 1;
  198.    }
  199.  
  200.    //*********************************
  201.    // PID Speed control
  202.    //*********************************
  203.    if (sample==1) {
  204.       sample = 2;
  205.  
  206.       Vref = 20;
  207.  
  208.       Err_old = Err;
  209.       Err = Vref - Vmot;    
  210.       Integ += (Err + Err_old)/2;
  211.       if (Integ>30000) Integ = 30000;
  212.       if (Integ<-30000) Integ = -30000;
  213.  
  214.       Vo = Vref + Integ/128;      //   Err*(int)KP +   ((int)(100.0/KI));
  215.  
  216.       pwm1_set(Vo);
  217.    }
  218. }
  219.  
  220.  
  221. void pid_init() {
  222.    // PID inputs
  223.    CMCON = 0b00000111;
  224.    ADCON1 = 0b00001111;
  225.    DCMOT_TRIS_AN0 = 1;
  226.  
  227.    // PID values
  228.    Err_old = 0;
  229. }
  230.  
  231. /****************************************************************************
  232.       MAIN PROGRAM
  233.  ****************************************************************************/
  234. void main(void) {
  235.    char buff[80], buff_p;
  236.    char send;
  237.  
  238.    //*********************************
  239.    // Initialize
  240.    //*********************************
  241.    rs232_init();
  242.    isr_init();
  243.    pwm1_init();
  244.    pid_init();
  245.  
  246.    fprintf (_H_USART, "\r\nSystem OK.\r\n");
  247.  
  248.    //*********************************
  249.    // DC MOTOR SPEED CONTROL
  250.    //*********************************
  251.    send = 0;
  252.    while(1) {
  253.  
  254.       //*********************************
  255.       // PID control
  256.       //*********************************
  257.       pid_control();
  258.    
  259.       //*********************************
  260.       // Print PID values
  261.       //*********************************
  262.       TRISBbits.TRISB5 = 0;
  263.       if (milli_second==3 && send == 0) {
  264.          sprintf (buff, "Vm=%4d\tInteg=%5d\tVo=%4d\r\n", Vmot, Integ, Vo);
  265.          buff_p = 0;
  266.          send = 1;
  267.       }
  268.       if (send) {
  269.          buff_p = rs232_puts(buff, buff_p);
  270.          if (buff_p == -1)
  271.             send = 0;
  272.       }    
  273.    }
  274. }

Saludos.
« Última modificación: 11 de Febrero de 2012, 16:44:19 por picuino »

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #62 en: 11 de Febrero de 2012, 11:14:06 »
Ok...lo tendre muy encuenta picuino..

saludos... :-/ :-/ :-/

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #63 en: 12 de Febrero de 2012, 09:57:44 »
Código: [Seleccionar]
Estoy probando un método para medir la velocidad del motor y 'obsevar'  como varía la velocidad.

Añadiendo un led al PIC que se encienda durante 1ms cada 10ms se consigue una luz estroboscópica.
Iluminando el eje del motor con la luz se observa el eje del motor "quieto" cuando gira a 6000rpm

Si añadimos al eje motor 3 marcas negras (por ejemplo las 3 pinzas en un motor de taladro), podemos dejarlas "quietas" a 2000rpm

El código es sencillo. He modificado la rutina de interrupción para que encienda un led en el puerto RB5:

[code = c]
      if (sys_clk==0) {
         sys_clk = TMR0_COUNT;
         LATBbits.LATB5 = 1;                        // Luz estroboscópica off
         if (++milli_second == 10) {
            LATBbits.LATB5 = 0;                     // Luz estroboscópica on
            milli_second = 0;
         }
      }


Luego se conecta el led:

                Led          R              | PIC 18F2550
     (+)-----|>|-----[ 220 ]--------| Pin RB5
                  \\                          |

Saludos.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #64 en: 13 de Febrero de 2012, 17:54:35 »
Estoy probando diferentes métodos para medir la intensidad del motor.
La resistencia de sensado de corriente de 0.1 ohmio da una señal muy pequeña, de forma que estoy intentando amplificar su señal sin introducir ruido.

Por otra parte he probado el control de velocidad en varios motores y creo que con algunos el circuito oscila porque la back-emf está llena de ruido.
Las señales de tensión emf y de corriente están llenas de pulsos y oscilaciones debido a la conmutación de las escobillas.
En algunos motores casi no se nota y en otros llega a ser demasiado grande.
Tengo que encontrar alguna técnica para corregir el ruido sin perder precisión y rapidez.


También he encontrado una forma de controlar la corriente cada 1ms a la vez que mantengo las comunicaciones RS232 (imprescindible si quiero saber cómo está funcionando el regulador).
Por ahora lo consigo convirtiendo y enviando los caracteres uno a uno por el rs232 de forma cooperativa con el control de corriente.
Para facilitar las cosas envío los datos en hexadecimal (así la conversión es más rápida)

En cuanto tenga un resultado claro lo posteo.

Saludos.

« Última modificación: 13 de Febrero de 2012, 17:57:05 por picuino »

Desconectado LeugimZerO

  • PIC16
  • ***
  • Mensajes: 112
    • SmaTSoft Electronics
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #65 en: 14 de Febrero de 2012, 20:17:52 »
sigue asi picuino falta poco ya estas cerca  :-/

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #66 en: 22 de Febrero de 2012, 19:14:40 »
He conseguido que el motor gire despacio (30rpm) y que se adapte a los cambios de carga.

El problema está en que hay mucho ruido en el sensado de corriente. Si compenso poco, el motor no responde lo suficiente y si compenso más, el motor responde bien a los cambios de carga pero vibra mucho.

Sigo con ello. Por ahora adjunto el programa con el que voy haciendo pruebas con compensación de corriente.

Código: C
  1. /****************************************************************************
  2.    DC MOTOR SPEED CONTROL
  3.    PICUINO APPLICATION BOARD
  4.    https://sites.google.com/site/picuino
  5.  ****************************************************************************/
  6.  
  7. #include <p18cxxx.h>
  8. #include <stdio.h>
  9.  
  10.  
  11. /****************************************************************************
  12.       HARDWARE DEFINITIONS
  13.  ****************************************************************************/
  14. #define  FOSC 20000000
  15. #define  BAUD 57600
  16.  
  17.  
  18. #define DCMOT_TRIS_AN0     TRISAbits.TRISA0
  19. #define DCMOT_TRIS_AN1     TRISAbits.TRISA1
  20. #define DCMOT_TRIS_AN2     TRISAbits.TRISA2
  21.  
  22. #define DCMOT_TRIS_ENABLE  TRISCbits.TRISC0
  23. #define DCMOT_ENABLE       LATCbits.LATC0
  24.  
  25. #define DCMOT_TRIS_MOT1    TRISCbits.TRISC1
  26. #define DCMOT_MOT1         LATCbits.LATC1
  27.  
  28. #define DCMOT_TRIS_MOT2    TRISCbits.TRISC2
  29. #define DCMOT_MOT2         LATCbits.LATC2
  30.  
  31. #define DCMOT_TRIS_LED1    TRISBbits.TRISB7
  32. #define DCMOT_LED1         LATBbits.LATB7
  33.  
  34.  
  35. /****************************************************************************
  36.       INTERRUPTS
  37.  ****************************************************************************/
  38. #define TMR0_COUNT      (FOSC/((unsigned long)4*4*250*1000))      // Number of carrys per second
  39.  
  40. unsigned char milli_second, sys_clk;
  41.  
  42. void isr_main(void);
  43.  
  44. #pragma code HIGH_INTERRUPT_VECTOR = 0x0008
  45. void High_ISR (void) {
  46.    _asm goto isr_main _endasm
  47. }
  48.  
  49. #pragma interrupt isr_main
  50. void isr_main(void) {
  51.    if (INTCONbits.TMR0IF==1)  {        // if TIMER0 overflow interrupt
  52.       INTCONbits.TMR0IF = 0;           // Clear Timer0 interrupt flag
  53.       TMR0L += 6+3;
  54.       sys_clk--;
  55.       if (sys_clk==0) {
  56.          sys_clk = TMR0_COUNT;
  57.          if (++milli_second == 10) {
  58.             milli_second = 0;
  59.          }
  60.       }
  61.    }
  62. }
  63.  
  64.  
  65. /*
  66.    Initialize isr routine and Timer0
  67. */
  68. void isr_init(void) {
  69.    INTCON = 0b11100000;  // Enable interrupts
  70.    T0CON =  0b11000001;  // Prescaler = 4  
  71.    TMR0L = 6+3;
  72.    sys_clk = TMR0_COUNT;
  73.    milli_second = 0;
  74. }
  75.  
  76.  
  77. /****************************************************************************
  78.     ADC FUNCTIONS
  79.  ****************************************************************************/
  80. /*
  81.   Read Analog Input AN0 or AN1
  82. */
  83. unsigned short adc_read(unsigned char channel) {
  84.    union {
  85.       struct {
  86.           unsigned char lob;
  87.           unsigned char hib;
  88.       };
  89.       unsigned short word;
  90.    } adc_val;
  91.  
  92.    // Configure ADC
  93.    ADCON0 = 0b00000001 + (channel<<2);   // ADC on
  94.    ADCON1 = 0b00001100;   // Analog inputs = AN0, AN1, AN2
  95.    ADCON2 = 0b10010101;   // TAD
  96.  
  97.    // Make an ADC conversion
  98.    ADCON0bits.GO = 1;        // ADC Hold and Start conversion
  99.    while (ADCON0bits.GO==1); // Conversion
  100.  
  101.    // Configure ADC
  102.    ADCON0 = 0b00000000;   // ADC off
  103.    ADCON1 = 0b00001111;   // All pins to digital inputs
  104.  
  105.    // Return ADC conversion
  106.    adc_val.lob = ADRESL;
  107.    adc_val.hib = ADRESH;
  108.    return adc_val.word;
  109. }
  110.  
  111.  
  112. /****************************************************************************
  113.       RS232 FUNCTIONS
  114.  ****************************************************************************/
  115.  
  116. /*
  117.   Initialize USART for RS232 comunications
  118. */
  119. void rs232_init(void) {
  120.    PIE1bits.TXIE = 0;               // Disable RS232 interrupts
  121.    BAUDCONbits.BRG16 = 0;             // BRG16: 16-Bit Baud Rate Register Enable bit
  122.    SPBRGH = 0;
  123.    SPBRG = (FOSC/(16*BAUD))-1;        // Real Baud = FOSC/(16*(SPBRG+1))
  124.    TXSTA = 0b00100110;
  125.    RCSTA = 0b10010000;
  126.    TRISCbits.TRISC6 = 0;            // Enable TX output
  127. }
  128.  
  129.  
  130. /*
  131.    Send char to USART
  132. */
  133. void rs232_putc(char c) {
  134.    TXREG = c;
  135. }
  136.  
  137.  
  138. /*
  139.    Return Hexadecimal value of a nibble
  140. */
  141. char Hexdec(char nibble) {
  142.    nibble &= 0x0F;
  143.    if (nibble>9)
  144.       return ('A'-10) + nibble;
  145.    return '0' + nibble;
  146. }
  147.  
  148.  
  149. /****************************************************************************
  150.       PWM FUNCTIONS
  151.  ****************************************************************************/
  152. /*
  153.   Initialize and configure PWM module
  154.   D = Duty cycle in range 0 .. 200
  155. */
  156. void pwm1_set(int D) {
  157.    if (D > 1000) D = 1000;
  158.    if (D<0) {
  159.       D = 0;
  160.    }
  161.    DCMOT_MOT1 = 1;
  162.    CCP1CON = 0b00001100;
  163.    if (D & 1) CCP1CON |= (1<<4);
  164.    if (D & 2) CCP1CON |= (1<<5);
  165.    D = D>>2;
  166.    CCPR1L = D;
  167. }
  168.  
  169.  
  170. void pwm1_init(void) {
  171.    T2CON = 0b00000100;    // Timer2 on, prescaler = 1
  172.    PR2 = 250;             // PWM Period = [(PR2) + 1] • TCY •(TMR2 Prescale Value)]
  173.  
  174.    DCMOT_MOT1 = 0;
  175.    DCMOT_MOT2 = 0;
  176.    DCMOT_ENABLE = 0;
  177.  
  178.    DCMOT_TRIS_MOT1 = 0;
  179.    DCMOT_TRIS_MOT2 = 0;
  180.    DCMOT_TRIS_ENABLE = 0;
  181. }
  182.  
  183.  
  184. /****************************************************************************
  185.       PID CONTROL
  186.  ****************************************************************************/
  187. #define DCMOT_RM   8        // Motor resistance in ohm
  188. #define DCMOT_RS   100      // I sense resistance in milliohm
  189. #define DCMOT_IMAX 2000     // Max motor current in milliamp
  190. #define VDD        12
  191.  
  192. #define KI          100
  193. #define PWM_STEPS   1000
  194.  
  195. #define INTEG_MAX  30000
  196.  
  197. signed int Vref, Vmot, Err, Err_old, Integ, Vo, Vo2, Imot, Imot_old;
  198.  
  199. void pid_control(void) {
  200.    char sample;
  201.  
  202.    //*********************************
  203.    // BACK EMF SENSE
  204.    //*********************************
  205.    while (milli_second == 0) {
  206.       DCMOT_ENABLE = 0;
  207.       sample = 0;
  208.    }
  209.    if (milli_second == 1 && sample == 0) {
  210.       Vmot = adc_read(0);
  211.       DCMOT_ENABLE = 1;
  212.       sample = 1;
  213.    }
  214.  
  215.    //*********************************
  216.    // PID Speed control
  217.    //*********************************
  218.    if (sample==1) {
  219.       sample = 1;
  220.  
  221.       Vref = adc_read(2)/2;  // External pot
  222.  
  223.       Err = Vref - Vmot;
  224.       Integ += (Err + Err_old)/2;
  225.       Err_old = Err;
  226.       if (Integ>INTEG_MAX) Integ = INTEG_MAX;
  227.       if (Integ<-INTEG_MAX) Integ = -INTEG_MAX;
  228.  
  229.       Vo = Vref + Integ/KI;      // Integral control
  230.    }
  231.  
  232.    //*********************************
  233.    // Current Control
  234.    //*********************************
  235.    Imot = adc_read(1);
  236.    Imot += adc_read(1);        
  237.    Imot = Imot*250/DCMOT_RS;   // Imot in milliamp
  238.    if (Imot > DCMOT_IMAX) {
  239.       DCMOT_LED1 = 1;          // Max current led = 1
  240.       if (Vmot>Vref)
  241.          pwm1_set(Vmot);
  242.       else
  243.          pwm1_set(Vmot + ((long)DCMOT_IMAX*DCMOT_RM*PWM_STEPS/((long)VDD*1000)));
  244.    }
  245.    else {
  246.       DCMOT_LED1 = 0;        
  247.       Vo2 = Vo + (long)Imot*DCMOT_RM*PWM_STEPS/(1000*VDD);
  248.       pwm1_set(Vo2);
  249.    }  
  250.    Imot_old = Imot;
  251. }
  252.  
  253.  
  254. void pid_init() {
  255.    // PID inputs
  256.    CMCON = 0b00000111;
  257.    ADCON1 = 0b00001111;
  258.    DCMOT_TRIS_AN0 = 1;
  259.    DCMOT_TRIS_AN1 = 1;
  260.    DCMOT_TRIS_AN2 = 1;
  261.  
  262.    // PID values
  263.    Integ = 0;
  264.    Err_old = 0;
  265. }
  266.  
  267. /****************************************************************************
  268.       MAIN PROGRAM
  269.  ****************************************************************************/
  270. void main(void) {
  271.    char send;
  272.  
  273.    //*********************************
  274.    // Initialize
  275.    //*********************************
  276.    rs232_init();
  277.    isr_init();
  278.    pwm1_init();
  279.    pid_init();
  280.    TRISB &= 0x0F;
  281.    fprintf (_H_USART, "\r\nSystem OK.\r\n");
  282.  
  283.  
  284.    //*********************************
  285.    // DC MOTOR SPEED CONTROL
  286.    //*********************************
  287.    send = 0;
  288.    while(1) {
  289.  
  290.       //*********************************
  291.       // PID control
  292.       //*********************************
  293.       pid_control();
  294.  
  295.       //continue;
  296.      
  297.       //*********************************
  298.       // Print PID values
  299.       //*********************************
  300.       #define PUTC(A, B) case A: rs232_putc(B); break;
  301.    
  302.       if (PIR1bits.TXIF == 1) {
  303.          LATBbits.LATB6 = 1;
  304.          switch(send++) {
  305.             PUTC(1, '\r')
  306.             PUTC(2, '\n')
  307.             PUTC(3, 'V')
  308.             PUTC(4, 'm')
  309.             PUTC(5, '=')
  310.             PUTC(6, Hexdec(Vmot>>12))
  311.             PUTC(7, Hexdec(Vmot>>8))
  312.             PUTC(8, Hexdec(Vmot>>4))
  313.             PUTC(9, Hexdec(Vmot))
  314.             PUTC(10, '\t')
  315.  
  316.             PUTC(11, 'I')
  317.             PUTC(12, 'm')
  318.             PUTC(13, '=')
  319.             PUTC(14, Hexdec(Imot>>12))
  320.             PUTC(15, Hexdec(Imot>>8))
  321.             PUTC(16, Hexdec(Imot>>4))
  322.             PUTC(17, Hexdec(Imot))
  323.             PUTC(18, '\t')
  324.  
  325.             PUTC(19, 'I')
  326.             PUTC(20, 'n')
  327.             PUTC(21, 't')
  328.             PUTC(22, 'e')
  329.             PUTC(23, 'g')
  330.             PUTC(24, '=')
  331.             PUTC(25, Hexdec(Integ>>12))
  332.             PUTC(26, Hexdec(Integ>>8))
  333.             PUTC(27, Hexdec(Integ>>4))
  334.             PUTC(28, Hexdec(Integ))
  335.             PUTC(29, '\t')
  336.  
  337.             PUTC(30, 'V')
  338.             PUTC(31, 'o')
  339.             PUTC(32, '=')
  340.             PUTC(33, Hexdec(Vo2>>12))
  341.             PUTC(34, Hexdec(Vo2>>8))
  342.             PUTC(35, Hexdec(Vo2>>4))
  343.             PUTC(36, Hexdec(Vo2))
  344.             PUTC(37, '\t')
  345.  
  346.             default: send = 1;
  347.          } //End switch
  348.          LATBbits.LATB6 = 0;
  349.       } //End if
  350.    } //End while
  351.  
  352. }

Saludos.


Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #67 en: 23 de Febrero de 2012, 14:39:09 »
Hoy he probado la compensación de corriente con un circuito analógico (operacional + transistor bipolar) y funciona perfectamente.
Sin embargo, cuando intento realizar el mismo control con el PIC, la corriente comienza a oscilar y no aumenta lo necesario. El motor se para y no regula la velocidad.
No se qué ocurre. Voy a intentar comenzar de cero sólo con compensación de corriente y sin control back-emf para poder ver sólo un efecto y que las formas de onda sean más sencillas. Así podré ver algo con el osciloscopio.

También intentaré cambiar la frecuencia PWM para que no interfiera tanto en las formas de onda de corriente.

Espero que merezca la pena porque llevo muchas horas dedicadas al proyecto y no avanza.
A veces me siento algo desalentado.

Un saludo.

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18271
    • MicroPIC
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #68 en: 23 de Febrero de 2012, 16:43:53 »
Ánimo, picuino, no te desanimos. Los mejores premios vienen tras los mayores esfuerzos.

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #69 en: 23 de Febrero de 2012, 17:05:34 »
Saludos PICUINO..

Estoy seguro que al igual que yo hay muchisimos mas pendientes de este hilo asi que ANIMO!!!! :-/ :-/ :-/ ;-) ;-) ;-) :-/ :-/ :-/

Bueno comentarte tambien que por mi parte sigo avanzando en este proyecto, y hasta ahora ya tengo una respuesta modesta con respecto a la respuesta del motor ante cambios bruscos de carga (Tambien es cierto que el motor si vibra un poco ante distintas cargas,.....y bueno deje este tema aparte para una revision posterior).... bueno me dedique ha ver la parte de la inversion de giro y la toma de lectura...y esto fueron los resultados:

* probe la inversion con distintos componentes por separado y tube al final una buena respuesta..

* tambien fue satisfactorio la toma de lectura de la back-emf tanto en giro Derecho como Izquierdo

Ahora me hallo implementando el programa en el micro para controlar todos los componentes (es decir los controlare via RS-232)

Bueno dejo el esquema con el cual estoy trabajando...

Saludos...

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #70 en: 23 de Febrero de 2012, 18:56:24 »
Muchas gracias por los ánimos Nocturno y amyver. Sigo con ello.

El esquema está fenomenal. Es ingeniosa la solución para utilizar una sola salida PWM para las dos entradas del driver.
De todas formas te recomiendo pasar al PIC16F886. Totalmente compatible con el 16F877 y con 4 salidas PWM. Incluso puede controlar a la vez los 4 transistores de un puente en H.
Habría que plantearse utilizar un puente en H con transistores discretos. Tendríamos más potencia y, total, ya se están utilizando 2 mosfet discretos para llevar a tierra la tensión.

La ventaja de un puente en H es la medida de corriente. En el esquema no detallas como medir corriente. A mi me está dando muchos problemas.
El L6203 sólo deja pasar corriente durante el tiempo de ciclo de trabajo, con lo que la forma de la corriente es a pulsos, tiene mucho ruido y es difícil calcular su valor medio.

Me alegro de que te funcione la medida de la back-emf. A mi también me funciona bien, aunque dependiendo del motor tiene más o menos ruido.

Una cosa que no entiendo del esquema es para qué sirve la TensionMux.

Saludos.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #71 en: 23 de Febrero de 2012, 19:21:13 »
Ya sé para qué sirve la tensión mux.
Se me ha ocurrido una solución mejor para el sensado back-emf.

¿Qué te parece si quitas R8 y colocas un divisor de tensión que salga de la unión R3 y R4 ?

El mismo cable serviría para medir tensión positiva o negativa dependiendo del transistor mosfet que lleve a tierra el terminal del motor.
La tensión siempre sería positiva entre 0 y 5 voltios.

Dejo una imagen:



Saludos

« Última modificación: 23 de Febrero de 2012, 19:51:39 por picuino »

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #72 en: 24 de Febrero de 2012, 15:09:18 »
Saludos PICUINO...en hora buena por continuar en este proyecto  :mrgreen: :mrgreen: :mrgreen:

Primeramente y con respecto al circuito para la toma de la Back-emf tanto negativa como positiva me parece genial... ((:-)) ((:-)) ((:-))

Segundo, tambien me parecio una buena alternativa el micro PIC16f887 en lugar del 16F877A, lo buscare en la tiendas de electronica de mi ciudad

Por ultimo  sobre la medida de la corriente, no la estoy realizando (la verdad no le entiendo mucho, asi como tampoco  se influencia en el circuito.. :lol: :lol:)

saludos...
« Última modificación: 24 de Febrero de 2012, 16:29:10 por amyver »

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #73 en: 24 de Febrero de 2012, 16:31:30 »
Bueno tambien aprovecho para consultar una duda acerca del funcionamiento del motor, es la siguiente:

*Sucede que cuando el motor esta funcionando a una velocidad programada con el control Back-emf
  al aplicarle una carga y retirarla rapidamente...el microcontrolador se reinicia o tiene un mal funcionamiento...
  utilizo para energizar todo el circuito un solo trafo con el cual saco todas las tensiones de alimentacion...
  
bueno como podria solucionar este problemilla???  :lol: :lol:

Por ultimo consultar tambien si alguno conoce que micro de 40 pines tiene mas de DOS salidas PWM y mayor memoria que los 16F877A..

saludos

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5878
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #74 en: 24 de Febrero de 2012, 18:45:50 »
No se si puede tener algo que ver, pero aprovecho para comentar un efecto del control de velocidad.

Cuando el puente de potencia intenta frenar al motor (reducir su velocidad) absorbe energía del motor y carga el condensador de alimentación.
Si no se tiene cuidado, el condensador puede llegar a aumentar mucho su velocidad. Para que el controlador pueda frenar al motor hace falta que una resistencia consuma la corriente absorbida del motor.


El 16F886 tiene la misma memoria de programa y tiene 1 pwm con 4 salidas para poder controlar un puente en H.
Si quieres más creo que tendrías que ir a la serie 18F

También puedes intentar optimizar el tamaño del programa (el compilador CC5X no es una maravilla, pero crea código muy compacto y la versión gratuita funciona muy bien)
y se puede simular PWM a baja frecuencia por programa.


Saludos.
« Última modificación: 24 de Febrero de 2012, 18:48:35 por picuino »


 

anything