Página 1 de 1

Rotary Encoder

MensagemEnviado: 12 Jan 2011 10:08
por samueldionisio
Pessoal,

Estou precisando inserir um rotary encoder em meu projeto.

Alguem tem um codigo exemplo em C para eu ter como referencia para o desenvolvimento da aplicação?

Obrigado.

MensagemEnviado: 12 Jan 2011 11:50
por _blackmore_
interrupção ... é um caminho ...
entendeu?

MensagemEnviado: 12 Jan 2011 11:53
por enigmabox
Acho que nao é dificil, ligue o canal A do encoder, por exemplo, em um contador interno do MCU(contador 16bits) e o canal Z use para resetar este contador atraves de interrupção ou via hardware no MCU.
Depois a rotina feita em C é só pra ler o valor contido neste contador interno da MCU referente a posição do encoder, dai pra frente vc faz o que quiser com este valor.

:wink:

MensagemEnviado: 12 Jan 2011 12:00
por _blackmore_
outra coisa ... vc precisa saber o sentido da rotação?

Rotary Encoder

MensagemEnviado: 12 Jan 2011 14:45
por samueldionisio
Então preciso sim.

Obrigado.

MensagemEnviado: 12 Jan 2011 15:16
por enigmabox
Então vai ter que ter um RESOLVER.
E no MCU dependendo que for 2 canais de entrada.

MensagemEnviado: 12 Jan 2011 15:23
por die6o
Samuel.
Este rotary encoder é do tipo de decodificação por quadratura ?
Tipo, igual de mouse antigo ?

Se sim, este codigo resolveu perfeitamente para min.


Código: Selecionar todos
  char newA, newB;
  int    *variavel;//ponteiro que vai inc ou deinc variavel do momento

//Separa os dois bits relativos a A e B do encoder incremental
   temp =   (((char *)&IOPIN0)[1]&0x0C)>>2;


//na verdade, você pode fazer da seguinte forma.
//    SE pino A = 1 então variavel pino A = 1 senão variavel pino A = 0;
//    SE pino B = 1 então variavel pino B = 1 senão variavel pino B = 0;
//    DEsta segunda forma voce pode apontar pra qualquer pino do processador, não necessariamente no mesmo port.


           
//faz teste de valor atual com anterior, descobre se houve movimento
    if(temp != oldtemp){
//internamente é testado a posição anterior dos bits e a atual
//desta forma descobre-se se houve movimento incremental ou decremental
//assim incrementa-se duas chars, cada uma relativa ao movimento citado
//no fim do tratamento, compara-se a variavel de acumulo de incremento ou decremento,
//com um valor de sensibilidade, que é relativo a quantidade de movimentos executados.
//se valor de acumulo de movimento > sensibilidade, então incrementa ou decrementa
//o valor da variavel de valor associado a logica do sistema.
   
   if(oldtemp==3 && temp ==2)
     newA++;
   
   if(oldtemp==3 && temp ==1)
   newB++;

   if(oldtemp==2 && temp ==0)
   newA++;
   
   if(oldtemp==2 && temp ==3)
   newB++;

   if(oldtemp==0 && temp ==1)
   newA++;
   
   if(oldtemp==0 && temp ==2)
   newB++;

   oldtemp = temp;

   if(newA>sensi){
   newA=0;
   *variavel+=1;
   }
     if(newB>sensi){
   *variavel-=1;
   newB=0;
   }
   
   }   

Rotary Encoder

MensagemEnviado: 13 Jan 2011 10:51
por samueldionisio
Vou testar.

Obrigado.

T+

Rotary Encoder

MensagemEnviado: 13 Jan 2011 10:53
por samueldionisio
Vou testar o codigo

Obrigado.

T+

MensagemEnviado: 27 Jan 2011 19:08
por eletroinf
Olha... eu tomei uma surra por causa desses encoders...
Porque eu comprei um punhado e o vendedor me mandou um datasheet dizendo que, bastaria pegar uma interrupção, por exemplo na borda de subida; aí testava o outro pino, se estivesse em 0 era um sentido; se estivesse em 1 era outro... só que não funcionava! Aí eu dei uma pesquisada e descobri que o maldito funcionava por um tal código Gray. Pronto! O código de teste que eu fiz aqui num protoboar com z8 encore @ 18MHz é o seguinte:

Código: Selecionar todos
// Interrupção em ambas bordas de PC0.
#pragma interrupt
void Int_PC0(void)
{
   unsigned char cnt;
   
   for(cnt=250; cnt; cnt--)   asm("nop");   // Tempinho.
   
   if(ENC_INT)   
   {
      if(ENC_IN)   encoder++;
      else      encoder--;
         
   }
/*   else      
      {
         //if(!ENC_IN)   encoder++;
         //else      encoder--;
      }*/
   for(cnt=50; cnt; cnt--)   asm("nop");   // Tempinho.
   
   IRQ2   &= 254;   // Limpo o flag de interrupção...
}


Se descomentar o else do meio do código ele capta dois incrementos a cada "tic" no giro do benedito...