Autor Tema: un pic puede leer un encoder?  (Leído 13453 veces)

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

Desconectado enero0022

  • PIC10
  • *
  • Mensajes: 36
un pic puede leer un encoder?
« 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

Desconectado poseidon20

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 762
Re: un pic puede leer un encoder?
« Respuesta #1 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:

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: un pic puede leer un encoder?
« Respuesta #2 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)

Hay muchos tipos de motores; unos se pueden regular con PWM y otros no. Habría que saber más sobre el que indicas.

Desconectado maunix

  • Moderadores
  • DsPIC33
  • *****
  • Mensajes: 4751
    • Mi Sitio Web Personal
Re: un pic puede leer un encoder?
« Respuesta #3 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.


- La soberbia de un Einstein es entendible.. la de un salame es intolerable (A.Dolina)
- En teoría no hay diferencia entre la teoría y la práctica. En la práctica... si la hay.
- Lee, Lee, Lee y luego pregunta.(maunix)
- Las que conducen y arrastran al mundo no son las máquinas, sino las ideas (V. Hugo)
- Todos los hombres se parecen por sus palabras; solamente las obras evidencian que no son iguales.(Moliere)
- Todo debería ser hecho tan simple como sea posible pero no mas simple que eso.(A.Einstein)

Desconectado Vayadespiste

  • PIC12
  • **
  • Mensajes: 53
Re: un pic puede leer un encoder?
« Respuesta #4 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.

Desconectado jjcblanco

  • PIC10
  • *
  • Mensajes: 20
Re: un pic puede leer un encoder?
« Respuesta #5 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?

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: un pic puede leer un encoder?
« Respuesta #6 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.

Desconectado jjcblanco

  • PIC10
  • *
  • Mensajes: 20
Re: un pic puede leer un encoder?
« Respuesta #7 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.


Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: un pic puede leer un encoder?
« Respuesta #8 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.

Desconectado jjcblanco

  • PIC10
  • *
  • Mensajes: 20
Re: un pic puede leer un encoder?
« Respuesta #9 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

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: un pic puede leer un encoder?
« Respuesta #10 en: 23 de Julio de 2009, 13:14:37 »
Si quieres seguridad compra un encoder hecho y usa el pic para controlarlo

Desconectado Alexandra

  • PIC10
  • *
  • Mensajes: 22
Re: un pic puede leer un encoder?
« Respuesta #11 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??

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: un pic puede leer un encoder?
« Respuesta #12 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?

Desconectado Alexandra

  • PIC10
  • *
  • Mensajes: 22
Re: un pic puede leer un encoder?
« Respuesta #13 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...

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: un pic puede leer un encoder?
« Respuesta #14 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);
         }
      */
      }
   }
  
  


 

anything