Autor Tema: Control motor introduciendo la velocidad!!  (Leído 4769 veces)

0 Usuarios y 2 Visitantes están viendo este tema.

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
Control motor introduciendo la velocidad!!
« en: 21 de Julio de 2004, 03:14:00 »
Buenas gente, haber si podeis ayudarme!!
Deseo generar un duty cycle dependiendo de la velocidad que queremos que gire, es decir, se introduce la velocidad en r.p.m. y se transmite via serie, entonces el PIC generara un PWM dependiendo de esta velocidad, la regla de tres es la siguiente
(velocidad*100)/3900.0=el resultado es el duty cycle que queremos; luego logicamente nos daria una velocidad, que muy dificilmente coincidiria con la deseada, entonces habria que sacar el error y multiplicarlo por una constante y enviar de nuevo otro duty, en funcion del error y la constante (en resumen un lazo Proporcional)!!!
Pero mi primera duda  es la primera, la segunda ya se intentaria solucionr mas adelante!!
 Aqui os mando lo que he hecho, pero no funciona correctamente!!!
Creo que es por alguna definicion de variables, pero si mem pudierais ayudar mejor!!

codigo:

#include <16f873.h>
#device adc=10
#include <stdlib.h>

#fuses XT, NOPROTECT, NOWDT, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
#zero_ram

int opcion;
int i;
int16 duty;
int16 pulsos;
int16 interrupcion;
int16 velocidad;
int16 recibido;
int  reset;
float dato;
//float const resolucion=5.0/1024.0;
int16 value;
char string[10];
//float corriente;
//float sumacorriente;
//float corrientemedia;
int habilitacion;
//int convertidor;
int32 tiempoReal;
int32 Tiempo;

#int_RTCC   //se determina la funcion de la interrupcion

RTCC_isr()
{

    if(habilitacion==1)
    {

         tiempoReal++;   //se suma a una variable que computa el tiempo transcurrido

         pulsos=get_timer1();    //se obtiene el valor del contador timer1
         interrupcion++;   //se suma en uno el flag de interrupcion
         if(interrupcion==100)   //cuando se llega a 100, es decir, 1 segundo, 100*10ms=1000ms=1seg; se introduce en la funcion
         {
            velocidad=pulsos*15;   //sacamos la velocidad con una regla de tres
            printf("%lu r.p.m.
",velocidad);  //tambien puerto serie

            /* ************ convertidor analógico *****************
            for(i=0;i<10;i++)
            {
            set_adc_channel( 0 );       //el canal 0, entrada AN0
            delay_us(160);                //delay 1us
            value = read_adc();
            dato = value*resolucion;
            corriente=dato;   //una R=0,005 -->  V=IR; I=V/R; corriente=dato/R=dato/0.005=corriente

                 sumacorriente=sumacorriente+corriente;
                 corrientemedia=sumacorriente/10.0;
            }
            printf("%1.3f A
",corrientemedia);*/
            printf("%lu duty",duty);
            Tiempo=tiempoReal*0.01;
            printf("%lu segundos", Tiempo);
            //corrientemedia=0;
            //sumacorriente=0;

            interrupcion=0;  //se inicializa de nuevo el flag de interrupcion para que vuelva a contar 100 interrupciones
            set_timer1(0);   //se inicializa tambien el contador
            set_rtcc(178);   //se introduce de nuevo el valor del temporizador de interrupcion
         }
         else
         {
            set_rtcc(178);
            set_timer1(pulsos);
         }
    }

}








main()
{
   //set_tris_b(0x00);     //si se habilita no se puede sacar el PWM 1
   enable_interrupts(GLOBAL); //se habilitan interrupcion general
   enable_interrupts(INT_RTCC);  //habilita int. del timer0
   setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_128);  //se configura el timer0 como temporizador y una báscula de 128
   set_rtcc(178); //10ms -> 10000us -> 10000/128=78 -> 255-78=177 se le inserta el tiempo a contar, se suma uno
   duty = 0;   //se inicializa el duty en cero
   setup_ccp1(CCP_PWM); //Se habilita el pwm 1
   setup_timer_2(T2_DIV_BY_16, 99, 1); //Se establece el valor de la frecuencia de 620Hz(1,6 ms el periodo) para el PWM
   set_pwm1_duty(duty); //se manda el duty al PWM
   //setup_adc_ports( ALL_ANALOG ); //todo el puerto analogico
   //setup_adc( ADC_CLOCK_INTERNAL ); //convertidor con clock interno



   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1); //se configura el timer1 como contador, de pulsos externos y de báscula 1
   set_timer1(0); //se inicializa el contador en cero

   interrupcion=0;   //se inicializan los flags
   habilitacion=0;
   //convertidor=0;
   tiempoReal=0;
   Tiempo=0;

   while(true)
   {
   //el programa principal que estaria haciendo, esperando a la interrupcion del timer0

               //while(!kbhit());


               gets(string); //Guarda el Duty (0-255) en la variable string aunque solo necesitamos hasta 100
                              //y espera un RETURN (Ctrl 13)
               opcion=atoi(string); //Usa la función ATOI para pasarlo a entero
         switch (opcion) {

            case 3:  //recibido duty cycle

                  while(true)
                  {
                     gets(string);
                     recibido=atol(string);
                     if(recibido==200 || recibido==201);

                        reset_cpu();

                     else
                        duty=recibido;
                        set_pwm1_duty(duty); //El caracter ascii recibido pasado a entero
                                    //establecido como ciclo de trabajo
                        habilitacion=1;   //flag pata habilitar el contaje de los pulsos de velocidad del optoacoplador

                  }
                  break;

            case 4:  //recibido velocidad

                  while(true)
                     {
                     gets(string);
                     recibido=atol(string);
                     if(recibido==200 || recibido==201)

                        reset_cpu();


                     else

                        duty=(recibido*100.0)/3900.0;
                        set_pwm1_duty(duty);
                        habilitacion=1;

                     }
                  break;   }



   }

}


