Autor Tema: Problema con ENCODER  (Leído 3593 veces)

0 Usuarios y 1 Visitante están viendo este tema.

Desconectado samshiel_pic

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 777
    • Electrónica·Ingenia
Problema con ENCODER
« en: 04 de Septiembre de 2010, 17:13:09 »
Hola chicos que tal??
Estoy trabajando con un encoder para poder integrarlo en un proyecto pero estoy teniendo una serie de problemas.
Estoy usando un PIC16F877A y un encoder de ALPS de la serie EC09E el cual tiene un botón integrado.
Y el muestreo lo iba ha hacer en una placa con 8 leds y que se fueran prendiendo según giro a izquierda o a derecha, pero lo simplifique a dos leds. Si gira a izquierda se enciende el led de la izq. y a derecha al contrario.  ;-)

Peeero aqui esta el problema cuando giro a izq. se enciende el led de la izq. pero según sigo girando se enciende bastantes veces la de la derecha y al contrario igual.

no se que es lo que puede pasar pero pienso que puede ser que no le de tiempo a entrar en la interrupción externa y cuando vuelve a entrar ya han pasado dos tres pasos mas y se confunde. "CREOOOO" ustedes que pensáis????  :?

Este es el codigo:

Código: C
  1. #include <16F877A.h>
  2.  
  3. #FUSES XT, NOWDT, NOPROTECT, NOPUT, NOLVP // Ordenes para el programador.
  4. #USE DELAY( CLOCK=4000000 ) // Frecuencia del oscilador.
  5. #use fixed_io(b_outputs=PIN_B2,PIN_B3,PIN_B5,PIN_B6,PIN_B7)
  6. #USE STANDARD_IO (A)
  7.  
  8. #byte PORTA    =  0x05
  9. #byte PORTB      = 0x06
  10.  
  11.  
  12.  
  13. #bit ENCA   = PORTB.0   //TERMINAL A
  14. #bit ENCB   = PORTB.1   //TERMINAL B
  15. #define DER      1   //SENTIDOS DEL ENCODER
  16. #define IZQ      0  
  17.  
  18. //Variables
  19. short giro   = FALSE;
  20. short sentido   = DER;
  21.  
  22. #int_EXT
  23. void INTRB0(void)
  24.    {
  25.    sentido = ENCB;
  26.    giro = TRUE;
  27.    }
  28.  
  29. VOID MAIN (VOID)
  30.    {
  31.    enable_interrupts(INT_EXT);
  32.    enable_interrupts(GLOBAL);
  33.    ext_int_edge(1,H_TO_L);
  34.    do{
  35.       if(giro == TRUE)
  36.          {
  37.          giro = FALSE;
  38.          if(sentido == DER){
  39.          OUTPUT_HIGH(PIN_B3);
  40.          //DELAY_MS(250);
  41.          OUTPUT_LOW(PIN_B2);  
  42.          }
  43.          IF(sentido == IZQ){
  44.          OUTPUT_HIGH(PIN_B2);
  45.          //DELAY_MS(250);
  46.          OUTPUT_LOW(PIN_B3);
  47.          }
  48.  
  49.          }
  50.       }
  51.    while(TRUE);  
  52.    }

Si no lo he explicado muy bien después pongo un video del funcionamiento.

GRACIAS  :P

Desconectado korpaztk

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 202
Re: Problema con ENCODER
« Respuesta #1 en: 06 de Septiembre de 2010, 12:08:50 »
no logro entender bien lo que planteas...
para que son los delay q tenes anulados de 250ms?
en ves de utilizar tantos if, no es mas comodo utilizar los case?
o sino probaria con

VOID MAIN (VOID)
   {
   enable_interrupts(INT_EXT);
   enable_interrupts(GLOBAL);
   ext_int_edge(H_TO_L);
   do{
      if(giro == TRUE)
         {
         giro = FALSE;
         if(sentido == DER){
         OUTPUT_HIGH(PIN_B3);
         //DELAY_MS(250);
         OUTPUT_LOW(PIN_B2); 
         }
         else{
         OUTPUT_HIGH(PIN_B2);
         //DELAY_MS(250);
         OUTPUT_LOW(PIN_B3);
         }
 
         }
      }
   while(TRUE);   
   }


no soy muy avanzado que digamos en c.. pero espero darte alguna ayuda
Korpaz.
Técnico Electronico.

El Papel Es Mi Mejor Psicologo

Desconectado f-traxx

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 116
Re: Problema con ENCODER
« Respuesta #2 en: 06 de Septiembre de 2010, 13:28:01 »
Hola amigo, yo cambiaria los OUTPUT_HIGH(PIN_B3); y OUTPUT_LOW(PIN_B2) por un output_toggle(PIN_B3) asi solo se encederia mientras este en el bucle y si el encoder va muy rapido lo verias encendido bastante tiempo.

Te doy esa opcion porque a mi me paso algo parecido (se me quedaba pillado con los output high y output low).

por si lo quieres probar seria asi: (yo de ti lo probaria, no pierdes nada)

do{
     if(giro == TRUE)
        {
        giro = FALSE;
        if(sentido == DER){
        OUTPUT_toggle(PIN_B3);
        //DELAY_MS(250);
        }
        IF(sentido == IZQ){
        OUTPUT_toggle(PIN_B2);
        //DELAY_MS(250);
        }
        }
     }
  while(TRUE);   

Desconectado samshiel_pic

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 777
    • Electrónica·Ingenia
