Autor Tema: INterrupcion de MPG, no detecta el sentido de giro  (Leído 3501 veces)

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

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
INterrupcion de MPG, no detecta el sentido de giro
« en: 10 de Julio de 2012, 15:54:52 »
USo una interrupcion para contar puloso de un MPG y no funciona bien,
No detecta el sentido de giro correctamente. Esta escrito en Hitec y el original, que no funciona bien es esta rutina

// GESTION DEL MPG POR INTERRUCION SE USA INT0
// LA INTERRUPCION DETECTA EL SENTIDO DE GIRO Y MANTIENE UN CONTADOR
//************************************************************************
void interrupt Isr(void) 
{
 if (SSPIF)   
    {
     SSPIF = 0;   
     isrEnd = 1;
    }
 if (INTF) // interrupcion mpg2 pines rb0(a) y rb1(b) la resolucion es X1
     {
      (RB1) ? MPG++: MPG--; // esto es un if un poco raro jejeje
      INTF=0; // fin de la int para MPG a X1
     }
}


YO la he modificado asi, pero tampoco detecta el sentido , si los pulsos, es decir como la anterior.


//************************************************************************
// Funcion que verifica el valor de un bit de una variable
//  Devuelve el valor del bit que se chequea
//************************************************************************

int bittest(var,bitno){
int var_int=0;
if(bitno==0)
   var_int = var & 0x00000001;
if(bitno==1)
   var_int= var &0x00000010;   
return var_int;
}


//************************************************************************
// SERVICIOS DE INTERRUPCION
//
//
//
// GESTION DEL MPG POR INTERRUCION SE USA INT0
// LA INTERRUPCION DETECTA EL SENTIDO DE GIRO Y MANTIENE UN CONTADOR
//************************************************************************
//como hacer un test de un bit
// variable_aux = variable & 0b00000010;
// si el bit 1 de variable estaba en 1, el resultado de la and es 2.
// if (variable_aux == 2) ....   
// evaluo el valor, para saber si el bit estaba en 1