PD: en el codigo estoy intentando tambien tener la opcion de poder controlar con la velocidad o con el duty cycle; por eso la sentencia CASE!! Dpendiendo de lo que le llegue por el puerto serie (un 3 o un 4)!!
Muchas gracias y saludos!!!

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
RE: Control motor introduciendo la velocidad!!
« Respuesta #1 en: 21 de Julio de 2004, 03:39:00 »
Buenas de nuevo!!
Acabo de solucionar el problema, ya puedo controlar mediante el duty cycle y la velocidad si lo deseo, dependiendo de lo que me llegue por el puerto serie!!

Ahora solo me falta realizar el lazo cerrado Proporcional, si alguien podria ayudarme, es uqe no tengo ni idea de como se podria realizar.
Este lazo solo se podria realizar en el control mediante velocidad, no en el control mediante duty!!
Entonces yo solo se que tengo sacar el error, es decir, la diferencia entre la velocidad medida y la deseada, y luego ese error multiplicarlo por una constante ygenerar otro duty, y asi ir acercandonos al velocidad deseada!!
Eso enteoria, pero como se podria hacer programando??? Como se calcularia la konstante, por la cual hay que multiplicar???
Gracias y saludos, os pongo el nuevo codigo:


#include <16f873.h>
#device adc=10
#include <stdlib.h>

#fuses XT, NOPROTECT, NOWDT, NOPUT, NOBROWNOUT, NOLVP, NOCPD, NOWRT
#use delay(clock=4000000)
#use rs232(baud=9600, xmit=PIN_C6, rcv=PIN_C7, parity=N, bits=8)
#zero_ram

int opcion;
int i;
int duty;
int16 pulsos;
int16 interrupcion;
int16 velocidad;
int16 recibido;
int  reset;
float dato;
int16 value;
char string[10];
int habilitacion;
int32 tiempoReal;
int32 Tiempo;

#int_RTCC   //se determina la funcion de la interrupcion

RTCC_isr()
{

    if(habilitacion==1)
    {

         tiempoReal++;   //se suma a una variable que computa el tiempo transcurrido

         pulsos=get_timer1();    //se obtiene el valor del contador timer1
         interrupcion++;   //se suma en uno el flag de interrupcion
         if(interrupcion==100)   //cuando se llega a 100, es decir, 1 segundo, 100*10ms=1000ms=1seg; se introduce en la funcion
         {
            velocidad=pulsos*15;   //sacamos la velocidad con una regla de tres
            printf("%lu     ",velocidad);  //tambien puerto serie

         
            printf("%u     ",duty);  //imprimo el duty para saber cual nos ha generado
            Tiempo=tiempoReal*0.01; //calculo el tiempo en segundos trnascurrido
            printf("%lu     ", Tiempo); //imprimo el tiempo
            interrupcion=0;  //se inicializa de nuevo el flag de interrupcion para que vuelva a contar 100 interrupciones
            set_timer1(0);   //se inicializa tambien el contador
            set_rtcc(178);   //se introduce de nuevo el valor del temporizador de interrupcion
         }
         else
         {
            set_rtcc(178);
            set_timer1(pulsos);
         }
    }

}