Re: Problema con ENCODER
« Respuesta #3 en: 07 de Septiembre de 2010, 13:18:21 »
Hola f-traxx he hecho lo que me has comentado pero sigue igual. Si giro a derecha me enciende el led de la derecha pero de se equivoca bastantes veces y me enciende el de la izquierda e igual al contrario.

korpaztk la primera vez que hice el pequeño programa lo hice con un switch(sentido); pero como me sacaba este fallo lo cambie por if para ver si el problema era ese.  Y los delay son de hacer pruebas pero no son valen para nada.

No tengo ni idea de que puede pasar.
Me estan entrando dudas de haber si va ha ser del hardware y no del soft.

yo tengo conectado el encoder asi:


No se ahi gente que le he visto con resistencias 47k en vez de las que le tengo puestas yo.

Desconectado f-traxx

  • Colaborador
  • PIC16
  • *****
  • Mensajes: 116
Re: Problema con ENCODER
« Respuesta #4 en: 09 de Septiembre de 2010, 09:07:09 »
 :? Yo no creo que sea del Hardware, pero no me hagas caso porque no se mucho, intenta con resistencias de 22K creo que 47K seria demasiado.

Puede que sea culpa de "rebotes" pero no lo se, en principio el software parece que sea fácil, si consigues solucionarlo, publica el problema que tenias.

Siento no haberte podido ser de ayuda.

Desconectado samshiel_pic

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 777
    • Electrónica·Ingenia
Re: Problema con ENCODER
« Respuesta #5 en: 09 de Septiembre de 2010, 10:35:37 »
Gracias f-traxx, provare a ver que tal pero no se sigo igual.

Desconectado mparra

  • PIC10
  • *
  • Mensajes: 8
Re: Problema con ENCODER
« Respuesta #6 en: 09 de Septiembre de 2010, 16:28:57 »
Hola, he mirado el datasheet de tu encoder, y he visto los siguientes valores:

At R = 5kΩ
Chattering: 5ms max.
Bounce: 2ms max.

Por lo pronto las resistencia es de 5 K, yo primero las pondria como están en el datasheet.
Despues y creo que es lo más importante aparece algo relacionado con rebotes, que tienen máximos de 5 ms y 2 ms. No se exactamente a que se referira, pero parece que en tu codigo tienes que tomar lecturas de la entrada A y B con esa separacion de tiempo. Lo que te está pasando es que detectas una señal valida, y una falsa depués, intenta hacer un retardo de 5ms antes volver a leer los pines. Yo me crearia una variable candado que no deje que modifique las variables en la interrupción hasta que no haya pasado ese tiempo. Esta variable puede ser la misma que usas de giro.
Ya nos cuentas algo

Código: [Seleccionar]


void INTRB0(void)
 {
    if (giro = FALSE)    // si se produce un rebote antes de 2ms no modificará variables
     {
        sentido = ENCB;
        giro = TRUE;
     }
  }
 

VOID MAIN (VOID)
{

  enable_interrupts(INT_EXT);
  enable_interrupts(GLOBAL);
  ext_int_edge(1,H_TO_L);

  do{
     
     if(giro == TRUE)
        {
        delay_ms (2);
        giro = FALSE;
        if(sentido == DER){
        OUTPUT_HIGH(PIN_B3);
        //DELAY_MS(250);
        OUTPUT_LOW(PIN_B2); 
        }
        else{       //creo que así quedaria, y si colocas dos if podria entrar en los dos si estan produciendose algun rebote

        OUTPUT_HIGH(PIN_B2);

        //DELAY_MS(250);

        OUTPUT_LOW(PIN_B3);

        }
#
 
#
        }
#
     }
#
  while(TRUE); 
#
  }


Desconectado samshiel_pic

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 777
    • Electrónica·Ingenia
Re: Problema con ENCODER
« Respuesta #7 en: 09 de Septiembre de 2010, 18:38:20 »
Pues he probado eso lo que me has comentado mparra y tienes razon con lo de los rebotes y las resistencias pero sigue igual. No se he visto por ahi unos filtros que se le ponen al encoder en los terminales A y B pero no se si servirá.



mira que son simples pues no ahi manera de que funcione. :?
gracias mparra

os dejo el datasheet del encoder.
« Última modificación: 09 de Septiembre de 2010, 18:45:26 por samshiel_pic »

Desconectado mparra

  • PIC10
  • *
  • Mensajes: 8
Re: Problema con ENCODER
« Respuesta #8 en: 13 de Septiembre de 2010, 17:00:21 »
Hola de nuevo, vamos a ver partimos de que este componente es algo comercial y tiene una funcion específica. tiene q generar señal 0 y 1 en terminales A y B. Has una cosa. Primero borra todo ese codigo y parte de cero. Quita interrupciones. y vamos a empezar a analizar la señal de los dos pines. Cuando funcione bien entonces prueba con interrupciones.

Yo haria que la funcion detecte el cambio de estado a 1 en la señal A. y le metes un retardo de 10ms y ahora detecta la puesta a cero de la señal A. Cuando esto se produzca lee la señal B, si es 1 va en un sentido y si es dos va en el otro. Esto es muy simple, y si con esto te falla puedes empezar a pensar que el encoder esta mal. (recientemente me ha pasado con un driver de displays)

Este código tiene que ser superfacil y ademas podrias probarlo sin encoder, colocando a cero fijo la B, y dando y quitando positivo en A con un pulsador y viceversa.

Por cierto no tendrá que ver con las resistencias pullup del puerto B? Yo programo en C18 y no entiendo algunas constantes de configuracion q tienes.

Espero q te funcione al fin.


 

anything