TODOPIC

Microcontroladores PIC => Todo en microcontroladores PIC => Mensaje iniciado por: enero0022 en 16 de Enero de 2008, 22:39:38

Título: un pic puede leer un encoder?
Publicado por: enero0022 en 16 de Enero de 2008, 22:39:38
hola a todos tengo la inquietud de conectar un encoder a un pic para poder controlar el avance de un motor a determinada
distancia y quiero saber si ya alguien lo realizo y si me pueden enviar algun ejemplo o alguna sugerencia a la vez quiero saber si se puede controlar el motor con el pwm han de saber que el motor es de tipo industrial 1 hp aproximadamente.
gracias
Título: Re: un pic puede leer un encoder?
Publicado por: poseidon20 en 16 de Enero de 2008, 23:20:48
mi estimado enero0022, le recomiendo usar al señor BUSCADOR del foro, si lo usa le facilitara la busqueda de informacion, acabo de consultarle con la palabra "encoder" y me arrojo 9 paginas de 30 enlaces(aprox) cada una, animese a preguntarle, el no muerde  :mrgreen: :mrgreen:
Título: Re: un pic puede leer un encoder?
Publicado por: Nocturno en 17 de Enero de 2008, 06:24:44
Sí se puede. Yo hice un ejemplo que podrías mirar, aunque sólo sirve si utilizas un dsPIC con módulo QEI.
dsPIC33F - Capítulo 3: Quadrature Encoder Interface (QEIM) (http://www.micropic.es/index.php?option=com_content&task=view&id=18&Itemid=44)

Hay muchos tipos de motores; unos se pueden regular con PWM y otros no. Habría que saber más sobre el que indicas.
Título: Re: un pic puede leer un encoder?
Publicado por: maunix en 17 de Enero de 2008, 08:13:38
Puedo agregar que también se puede con un 18F y con un 16F utilizando el módulo de comparación y captura, por ejemplo.

Todo depende de la precisión que necesites y si necesitas sensar sentido de giro o si tu lo etarás comandando y a cuantas RPM estarás girando el eje y de cuantos pulsos por vuelta arroje el mismo. 

Cuantos mas pulsos por vuelta arroje y mayor velocidad gire el eje más velocidad necesitaras en tu microcontrolador para leer el pulso.


Título: Re: un pic puede leer un encoder?
Publicado por: Vayadespiste en 17 de Enero de 2008, 10:17:25
Hay algunos modelos de pic18f que llevan incorporado QEI (Quadrature Encoder Interface) por ejemplo el 18F4431, 2431, 2331 etc... verás toda la información en el capitulo 16.2 del Datasheet.
Título: Re: un pic puede leer un encoder?
Publicado por: jjcblanco en 21 de Julio de 2009, 13:47:10
Estoy trabajando en el tema, lei el ejemplo de nocturno, pero yo estoy trabajando con 18f4331 que tiene el modulo.
La pregunta es yo me tendria que armar un disco con esa forma pero la duda es cuantas ventanas tiene que tener?
cuantas mas ventanas, mas presicion?
Título: Re: un pic puede leer un encoder?
Publicado por: Algec en 21 de Julio de 2009, 14:55:34
No hace falta ningun modulo ni nada, con dos entradas y el soft adecuado se leen, yo tengo tres encoders caseros en mi fresadora y leen posicion perfectamente, con un 16F877 a 20 Mhz leen hasta 2500 rpms.
Si necesitas el ejemplo lo subo.
Título: Re: un pic puede leer un encoder?
Publicado por: jjcblanco en 22 de Julio de 2009, 15:00:40
gracias el tema es como los instalo en el motor?
Uso sensor optico , o hall?

una vez hecho eso es analizar una senial cuadrada, periodo y duty cicle.
Si tenes un ejemplo subilo.

Título: Re: un pic puede leer un encoder?
Publicado por: Algec en 23 de Julio de 2009, 09:55:32
en el eje dos sensores desfasados es suficiente, que den señal de 0 a 5 v, para eso se suele usar un 40106 o similar.
Dos entradas del pic leen los pulsos desfasados, Hay que convertir de codigo Gray a codigo binario y comparar etc....y de ahoi sale el sentido de giro la velocidad y contador si quieres para posicion.
Título: Re: un pic puede leer un encoder?
Publicado por: jjcblanco en 23 de Julio de 2009, 13:10:36
Pero vi que al eje le colocan unos discos con ventanas blanco/negro y estoy viendo como hacer eso porque es un motor bastante importante
Título: Re: un pic puede leer un encoder?
Publicado por: Algec en 23 de Julio de 2009, 13:14:37
Si quieres seguridad compra un encoder hecho y usa el pic para controlarlo
Título: Re: un pic puede leer un encoder?
Publicado por: Alexandra en 24 de Julio de 2009, 10:23:02
Citar
No hace falta ningun modulo ni nada, con dos entradas y el soft adecuado se leen, yo tengo tres encoders caseros en mi fresadora y leen posicion perfectamente, con un 16F877 a 20 Mhz leen hasta 2500 rpms.
Si necesitas el ejemplo lo subo.


Hola Algec , puedes publicar tu ejemplo??
Título: Re: un pic puede leer un encoder?
Publicado por: Algec en 24 de Julio de 2009, 16:43:43
Vale lo publicare pero tengo un pequeño problema, no recuerdo como pegar el codigo y que quede como codigo, me lo recordais?
Título: Re: un pic puede leer un encoder?
Publicado por: Alexandra en 24 de Julio de 2009, 16:51:18
Cuando ingresas para responder en la parte de arriba hay varios iconos, elige el que tiene el simbolo # luego has un copy/past de tu codigo y leugo vuelve a precionar para cerar la opcion y ya esta...
Título: Re: un pic puede leer un encoder?
Publicado por: Algec en 24 de Julio de 2009, 17:01:48
Aver si os vale esto, si quereis mas decidmelo
Trato de subir el proteus completo caratulas etc pero de momento no me deja
Código: [Seleccionar]
#include <16F877.h>
   #use delay(clock=4000000)      
  
   // mas precision y velocidad de conteo si se usa a 20 Mhz
   // tambien trabaja a 4 Mhz pero pierde velocidad

   #fuses HS,NOWDT,NOPROTECT,NOLVP,PUT,NODEBUG,BROWNOUT,NOCPD,NOWRT // 0x3F71
  
   // Uso mi propia libreria de LCD por usar un lcd de 4x20 y no estar este
   // configurado en la rutina propia de CCS
   // se puede usar la libreria lcd.h de CCS con un display conectado tal y como indica
   // la libreria de CCS

   #include <lcd1.c>        //"lcd.h"
  
   // inicializa valores de contadores
  
  // si se utiliza int16 pierde valor maximo de conteo, pero gana en velocidad de calculo por
  // lo que permite mas velocidad de giro o mas impulsos por vuelta sin dar error
  // int32 da mas pulsos contados a costa de perder velocidad en el contador y generar mas errores

   signed int16 contador_X = 0;
   signed int16 contador_Y = 0;
   signed int16 contador_Z = 0;
  


      // Rutina de cambio de codigo
      // pasa de codigo gray (que es el que genera a dos bits el encoder) a binario
      // gray     binario
      // 00       00
      // 01       01
      // 11       10
      // 10       11
 
 /**************************************************************************************/

  
 
byte pasa_a_binario(byte valor)
   {
   if(bit_test(valor,1)==1)        // si el bit 1 de valor es 1
      {
      if(bit_test(valor,0)==0)     // invierte el bit 0 de valor
         bit_set(valor,0);         // hace 1 el bit 0 de valor
      else
         bit_clear(valor,0);      // hace cero el bit 0 de valor
      }
   return valor;
   }
  
  
void main(void)
   {
  
   unsigned byte actual_X ;
   unsigned byte anterior_X ;
   unsigned byte diferencia_X ;  
   unsigned byte actual_Y;
   unsigned byte anterior_Y;
   unsigned byte diferencia_Y;
   unsigned byte actual_Z;
   unsigned byte anterior_Z;
   unsigned byte diferencia_Z;
  
   disable_interrupts(GLOBAL);
   enable_interrupts(INT_RB);
   enable_interrupts(GLOBAL);
  
   // inicializa el lcd
  
   lcd_init();

   // visualiza los Textos

   lcd_gotoxy(1,1);
   lcd_putc("X:");
   lcd_gotoxy(1,2);
   lcd_putc("Y:");
   lcd_gotoxy(1,3);
   lcd_putc("Z:");
   lcd_gotoxy(3,1);
  
   printf(lcd_putc,"%4.2w  ",contador_X);
   lcd_gotoxy(3,2);
   printf(lcd_putc,"%4.2w  ",contador_Y);
   lcd_gotoxy(3,3);
   printf(lcd_putc,"%4.2w  ",contador_Z);


   // borra las salidas de los leds de error

   output_c(0x00);
   // Lectura inicial  
   // lee los dos bits de menos peso del puerto A y los pone en la variable estado_X
   // estos corresponden a las entradas del pic asignadas al encoder del eje X

   anterior_X=input_a() & 0x03;         // lee solo los bits 0 y 1
  
   // hace la lectura del encoder Y
  
   // para solo considerar los dos bits que interesan

   anterior_Y=(input_a() & 0x0c)/4;     // lee los bits 2 y 3 y desplaza a la izda 2 bits

   // hace la lectura del encoder Z

   // para solo considerar los dos bits que interesan

   anterior_Z=(input_a()& 0x30) / 16;  // lee los bits 4 y 5 y desplaza a la izda 4 bits
        
  
   // pasa de codigo gray (que es el que genera a dos bits el encoder) a binario

   anterior_X = pasa_a_binario(anterior_X);
   anterior_Y = pasa_a_binario(anterior_Y);
   anterior_Z = pasa_a_binario(anterior_Z);
  

   while(TRUE)
      {

    
   // hace la lectura del encoder X      

      actual_X=input_a() & 3;       // lee solo los bits 0 y 1
  
     // hace la lectura del encoder Y

      actual_Y=(input_a()& 0x0c)/4;
      
     // hace la lectura del encoder Z

      actual_Z=(input_a()& 0x30)/16;

      // hace la lectura del encoder Z
  
      actual_X = pasa_a_binario(actual_X);     // cambia de codigo gray a binario
      actual_Y = pasa_a_binario(actual_Y);     // cambia de codigo gray a binario          
      actual_Z = pasa_a_binario(actual_Z);     // cambia de codigo gray a binario          

      // rutina del eje X
     if(actual_X != anterior_X)    // si ha cambiado el estado es que ha habido un pulso
     {
      // calcula la diferencia para ver los bits de signo y de error
      
     diferencia_X = actual_X - anterior_X;

      //lineas de testeo
//        lcd_gotoxy(10,1);
//        printf(lcd_putc,"%d %d %x", anterior_X,actual_X,diferencia_X&3);

         // chequeo los bits de error y signo
        
       if(bit_test(diferencia_X,0) == 0)   // si se ha producido un error se habra puesto a cero el bit 0
           {
           output_high(PIN_C0);       // enciende el led de error
           lcd_gotoxy(12,1);
           lcd_putc("ERROR");
           }
         else
            {  // chequea el bit de sentido de giro
               // si es hacia un lado incrementa el contador lo que
               // sea necesario segun el numero de pulsos/vuelta
               // y la precision requerida

            if(bit_test(diferencia_X,1) == 1)
               contador_X = contador_X + 5;                                                              
            else  
               contador_X = contador_X - 5;  
  
             // visualizacion eje X
      
            lcd_gotoxy(3,1);
            printf(lcd_putc,"%4.2w  ",contador_X/4);
            }
            // memoriza en anterior_X el estado actual
            anterior_X  = actual_X;
         }

    
    
     // rutina del eje Y
    
     if(actual_Y != anterior_Y)    // si ha cambiado el estado es que ha habido un pulso
         {
          
          // calcula la diferencia para ver los bits de signo y de error

         diferencia_Y = (actual_Y- anterior_Y);
      
        
         // chequeo los bits de error y signo

         if(bit_test(diferencia_Y,0) == 0)   // si se ha producido un error se habra puesto a cero el bit 0
            {
            output_high(PIN_C1);       // enciende el led de error
            lcd_gotoxy(12,2);
            lcd_putc("ERROR");
            }  
         else
            {  
            if(bit_test(diferencia_Y,1) == 1)   // chequea el bit de sentido de giro
               contador_Y=contador_Y+5;                  // si es hacia un lado incrementa el contador
            else
               contador_Y=contador_Y-5;   // hacia el otro lo decrementa igualmente

             // visualizacion eje Y
      
            lcd_gotoxy(3,2);
            printf(lcd_putc,"%4.2w  ",contador_Y/4);
            }
            // memoriza en anterior_Y el estado actual
            anterior_Y  = actual_Y;    
        }
    // Rutina del eje Z

    if(actual_Z != anterior_Z)    // si ha cambiado el estado es que ha habido un pulso
         {

          // calcula la diferencia para ver los bits de signo y de error

         diferencia_Z = actual_Z - anterior_Z;
        
         // chequeo los bits de error y signo
        
         if(bit_test(diferencia_Z,0) == 0)   // si se ha producido un error se habra puesto a cero el bit 0
            {
            output_high(PIN_C2);            // enciende el led de error
            lcd_gotoxy(12,3);
            lcd_putc("ERROR");
            }  
         else
            {  
            if(bit_test(diferencia_Z,1) == 1) // chequea el bit de sentido de giro que sera 1 girando a derecha
               contador_Z=contador_Z+5;                // si es hacia un lado incrementa el contador
            else
               contador_Z= contador_Z-5     ;           // hacia el otro lo decrementa

             // visualizacion eje Z
      
            lcd_gotoxy(3,3);
            printf(lcd_putc,"%4.2w  ",contador_Z/4);
            }
           // memoriza en anterior_Z el estado actual
            anterior_Z  = actual_Z;
       }
        
  


     // Pulsadores de puesta a cero
    /*
     If(input(PIN_B0))          // puesta a cero de posicion Inicial tres ejes
         {
          output_low(PIN_C0);   // pone a cero los leds de error
          output_low(PIN_C1);
          output_low(PIN_C2);
          contador_X = 0;
          contador_Y = 0;
          contador_Z = 0;
          lcd_gotoxy(12,1);
          lcd_putc("     ");
          lcd_gotoxy(12,2);
          lcd_putc("     ");
          lcd_gotoxy(12,3);
          lcd_putc("     ");
          lcd_gotoxy(3,1);
          printf(lcd_putc,"%4.2w  ",contador_X);
          lcd_gotoxy(3,2);
          printf(lcd_putc,"%4.2w  ",contador_Y);
          lcd_gotoxy(3,3);
          printf(lcd_putc,"%4.2w  ",contador_Z);
         }
      If(input(PIN_B1))          // puesta a cero de posicion Inicial Eje X
         {
          output_low(PIN_C0);
          contador_X = 0;
          lcd_gotoxy(12,1);
          lcd_putc("     ");
          lcd_gotoxy(3,1);
          printf(lcd_putc,"%4.2w  ",contador_X);
         }
      If(input(PIN_B2))          // puesta a cero de posicion Inicial Eje Y
         {
          output_low(PIN_C1);
          contador_Y = 0;
          lcd_gotoxy(12,2);
          lcd_putc("     ");
          lcd_gotoxy(3,2);
          printf(lcd_putc,"%4.2w  ",contador_Y);
         }
      If(input(PIN_B3))          // puesta a cero de posicion Inicial eje Z
         {
          output_low(PIN_C2);
          contador_Z = 0;
          lcd_gotoxy(12,3);
          lcd_putc("     ");
          lcd_gotoxy(3,3);
          printf(lcd_putc,"%4.2w  ",contador_Z);
         }
      */
      }
   }
  
  
Título: Re: un pic puede leer un encoder?
Publicado por: Algec en 24 de Julio de 2009, 17:14:38
VAmos a ver, este es un ejemplo, yo hice un sistema completo con tres encoders para los tres ejes de mi fresadora CNC, al ser tres encoders no pude usar la interrupcion por cambio de estado, que habria funcionado mejor, por eso la hice testeando las entradas al cabo de cierto tiempo de forma ciclica, que tambien funciona.
Tengo todo el proyecto y creo que en su dia lo subi, mirar por el foro en CNC.
LLeva los encoders que son de mi propio diseño y contruccion, fotos proteus completo isis y ares, de las placas, creo que un video, las caratulas que use  en resumen un poco de todo.
TAmbien tengo un ejemplo con interrupcion por cambio de estado. si lo necsitais.....
El equipo esta funcionando en mi fresadora perfectamente y hasta 3000 rpm va bien al menos como yo lo tengo.
Al final encontre el post en el foro, es este
http://www.todopic.com.ar/foros/index.php?topic=23074.0
Título: Re: un pic puede leer un encoder?
Publicado por: cyberian en 21 de Octubre de 2009, 14:49:18
Hola, yo estoy usando un PIC18F4431 para hacer funcionar un motor trifásico de compactera y de disco rígido, ya he logrado hacerlos funcionar, con los 6 pwm y el inversor trifásico. Ahora quiero utilizar los 3 sensores hall que trae el motor de compactera, con el módulo QEI que trae el PIC18F4431. El tema es que no sé cómo trabajan los sensores hall. Una posibilidad que tengo, es llevarlo a la facu, y conectarle el osciloscopio, pero es mucho trastorno para mí. Estos sensores hall emiten un ancho de pulso proporcional a algo, o un pulso cuadrado proporcional a la velocidad?????. El motor trae 3 sensores hall, debajo de las bobinas, pero aún no me doy maña de cómo usarlo, tal vez conectar uno al QEA, otro al QEB, y otro al index????? para determinar el sentido de giro y las revoluciones.
El sentido de giro no es problema, porque lo manejo yo invirtiendo 2 fases del motor, lo que más me interesa es tener un control de la velocidad, ya que aunque la misma la varíe con la frecuencia, quiero que el sensor me la envía para mostrarla en un display.
Título: Re: un pic puede leer un encoder?
Publicado por: Nocturno en 21 de Octubre de 2009, 15:11:01
Yo me enfrenté a lo mismo con un motor parecido, aquí dejé lo que hice, puede que te sirva: http://www.micropic.es/index.php?option=com_content&task=view&id=81&Itemid=39
Título: Re: un pic puede leer un encoder?
Publicado por: cyberian en 10 de Diciembre de 2009, 01:32:54
Yo me enfrenté a lo mismo con un motor parecido, aquí dejé lo que hice, puede que te sirva: http://www.micropic.es/index.php?option=com_content&task=view&id=81&Itemid=39
Yo me enfrenté a lo mismo con un motor parecido, aquí dejé lo que hice, puede que te sirva: http://www.micropic.es/index.php?option=com_content&task=view&id=81&Itemid=39

Muchas gracias, estoy visitando el MicroPIC más seguido. El enlace al control del motor brushless que me pasaste está muy bueno, de hecho, estoy tratando de implementarlo, pero no entiendo bien el motor que tengo. tiene 3 sensores hall, smd de 4 conectores, y hay 8 cables a los sensores hall, y no puedo ver el conexionado, ya que son miniatura y los tapan las bobinas. Voy a ver si en las vacaciones, puedo ir al lab de la facu y usar los osciloscopios para descubrir como trabajan.
Yo lo he hecho funcionar con el control senoidal, pero no logro que levanten muchas revoluciones.
Los 3 sensores que traen son parecidos a estos: http://www.hallsensors.de/CYSH12AF.pdf
Agradezco mucho tu ayuda.