main()
{
   enable_interrupts(GLOBAL); //se habilitan interrupcion general
   enable_interrupts(INT_RTCC);  //habilita int. del timer0
   setup_timer_0 ( RTCC_INTERNAL | RTCC_DIV_128);  //se configura el timer0 como temporizador y una báscula de 128
   set_rtcc(178); //10ms -> 10000us -> 10000/128=78 -> 255-78=177 se le inserta el tiempo a contar, se suma uno
   duty = 0;   //se inicializa el duty en cero
   setup_ccp1(CCP_PWM); //Se habilita el pwm 1
   setup_timer_2(T2_DIV_BY_16, 99, 1); //Se establece el valor de la frecuencia de 620Hz(1,6 ms el periodo) para el PWM
   set_pwm1_duty(duty); //se manda el duty al PWM



   setup_timer_1(T1_EXTERNAL | T1_DIV_BY_1); //se configura el timer1 como contador, de pulsos externos y de báscula 1
   set_timer1(0); //se inicializa el contador en cero

   interrupcion=0;   //se inicializan los flags
   habilitacion=0;
   tiempoReal=0;
   Tiempo=0;

   while(true)
   {
   //el programa principal que estaria haciendo, esperando a la interrupcion del timer0

               //while(!kbhit());


               gets(string); //Guarda el Duty (0-255) en la variable string aunque solo necesitamos hasta 100
                              //y espera un RETURN (Ctrl 13)
               opcion=atoi(string); //Usa la función ATOI para pasarlo a entero
               
         switch (opcion) {    //case para entrar en un ocdigo u otro

            case 3:  //recibido duty cycle se controla mediante duty cycle con un rango

                  while(true)
                  {
                     gets(string);  //recibo la cadena
                     recibido=atol(string);  //la convierto la cadena a entero
                     if(recibido==150 || recibido==151)  //si se envia cualquiera de estos dos numeros se resetea el PIC, reset por software
                        {
                           reset_cpu();
                        }
                     else     //si no se ha recibido reset o desconexion, se prosigue a realizar el duty
                        {
                           duty=recibido;  
                           set_pwm1_duty(duty); //El caracter ascii recibido pasado a entero
                                       //establecido como ciclo de trabajo
                           habilitacion=1;   //flag pata habilitar el contaje de los pulsos de velocidad del optoacoplador
                        }
                  }
                  break;

            case 4:  //recibido velocidad se controla mediante velocidad con un rango

                  while(true)
                     {
                     gets(string);
                     recibido=atol(string);
                     if(recibido==150 || recibido==151)
                        {
                           reset_cpu();
                        }
                     else     //si no se ha recibido el reset o desconexion se prosigue a ejecutar el duty
                        {
                           duty=(recibido*100.0)/3900.0;
                           set_pwm1_duty(duty);
                           habilitacion=1;
                        }
                     }
                  break;   }        //fin del "CASE"



   }

}

Desconectado nordestenica

  • PIC16
  • ***
  • Mensajes: 215
RE: Control motor introduciendo la velocidad!!
« Respuesta #2 en: 21 de Julio de 2004, 04:55:00 »
Xa2 me as dejado estoy intentando acer algo parecido a esto e me e passado meses e nada de nada e de repente aparece un genio e en dos dias lo consigue

que dezirte bueno que eres un genio e perguntarte si puedo usar parte de tu codigo para mi bichito que estoy construiendo ace 4 meses e no me salia ni por nada

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
RE: Control motor introduciendo la velocidad!!
« Respuesta #3 en: 21 de Julio de 2004, 05:50:00 »
Gracias asi da gusto!!
Claro que puedes utilizarlo parte, pero hay que cambiar 150 y 151 por 5000 y 5001, ya que si introduces una velocidad de 150 o 151 el PIC se resetea!!!
Saludos!!

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Control motor introduciendo la velocidad!!
« Respuesta #4 en: 21 de Julio de 2004, 12:14:00 »
Te felicito Xa2, con la información que te dimos y con lo que tu has añadido te ha quedado un proyecto chulo.

Ahora a ver como solucionas lo de los decimales en el Duty de la velocidad ... estoy seguro que lo conseguirás.

Un saludo

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
RE: Control motor introduciendo la velocidad!!
« Respuesta #5 en: 21 de Julio de 2004, 12:41:00 »
Gracias Pocher!!!
Todo un cumplido viniendo de ti, muchas gracias!!!
No tengo el problema del duty, mi problema es otro, es el lazo proporcional!!!
Que no se que calculos hay que hacer ni nada!!
Haber si podeis ayudarme o mandarme alguna informacion buena!!
Gracias y saludos!!!

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Control motor introduciendo la velocidad!!
« Respuesta #6 en: 21 de Julio de 2004, 12:48:00 »
Sí creo que sí que son los decimales. Mira un ejemplo:

