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

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

Saludos.


Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5421
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: 17764
    • 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.
Un saludo desde Sevilla, España.
Visita MicroPIC                                                                                        ɔ!doɹɔ!ɯ ɐʇ!s!ʌ

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: 5421
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: 5421
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: 5421
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