void interrupt Isr(void) 
{
 if (SSPIF)   
    {
     SSPIF = 0;   
     isrEnd = 1;
    }
 if (INTF) // interrupcion mpg2 pines rb0(a) y rb1(b) la resolucion es X1
     {
      lec_mpg=(RB1*2)+RB0; // carga en mpg el valor en gray de las entradas RB0 y RB1
   

     if(bittest(lec_mpg,1)==1)        // si el bit 1 de valor es 1
         {
         if(bittest(lec_mpg,0)==0)     // invierte el bit 0 de valor
            bitset(lec_mpg,0);         // hace 1 el bit 0 de valor
         else
            bitclr(lec_mpg,0);      // hace cero el bit 0 de valor
         }
       
   if(lec_mpg!=lec_mpg_old){
      diferencia =lec_mpg-lec_mpg_old;
      if(bittest(diferencia,0) == 0)   // si se ha producido un error se habra puesto a cero el bit 0
            {
           
         } 
         else
            {   
            if(bittest(diferencia,1) == 1) // chequea el bit de sentido de giro que sera 1 girando a derecha
               MPG++;                // si es hacia un lado incrementa el contador
            else
               MPG--;            // hacia el otro lo decrementa
            }
           // memoriza en anterior_Z el estado actual
            lec_mpg_old  = lec_mpg;

         
   }      
      

Podeis echarme una mano, no se casi nada de hitec, por no decir nada. Siempre he trabajado en CCS.


Gracias

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #1 en: 15 de Julio de 2012, 12:42:23 »
Sigo liado con esto, me he dado cuenta de que Hitec no gestiona las interrupciones como lo hace CCS.
Creia que la interrupcion que se activaba en Hitec era la INT_RB del CCS pero no es asi, ya que los pines que detecta son RB0 Y RB1 y eso no es en CCS.
En CCS INT_RB vigila RB3 al RB7.
A ver quien me traduce esto, porque no se quien genera la interrupcion y eso puede ser parte del problema.

EN Hitec esta asi

// GESTION DEL MPG POR INTERRUCION SE USA INT0
// LA INTERRUPCION DETECTA EL SENTIDO DE GIRO Y MANTIENE UN CONTADOR
//************************************************************************
void interrupt Isr(void) 
{
 if (SSPIF)   
    {
     SSPIF = 0;   
     isrEnd = 1;
    }
 if (INTF) // interrupcion mpg2 pines rb0(a) y rb1(b) la resolucion es X1
     {
      (RB1) ? MPG++: MPG--; // esto es un if un poco raro jejeje
      INTF=0; // fin de la int para MPG a X1
     }
}
 

Esta interrupcion es cierto que vigila cambios de estado de RB0 Y RB1?
Si es asi como se haria en CCS? ya que no me sirve INT_RB y no se que haya nada que haga eso.



Sigo teniendo elmismo problema , en HiTEC no consigo que se discrimine el sentido de giro del MPG porque esta rutina de interrupcion no va bien. Asi que trato de enmendarla en CCS que es lo que conozco pero me encuentro problemas porque no se que hace Hitec.
Quien me puede echar una manita que sepa de Hitec?

Mil gracias

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #2 en: 15 de Julio de 2012, 19:16:49 »
Rehice la rutina y compila bien. Aun no pude probarla en hardware, pero a ver quien puede decirme si me equivoco en algo y quien demonios activa la rutina de interrupcion....No me entero de como va el HITEC

Código: C
  1. //************************************************************************
  2. // SERVICIOS DE INTERRUPCION
  3. //
  4. //
  5. //
  6. // GESTION DEL MPG POR INTERRUCION SE USA INT0
  7. // LA INTERRUPCION DETECTA EL SENTIDO DE GIRO Y MANTIENE UN CONTADOR
  8. //************************************************************************
  9.  
  10. void interrupt Isr(void)  
  11. {
  12.  if (SSPIF)    
  13.          {
  14.           SSPIF = 0;  
  15.           isrEnd = 1;
  16.          }
  17.  
  18.  
  19.  if (INTF) // interrupcion mpg2 pines rb0(a) y rb1(b) la resolucion es X1
  20.           {
  21.            lec_mpg=(PORTB && 0x00000011); // carga en mpg el valor leido del encoders MPG, que estara en codigo gray, de las entradas RB0 y RB1
  22.                 // codigo gray
  23.                 //  00    0
  24.                 //  01    1
  25.                 //  11    3
  26.                 //  10    2
  27.                 //  00    0
  28.                 //  ....
  29.    
  30. // convierte de gray a decimal
  31.  
  32.                 // codigo gray      decimal
  33.                 //  00    0                       00    0      
  34.                 //  01    1                       01    1      
  35.                 //  11    3           10        2
  36.                 //  10    2           11        3
  37.                 //  00    0           00    0
  38.                 //  ....                          ........
  39.  
  40. // para pasar de gray a decimal se vigila el bit de mayor peso, si es uno, se invierte el bit de menor peso, si no queda como estaba
  41.  
  42.  
  43.  
  44.                 if(((lec_mpg && 0x00000010))==2)  // si el bit 1 de lec_mpg es ==1       
  45.                 {
  46.                 if(((lec_mpg && 0x00000001)==0))        // si el bit 0 de lec_mpg  es cero
  47.                                 bitset(lec_mpg,0);         // hace 1 el bit 0 de valor
  48.                 else
  49.                 bitclr(lec_mpg,0);      // hace cero el bit 0 de valor
  50.                
  51.                         // aqui lec_mpg es decimal
  52.                         // calcula la diferencia entre el anterior y el actual
  53.                        
  54.                         diferencia = lec_mpg - lec_mpg_old;    
  55.                        
  56.                         // si el bit 1 de diferencia es == 1 es que esta girando a derecha
  57.  
  58.                         if(((diferencia && 0x00000010)==2)) // chequea el bit de sentido de giro que sera 1 girando a derecha
  59.                MPG++;                // si es hacia un lado incrementa el contador
  60.             else
  61.                MPG--;            // hacia el otro lo decrementa
  62.             }
  63.          
  64.                         // memoriza el valor  actual
  65.             lec_mpg_old  = lec_mpg;
  66.  
  67.         }              
  68.         INTF=0; // fin de la int para MPG a X1
  69. }
  70.  
  71.  
  72. // *****************************
  73. // ACTIVAR INTERRUPCIONES
  74. // *****************************
  75.  
  76. void setISR(void) /*Sets ISR bits */
  77. {
  78. GIE = 0;
  79. PEIE = 0;
  80. RCIE = 0;
  81. SSPIE = 0;
  82. EEIE = 0;
  83. INTE=  1; // Activar interrupcion INT0
  84. RBIE = 0; // DESActivar interrupciones on pin change del puerto B
  85. MPG = 0;  // Inicializa contador MPG
  86. GIE = 1;  // permite las ints (todas las activadas)
  87. }


Cualquier cambio de RB0 o RB1 activaria esta interrupcion?
Eso es lo que debe hacer, ya que el encoder esta en esos pines.
« Última modificación: 16 de Julio de 2012, 01:54:57 por un Moderador »

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #3 en: 16 de Julio de 2012, 01:56:41 »
Me he permitido modificar tu post para meterle format GeSHi al código y que se entienda mejor.

Tampoco conozco Hitech pero deduzco que para que se active la interrupción se hace escribiendo directamente los registros del micro.

Código: C
  1. void setISR(void) /*Sets ISR bits */
  2. {
  3. GIE = 0;
  4. PEIE = 0;
  5. RCIE = 0;
  6. SSPIE = 0;
  7. EEIE = 0;
  8. INTE=  1; // Activar interrupcion INT0
  9. RBIE = 0; // DESActivar interrupciones on pin change del puerto B
  10. MPG = 0;  // Inicializa contador MPG
  11. GIE = 1;  // permite las ints (todas las activadas)
  12. }

En esta función has desactivado las interrupciones pin change del puerto B. ¿No tendrías que poner RBIE=1?

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #4 en: 16 de Julio de 2012, 08:31:44 »
A ver eso es copiado del original, y el original funciona pero no determina el sentido de giro.
Ya he probado la nueva compilacion y esa no funciona, no entra en la interrupcion o al menos no aumenta ni disminuye MPG
Yo creo que el problema esta en que no se esta detectando los cambios de RB0 Y RB1 y que la interrupcion no se ejecuta.
EN el original (esta el codigo en el post) detecta algo y arranca la interrupcion, pero no detecta sentido de giro, es mas detecta el que le parece.
En la modificacion ultima mia, deberia funcionar si no me equivoque en algo pero no se ejecuta la interrupcion o al menos no aumenta ni disminuye MPG.
No puedo testearlo en Proteus porque no se como, asi que solo puedo modificar compilar y probar en hardware.
Una cuestion para mi es, esa interrupcioon arranca al cambiar el estado de RB0 y RB1?
Si en CCS INT_RB solo vigila rb4 al 7 como hace esto Hitec?

Una cosa mas,,,,,,Nocturno...ya no se que decirte, siempre sales en mi ayuda.
Mil gracias de nuevo, con gente como tu el mundo iria mejor seguro.


Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #5 en: 16 de Julio de 2012, 08:56:19 »
Pero en el código original la interrupción que se levanta es la de INT0, que suele estar en RB0.
Si es así, sólo habría que comprobar si RB1 es alto o bajo para saber el sentido de giro.
No se están usando las interrupciones por cambio de estado, así que retiro lo dicho en el post anterior.

¿Cómo lo tienes conectado?

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #6 en: 16 de Julio de 2012, 09:00:43 »
A ver no estoy muy de acuerdo en que si se ejecuta la rutina cuando cambia de estado RB0 solamente, sin tener en cuenta el cambio de RB1 , depende del estado de RB1 si es alto o bajo, esta girando a derecha o izda.
Eso es lo que dice Siliconio cuando hizo la rutina, pero lo cierto es que no funciona asi.
El problema es claro, no sabe para que lado va en la rutina original.
Ejecuta la interrupcion pero dtecta el sentido que le parece

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #7 en: 16 de Julio de 2012, 11:12:48 »
Vale ya he visto como es. tuve que tirar de libros etc, y tratar de recordar algo de ensamblador y demas.
La interrupcion con el programa original se genera con el flanco de subida de RB0 solamente. EN ese caso he estado mirando y tienes razon (como siempre jajaja) . Si el estado de RB1 es positivo cuando llega ese flanco esta girando hacia un lado, si es negativo gira hacia  el otro.
Bien parece que el programa deberia estar bien, pero lo cierto es que no detecta el sentido de giro. He probado con dos encoders, uno puramente mecanico y el otro es uno comercial industrial electronico optico y que con el osciloscopio va perfecto, (el mecanico tambien)
Quizas cambiando el pic por uno de mayor velocidad la rutina de interrupcion se ejecute mejor? mas rapido? y esa pueda ser la causa?
Usa uno de 4 Mhhz, Pruebo con 12 Mhz?
Tambien he pensado en poner algo a la salida del encoder y que adapte mejor la señal, incluso hacer un divisor que divida por 4 los pulsos para que lleguen menos. Es posible que sea eso? o quizas algo que mejore mas la señal? Ya tiene resistencias de pullup y no se que mas hacer.
La verdad me tiene aburrido.
Alguien tiene  el siliconio Modbus para mach3 funcionando con MPG y le va bien?
Lo demas del modbus va perfecto, pero necesitaria eso....es casi imprescindible.



Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #8 en: 16 de Julio de 2012, 13:05:02 »
Insisto, cuelga el esquema, sospecho que debe ser algo sencillo y no lo vemos por no tenerlo delante.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #9 en: 16 de Julio de 2012, 14:40:51 »
vale luego lo cuelgo

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #10 en: 17 de Julio de 2012, 16:16:52 »
Ahi va a ver que me decis

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #11 en: 18 de Julio de 2012, 01:31:14 »
Lo he intentado abrir y no puedo con Altium, supongo que será Eagle. ¿Te importa convertirlo a PDF o JPG?

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #12 en: 18 de Julio de 2012, 08:54:18 »
Ahi lo llevas en JPG. El encoder esta conectado entre RB0, RB1, 5 V y cero.

Desconectado Algec

  • Colaborador
  • PIC24F
  • *****
  • Mensajes: 974
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #13 en: 18 de Julio de 2012, 08:54:52 »
Se me paso subirlo

Desconectado Nocturno

  • Administrador
  • DsPIC33
  • *******
  • Mensajes: 18286
    • MicroPIC
Re: INterrupcion de MPG, no detecta el sentido de giro
« Respuesta #14 en: 18 de Julio de 2012, 09:30:58 »
No veo nada raro en el esquema.
Pero revisando el código sí que he encontrado algo. Este trozo de código está dentro de la interrupción:

Código: C
  1. if(((lec_mpg && 0x00000010))==2)  // si el bit 1 de lec_mpg es ==1       
  2.                 {
  3.                 if(((lec_mpg && 0x00000001)==0))        // si el bit 0 de lec_mpg  es cero
  4.                                 bitset(lec_mpg,0);         // hace 1 el bit 0 de valor
  5.                 else
  6.                 bitclr(lec_mpg,0);      // hace cero el bit 0 de valor
  7.                
  8.                         // aqui lec_mpg es decimal
  9.                         // calcula la diferencia entre el anterior y el actual
  10.                        
  11.                         diferencia = lec_mpg - lec_mpg_old;

Habíamos quedado en que la interrupción se produce en el flanco ascendente de INT0, o lo que es igual, cuando entres en la interrupción el pin RB0 siempre estará a 1.
Si esto es cierto, esta condición nunca se cumplirá:
if(((lec_mpg && 0x00000001)==0))   // si el bit 0 de lec_mpg  es cero

¿Estoy en lo cierto o lo he interpretado mal?