Si mandas una v=60 r.p.m. ---> CCPR1L (Duty)=(60·100)/3900=1,5 entonces como la variable duty es entera toma 1 y claro ya no irá a 60 r.p.m. irá a menos

Si mandas una v=180 r.p.m. ---> CCPR1L (Duty)=(180·100)/3900=4,6 entonces como la variable duty es entera toma 4 y claro ya no irá a 180 r.p.m. irá a menos

PD. ¿Elegiste 4 radios en el disco, no?

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
RE: Control motor introduciendo la velocidad!!
« Respuesta #7 en: 21 de Julio de 2004, 15:02:00 »
Si elegi 4 radios en el disco!!
Pero si tengo decimales, no puedo mandar flotantes para el PWM, solo enteros, entonces como se mandaria con decimales??
De todas formas luego vendria el lazo cerrado de velocidad proporcional y se corregiria el error o diferencia de velocidades deseadas y obenidas!!
No se contestame que te parece, o que harias tu!!!
Gracias de nuevo, no se que haria sin ti, jejej y luego dicen que soy un genio, pero si aqui el unico genio eres tù!!!
Saludos

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Control motor introduciendo la velocidad!!
« Respuesta #8 en: 22 de Julio de 2004, 00:32:00 »
Entre todos vamos haciendo camino ...

No te prometo nada, si puedo miraré lo del control P.

Un saludo

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Control motor introduciendo la velocidad!!
« Respuesta #9 en: 22 de Julio de 2004, 06:56:00 »
Oye si tienes el "chiringuito" montado podrías comprobar y decirme que velocidades devuelve si le envias por ejemplo 60 r.p.m., 120 r.p.m., 180 r.p.m. y 3900 r.p.m.

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
RE: Control motor introduciendo la velocidad!!
« Respuesta #10 en: 22 de Julio de 2004, 07:07:00 »
Pues ahora mismo no, porque esoty haciendo la placa y estoy teniendo unos problemillas, pero te puedo decir que la minima velocidad es de 700 r.p.m., ya que cuando introduces menos el motor no gira, no le llega suficiente intensidad!!
Si te sirve de ayuda!!
Cuando termine de monatr, te dejo el resto de datosQ!Q
Saludos^Pocher !!!

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
RE: Control motor introduciendo la velocidad!!
« Respuesta #11 en: 22 de Julio de 2004, 07:23:00 »
Ya esta, a 3900 r.p.m. me dan 3600 r.p.m. alrededor, siempre por esos valores!!
Las demas velocidades no me da!!
Tu me diras!!
Saludos

Desconectado pocher

  • Moderador Local
  • DsPIC30
  • *****
  • Mensajes: 2568
RE: Control motor introduciendo la velocidad!!
« Respuesta #12 en: 22 de Julio de 2004, 12:05:00 »
Pués sí que se va de mucho y eso que para 3900 r.p.m. no hay decimales (sale un duty justo igual a 100).

¿Porqué en esta medida se va de tanto? Prueba a conectar el motor directamente a alimentación (es de 5V, 12V, ... ¿?) a ver si saca las 3900 r.p.m. (velocidad máxima especificada en el motor), ya me dirás cuanto sale ahora.

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
RE: Control motor introduciendo la velocidad!!
« Respuesta #13 en: 22 de Julio de 2004, 14:00:00 »
Nosotros lo alimentamos a 13,2 V; pero te voy a decir porque cuando pongo 3900 r.p.m. deseadas salen 3600; es porque en el programa hago una regla de tres, y he supuesto que al 100 de duty la velocidad es de 3900, cuando es alrededor de 3600; por eso sale la diferencia, si se pone en el programa entre 3700 donde pone entre 3900; al desear 3700 r.p.m. nos saldria unas 3680 o siempre por esos valores.
Por eso nos sucede ese error!!
Creo que es por eso, si te vale la respuesta??
Saludos!!!

Desconectado Xa2

  • PIC12
  • **
  • Mensajes: 58
RE: Control motor introduciendo la velocidad!!
« Respuesta #14 en: 22 de Julio de 2004, 14:05:00 »
Joder se me ha olvidado decirte que en el motor tenemos una resistencia shunt de 1 ohmio; entonces hay una caida de tension de como maximo de 120 mV; esta medido, por lo que al motor le llegan 13,1 V mas o menos; te lo digo para que lo sepas aunque no creo que influya en la diferencia de velocidad real y velocidad del motor deseada!!
Yo creo que es por lo que te he dicho antes!!
Seguire probando cambiando la regla de tres que te he dicho, y te dare los resultados!
Saludos!!!



 

anything