Autor Tema: velocidad constante en motores DC ante cambios bruscos de carga con PIC...  (Leído 40776 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 #120 en: 14 de Marzo de 2012, 13:18:51 »
Buenas a todos, bueno pues comentarles que logre que el motor funcione decentemente   :mrgreen: :mrgreen: :mrgreen: :mrgreen:

bueno es un poco de codigo adicional por ahi que funciono bastante bien, claro que sin el sensado de corriente, bueno incluyo el codigo abajo.
Código: [Seleccionar]
/****************************************************************************
By: Amyver - Foro TODOPIC
*****VERSION 2_1B*****
Funciones:
*Modulo controlado atravez del interface USART
*Modulo usado CCP1
*El programa controla velocidad de un motor DC
 en dos sentido de giro, con la particularidad
 de mantener la velocidad constante ante cambios bruscos de carga
 
*Se soluciono el problema del reseteo del Micro usando
 amplificadores operacionales configurados como seguidores de voltaje
 dichos amplificadores fueron conectados a las salidas de los pines
 de -CCP1- -Control de Giro- y -Enable-
 ****************************************************************************/
#include <16F877A.h>
#device adc=10             //Definimos un Conversor Analogo/Digital con resolucion de 10 bits
#Fuses XT, NOWDT, NOPROTECT, NOLVP, PUT, BROWNOUT, NOCPD, NOWRT//palabra de configuracion
#Use delay(clock=4000000)  //usando un oscilador de 4MHz
#Use RS232(Baud=9600, Xmit=Pin_C6, Rcv= Pin_C7, Parity=N, Bits=8)

#Use Fast_io(B)
#Use Fast_io(C)

#Byte PortB=0x06
#Byte PortC=0x07

char var;
signed int16 senialError=0;
signed int16 lecturaBackEmf=0,fijarVelocidad=0,valorPWM=0;

int1 flagReversa=0,flagMicroMotor=0;
////////////////////////////////////////////////////////////////////////////////
void incrementarVelocidad()
{
 flagMicroMotor=1;         //bandera de señalizacion de motor ON

 OutPut_High(Pin_C5);      //Habilitamos el driver L6203

 fijarVelocidad+=20;       //incrementamos la velocidad en 300
 
 if(fijarVelocidad>=1000)  //pregutamos si se llego a la velocidad tope hacia adelante
 {
  fijarVelocidad=1000;     //se fija una velocidad tope
 }
printf("\r\n\r\nVelocidad Programada=%Ld\r\n   ",fijarVelocidad);    
}
void cambiarGiroMotor()       //preguntamos si se pulsa el boton reversa en PANEL o PEDAL
{
 flagReversa++;
  
 if(flagReversa)                   //si hay Reversa
 {
  printf("\r\n\r\nGIRO IZQUIERDO MOTOR\r\n   ");
  if(flagMicroMotor==1)            //preguntamos si el MicroMotor esta en funcionamiento
  {
   OutPut_Low(Pin_C5);             //Deshabilitamos el motor (PARADA)
   delay_ms(2000);                 //tiempo prudente para el frenado del motor
   OutPut_High(Pin_C5);            //Habilitamos el motor (GIRO)
    
   set_pwm1_duty((int16)0);        //se inicializa el PWM en Cero      
  }
  OutPut_High(Pin_C4);             //Cambiamos el sentido de giro del Micro Motor
 }
 else
 {
  printf("\r\n\r\nGIRO DERECHA MOTOR\r\n   ");
  if(flagMicroMotor==1)             //preguntamos si el MicroMotor esta en funcionamiento
  {
   OutPut_Low(Pin_C5);              //Deshabilitamos el motor (PARADA)
   delay_ms(2000);                  //tiempo prudente para el frenado del motor
   OutPut_High(Pin_C5);             //Habilitamos el motor (GIRO)
    
   set_pwm1_duty((int16)0);         //se inicializa el PWM en Cero          
  }
  OutPut_Low(Pin_C4);               //Cambiamos el sentido de giro del Micro Motor
 }
}
void pararMotor()                   //Funcion que recudira a cero la velocidad del Auto IR
{
 flagMicroMotor=0;                  //señalizamos motor Apagado

 OutPut_Low(Pin_C5);                //Deshabilitamos el motor (PARADA)
 delay_ms(2500);
 valorPWM=0;                        //actualizamos la variable
 set_pwm1_duty(valorPWM);           //se inicializa el PWM en Cero  
 fijarVelocidad=0;                  //Establecemos la velocidad en cero
 
 printf("\r\n\r\nPARAR MOTOR=%Ld\r\n   ",fijarVelocidad);
}
////////////////////////////////////////////////////////////////////////////////
void verificarRS232()
{
  if(kbhit())
  {                  // Si hay algo pendiente de recibir ...        
   var=getc();
        
   if(var==0x0D)     //preguntamos si se presiono Enter
   {
    incrementarVelocidad();    
   }
   if(var==0x08)     //preguntamos si se presiono retroceso
   {
      cambiarGiroMotor();
   }
   if(var==0x20)     //preguntamos si se presiono retroceso
   {
    pararMotor();
   }
  }
}
void testearBackEmf()
{
 delay_ms(7);         //tiempo que se enviara la señal PWM
  
 OutPut_Low(Pin_C5);   //Enable Motor OFF
 delay_ms(1);          //tiempo de espera para que la señal Back-emf se estabilice
  
 Set_adc_channel(1);   //selecion de canal 0
 delay_us(50);         //Retardo para que se carge la senal analogica
 lecturaBackEmf=read_adc();  //lee el resultado de la convercion y se guarda en nuestra variable de 16bits
 
 printf("\r\nLectura BACK-EMF=%Ld",lecturaBackEmf);
 OutPut_High(Pin_C5);  //Enable Motor ON
}
void ajustarVelocidad()
{
 signed int16 Control_I, KI;
 signed int16 fijarVelocidadAux=0;

 senialError= fijarVelocidad-lecturaBackEmf;
 fijarVelocidadAux=fijarVelocidad;

 printf("\r\nSenial de Error=%Ld",senialError);

 if((fijarVelocidadAux>=0)&&(fijarVelocidadAux<=100))//Estabelecemos una Ganancia alta para bajas velocidades
 {                                                   //para lograr una respuesta Rapida
  KI =10;          // Ganancia integral
 }
 else if((fijarVelocidadAux>100)&&(fijarVelocidadAux<=600))
 {                                                   //para lograr una respuesta Lenta
  KI = 2;         // Ganancia integral
 }
 else
 {
  KI = 1;         // Ganancia integral
 }

 Control_I = (senialError * KI) / 8;
 valorPWM += Control_I;

 if(valorPWM>=1000)
  valorPWM=1000;
 if((valorPWM<20))
  valorPWM=0;
  
 set_pwm1_duty((int16)valorPWM);                  //se inicializa el PWM en Cero  
 printf("\r\n\r\nValor del PWM=%Ld\r\n   ",valorPWM);
}

void main()
{
 Set_Tris_B(0b11111110);
 Set_Tris_C(0b10001011);

 PortB=0x00;                        //limpiamos el puertoB
 PortC=0x00;                        //limpiamos el puertoC

 OutPut_High(Pin_B0);               //senializacion de pic ON

////////////////////////////////////Configuracion de CCPx(PWM)/////////////////////////////////////////////////
 setup_timer_2(T2_DIV_BY_1,249,1); //configuramos el timer2, Prescaler=1,Periodo=249,Postcaler=1
                                   //con lo que se conseguira: T=50us o f=20Khz
                                   //"setup_timer_2(Prescaler,Periodo,Postcaler)"
 setup_CCP1(CCP_PWM);               //Escogemos el modo de trabajo de CCP1, lo escojemos como modulacion por ancho de pulso
//setup_CCP2(CCP_PWM);               //Escogemos el modo de trabajo de CCP2, lo escojemos como modulacion por ancho de pulso
                                    //NOTA.- Tanto para PWM1 y PWM2 el periodo es establecido por el timer2
// set_pwm2_duty((int16)value);     //NOTA2.-la resolucion maxima esta dada por: Tpwm=2´(n) * 1/Fosc
                                    //                                           50us=2´(n) * 1/4´(6)
                                    //                                           2´(n)= 200
                                    //Entonces el maximo valor que podemos cargar a "value" es de 200, con lo que se
                                    //conseguira un ciclo de trabajo de 100%
////////////////////////////////////Configuracion de CAD////////////////////////////////////////////////////
 setup_adc(ADC_CLOCK_INTERNAL);     //Se usara un reloj interno
 Setup_adc_Ports(AN0_AN1_AN3);              //A0
////////////////////////////////////////////////////////////////////////////////////////////////////////////
 set_pwm1_duty((int16)0);         //se inicializa el PWM en

 OutPut_High(Pin_C5);             //Enable Motor ON
 
 printf("\r\nSystem OK.\r\n");    //Sistema en linea y listo para transmitir

 while(true)
 {
  verificarRS232();
  testearBackEmf();
  ajustarVelocidad();
 }
}

Tambien incluyo el archivo de simulacion y el .hex....

Bueno ahora tengo otra inquietud en la cual quisiera un poco de ayuda....es la siguiente:

* Resulta que el motor efectivamente intenta conservar una velocidad constante ante cambios bruscos de carga.....hasta ahi OK..
* Pero como podria implementar una alarma o un pitido que me indique que el motor llego al tope de su fuerza y pararlo para que no se dañe dicho motor???

Bueno sobre este punto estaba pensando usar la lectura de corriente del integrado L6203, pero como dije antes no tengo muy claro su funcionamiento :(  

Saludos....


Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #121 en: 14 de Marzo de 2012, 15:10:02 »
Hola amyver.
Estos días atrás he estado ocupado con el hardware, fabricando una placa con el L6203:

http://sites.google.com/site/picuino/dc_motor_regulator

También he estado dando vueltas al circuito de sensado de corriente porque me daba problemas.

El caso es que ahora voy a meterme a fondo con el software y el control.

El sensado de corriente del que me hablas se puede realizar sin resistencia de sensado en el L6203:

   1º   Medir la tensión de alimentación del puente Vdd (midiendo la tensión del motor mientras está conectado a Vdd)

   2º   Calcular la tensión de alimentación al motor  Vmotor
         Vmotor = Vdd · D
         D =  ciclo de trabajo del PWM de 0 a 100%

   3º   Medir la tensión interna del motor Eg o back-emf

   4º   Estimar la corriente que circula por el motor:

         Imotor = (Vmotor - Eg) / Rmotor

         Rmotor =  Resistencia del motor en ohmios


Ejemplo de estimación de la corriente del motor con aritmetica de enteros:
En este caso hay que ajustar las unidades para que entren en un número de 0 a 65536:

Código: [Seleccionar]
   Rmotor = 156;                                 // (Rmotor + Rtransistores) · 10 = (15 + 0.6) · 10 = 156
    Vdd = 950;                                    // Vdd = 950 · 32v / 1023ptos = 29.7 voltios.  Cuando ADC=1023 el puente está a 32 voltios.
    D = 325;                                      // Ciclo de trabajo de 0 a 1000

    Vmotor = (Vdd/4) * (D/4);                    // Vmotor = 19197  = 9.65 voltios
    Eg  = 150;                                   // Eg = 150 · 32v / 1023ptos = 4.69 voltios.
    Vrm  = Vmot - Eg*62;                         // Vrm = 19197 - 9300 = 9897 = 4.96 voltios.  (caída de tensión en la resistencia del motor)
    Imotor = (Vrm / Rmotor)*81/16;              // Imotor = (9897 / 156)*81/16 = 318 = 0.318 Amperios

El último número que multiplica (81) es un factor de conversión para obtener la intensidad del motor en miliamperios. Depende de la aritmetica de enteros utilizada y del divisor de tensión del puente. Quizá lo más práctico es afinar ese número midiendo con un polímetro la corriente por el motor y ajustando hasta que Imotor coincida con el polímetro.

También se puede sustituir la ecuación por un valor de Rmotor ajustado:

    Imotor = (Vrm / Rmotor);         (en este caso Rmotor debe valer 31 y no se parece en nada a la verdadera resistencia del motor)

Saludos.
« Última modificación: 14 de Marzo de 2012, 16:09:33 por picuino »

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #122 en: 21 de Marzo de 2012, 11:10:03 »
Hola PICUINO...

Aqui a la espera de tus avances....seguro nos sorprenderas :-/ :-/ :-/ :-/

Saludos...

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #123 en: 21 de Marzo de 2012, 11:23:14 »
Hola amyver,
Estos días he estado fuera y un poco ocupado, de manera que no me he puesto con el control del motor.
Este fin de semana estoy pensando en dedicarle unas horas y terminar algo que se pueda presentar.

Estoy poniendo en marcha también una placa de desarrollo con un dsPIC que creo que será perfecta para controlar motores y experimentar.
El micro tiene conversor ADC con un millón de muestras por segundo  :shock: y módulo DSP con el que se puede hacer simulación e identificación de sistemas en tiempo real (para control avanzado).

También estoy pensando cómo se podría identificar la resistencia del motor para no tener que meterla como parámetro y que el controlador se adapte después de cada reset al motor que esté conectado en cada momento. No consigo encontrar una solución sin utilizar el sensor de corriente.

Se me ha ocurrido también otra forma de rectificar la señal de pico de la resistencia sensora de corriente. Es muy sencilla, sin amplificadores operacionales, y podrías ponerla en marcha en tu proyecto.

Mientras tanteo si quieres te puedo echar una mano con el limitador de corriente para tu motor.

Un saludo.
« Última modificación: 21 de Marzo de 2012, 11:28:01 por picuino »

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #124 en: 21 de Marzo de 2012, 11:38:41 »
Magnifico PICUINO, todas las ideas que tienes superan por mucho las que se me ocurren a mi  ((:-)) ((:-)) ((:-)) ((:-))

y si... porfa dame una mano con el limitador de corriente para mi motor. :)

saludos..

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #125 en: 21 de Marzo de 2012, 11:46:05 »
Bien puedes empezar midiendo la tensión del puente con el PIC.

¿Cómo es el esquema que utilizas?

¿Cuantos puntos mide tu ADC cuando mides tensión mientras el puente está conectado?

Puedes conectar el puente durante 20us (Enable = 1)
comenzar la conversión ADC
Desconectar el puente (Enable = 0)
Leer la conversión ADC cuando termine.


Saludos.

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #126 en: 21 de Marzo de 2012, 12:53:31 »
Hola picuino, bueno con respecto al punto
Citar
Bien puedes empezar midiendo la tensión del puente con el PIC.

Te refieres a la medida de tension luego del divisor de  tension con resistencias que puse en mi esquema???



y sobre el esquema que utilizo, quieres decir el esquema para la toma de corriente????
bueno si es asi, por el momento no hago ninguna lectura de corriente...

y sobre:
Citar
¿Cuantos puntos mide tu ADC cuando mides tensión mientras el puente está conectado?

Código: [Seleccionar]
void testearBackEmf()
{
 delay_ms(10);         //tiempo que se enviara la señal PWM
 
 OutPut_Low(Pin_C3);   //Enable Motor OFF
 delay_ms(1);          //tiempo de espera para que la señal Back-emf se estabilice
 
 Set_adc_channel(0);   //selecion de canal 0
 delay_us(50);         //Retardo para que se carge la senal analogica
 lecturaBackEmf=read_adc();  //lee el resultado de la convercion y se guarda en nuestra variable de 16bits
 
 OutPut_High(Pin_C3);  //Enable Motor ON
}

Voy llamando a la funcion de manera continua, pero solo hago el control cuando el usuario asi lo requiera (cuando el usuario pulsa un pulsador)

y sobre.
Citar
Puedes conectar el puente durante 20us (Enable = 1)
comenzar la conversión ADC
Desconectar el puente (Enable = 0)
Leer la conversión ADC cuando termine.

armare el circuito y te comentare resultados...

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #127 en: 21 de Marzo de 2012, 17:43:50 »
Si, me refiero a leer la entrada Analog cuando el puente está conectado:

Código: [Seleccionar]
signed int16 Analog;

void ADC_Analog_read(void)
{
   // Conectar el puente
   Set_adc_channel(0);               // selecion de canal 0
   set_pwm1_duty((int16)1001);  // PWM siempre a uno
   OutPut_High(Pin_C3);             // Enable Motor ON

   // Medir el valor de tensión
   delay_us(5);                          // Retardo para que se carge la senial analogica
   Analog = read_adc();             // Lee el resultado de la conversion y se guarda en nuestra variable de 16bits 


   // Dejar el puente en los valores originales
   OutPut_LowHigh(Pin_C3);       // Enable Motor OFF
   set_pwm1_duty((int16)valorPWM);
}


Saludos

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #128 en: 26 de Marzo de 2012, 10:22:37 »
Estoy haciendo los cambios en el programa para controlar la corriente a partir de la back-emf
Me está llevando más trabajo del que pensaba.
Como tenía problemas para interpretar los valores enteros, he modificado el programa para que utilice números en coma flotante.

También he tenido que modificar el esquema eléctrico y reducir el condensador C8 para que la medida de tensión varíe con rapidez. En caso contrario había que conectar la alimentación durante mucho tiempo para medir la tensión del puente y la corriente por el motor subía demasiado.

Cuando tenga resultados los posteo.

Saludos.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #129 en: 28 de Marzo de 2012, 15:40:21 »
Bueno, por fin solucioné el problema que tenía con la detección de corriente. Si hubiese un smiley sudando lo pondría.
Me ha costado bastantes pruebas, pero al final ha merecido la pena.
Cambiando el operacional a un CA3240 el circuito detector de pico de corriente funciona a la perfección.

Es bastante importante que funcione Ok el detector de pico para poder contrastar los resultados de cálculo de corriente por back-emf con la corriente verdadera.

Ahora puedo seguir con las pruebas.

Saludos.

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #130 en: 01 de Abril de 2012, 17:49:04 »
Hola amyver, estoy estudiando el regulador del motor.
Ahora el problema que tengo es el ruido de la señal back-emf.
Si la filtro, la respuesta es lenta y si no la filtro, la respuesta oscila mucho.

Espero tener un controlador dentro de poco y publico el programa.

¿Que tal vas tú con el proyecto?

Saludos.

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #131 en: 02 de Abril de 2012, 10:38:55 »
Hola master PICUINO...  :mrgreen: (espero no te moleste lo de master, lo dije con mucho respeto y admiracion por tus aportes)
En cuanto al ruido de la señal back-emf, trabajando con mi motor era considerable  :angry:, pero me di cuenta que trabajando con el ultimo programa que publique (con el control que me sugeriste) los valores que tomaba de dicha señal mantenian una velocidad en el motor relativamente constante.... :grin:

asi que como funcionaba relativamente bien :laugh: decidi dejarlo en un version 1.0....no quise meterle mas mano hasta que mis conocimientos sobre motores y control superen un poco mas mientras tanto dedicandome a hacer otros proyectos e ir con calma en esto de los motores..

saludos....


Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #132 en: 02 de Abril de 2012, 12:12:50 »
Me alegro de que estés contento con los resultados.
Recuerdo que querías limitar la corriente del motor. Yo estoy detras de ello y ya he conseguido resultados. Cuando lo pula un poco (el problema está en el ruido que ya he comentado) lo publicaré para que lo puedas utilizar.

Si con master te refieres a que has aprendido de mis aportes, me alegro mucho que para eso estamos en el foro.

Un saludo.

Desconectado amyver

  • PIC12
  • **
  • Mensajes: 75
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #133 en: 02 de Abril de 2012, 12:22:42 »
Me alegro de que estés contento con los resultados.
Recuerdo que querías limitar la corriente del motor. Yo estoy detras de ello y ya he conseguido resultados. Cuando lo pula un poco (el problema está en el ruido que ya he comentado) lo publicaré para que lo puedas utilizar.

Si con master te refieres a que has aprendido de mis aportes, me alegro mucho que para eso estamos en el foro.

Un saludo.

Pues si PICUINO, en el foro y con tu ayuda me entere de que existia una Back-Emf, y que existia una forma de controlar la velocidad de un motor ademas de los encoders...

saludos..

Desconectado Picuino

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 5883
    • Picuino
Re: velocidad constante en motores DC ante cambios bruscos de carga con PIC...
« Respuesta #134 en: 02 de Abril de 2012, 14:34:34 »
Hola amyver
Me gustaría ayudarte para que consigas limitar la corriente máxima del motor.

Yo lo he conseguido ya y funciona bien. Si intentas frenar el motor la corriente no sube de 2 amperios, el motor no se quema y la placa tampoco.

Un saludo.
  
« Última modificación: 02 de Abril de 2012, 14:51:21 por Picuino »