Leitura do Encoder E2-Q2
This tutorial is not available in English
Introdução
Existem diversas aplicações em que precisamos saber em que posição o eixo de um motor está, ter um retorno de qual é sua velocidade atual ou até mesmo saber em que sentido o eixo do motor está girando. Nestes casos podemos adicionar um encoder ao eixo do motor (seja ele de entrada ou de saída) e monitorar esses parâmetros que são essenciais nestes tipos de aplicações.
Neste tutorial vamos aprender como usar o módulo encoder E2-Q2 para identificar o sentido e a velocidade de rotação do motor DC com caixa de redução e eixo duplo.
Lista de Materiais
Lista completa de produtos
comprarJulieta V1.0
Encoder E2-Q2
Motor DC 3-6V com Caixa de Redução e Eixo Duplo
Fonte Chaveada 9V 1A
Extensor DC P4 Fêmea
Conceitos Teóricos
Encoder
Um encoder é um dispositivo eletromecânico que é responsável por transformar um movimento ou uma posição em um sinal elétrico. Este tipo de dispositivo costuma ser desenvolvido com um de dois tipos de sensores: os ópticos e os magnéticos (também conhecidos como de efeito Hall). Os encoders baseados em sensores de efeito Hall utilizam um ímã fixado no eixo do motor para identificar a mudança de pólo magnético, como vimos em nosso tutorial sobre o sensor de fluxo de água. Já os encoders com sensores ópticos necessitam de um disco/engrenagem com alguns furos/dentes para identificar a passagem ou a reflexão de luz emitida por um LED, como na imagem a seguir.
Normalmente os encoders geram um sinal analógico nas suas saídas, o que pode dificultar a leitura em microcontroladores, portanto é comum converter esse sinal para uma onda quadrada (digital), por exemplo com um Schmitt Trigger.
Encoder de Quadratura
Embora encoders com um sensor único funcionem muito bem e ajudem a obter a rotação de um motor, eles não são capazes de nos ajudar a identificar em que sentido o motor está girando. Para isso precisamos adicionar mais um sensor ao sistema do encoder, criando um modelo chamado de encoder de quadratura. Este tipo de encoder possui duas saídas de sinais de onda quadrada, e essas ondas possuem uma defasagem ("offset") de 90° entre cada borda de descida ou de subida, como na imagem a seguir.
Por conta dessa defasagem de 90° entre as ondas dos sinais de saída, há uma divergência na sequência lógica de cada canal que permite identificar o sentido de rotação do eixo do motor. A tabela a seguir ilustra a sequência lógica de cada canal, em ambos os sentidos e iniciando em níveis lógicos baixos.
Sequência Lógica | |||
---|---|---|---|
Horário | Anti-Horário | ||
Canal A | Canal B | Canal A | Canal B |
0 | 0 | 0 | 0 |
0 | 1 | 1 | 0 |
1 | 1 | 1 | 1 |
1 | 0 | 0 | 1 |
O módulo encoder fabricado pela RoboCore realiza a leitura da reflexão de luz infravermelha emitida pelo sensor QRE, que é retornada para o sensor quando um dente da engrenagem do kit está sobre o componente. E, como ele é composto de dois sensores QRE, ele também é um encoder de quadratura, portanto utilizaremos essa sequência lógica para determinar o sentido de rotação do motor deste tutorial.
Montagem Mecânica
Antes de mais nada, siga o manual do botão abaixo para fixar o módulo encoder na lateral do motor e prender o disco de seis dentes ao eixo do motor.
Manual de MontagemCircuito
Com o conjunto completo fixado, monte o circuito a seguir.
Código
Agora que o circuito está montado, carregue o código a seguir para sua placa.
Observação: se você estiver utilizando um encoder com disco de leitura de 10 dentes, altere o valor da variável
NUMERO_DENTES
de 6 para 10, como mencionado no comentário do código.
Entendendo o Código
O código inicia com a declaração das variáveis que armazenam os pinos de controle do motor DC da Julieta (PINO_INA
e PINO_ENA
), os pinos conectados aos botões embutidos da placa (PINO_BOTAO1
e PINO_BOTAO2
) e os pinos conectados aos canais do encoder (PINO_CH1
e PINO_CH2
).
Em seguida declaramos as variáveis estado
, ultimo_estado
e sentido
, que armazenam o estado atual de leitura de um dos canais, o estado anterior da leitura do mesmo canal e o sentido em que o eixo do motor está girando. Além disso, declaramos dois contadores, um para cada canal do encoder, juntamente com três variáveis constantes que nos ajudarão a converter os pulsos contados nos canais do encoder para um valor de rotação. Por fim, temos a declaração das variáveis tempo_antes
e MINUTO
, que serão responsáveis por realizar um período de espera de um minuto.
Já na rotina de configurações do código, configuramos os pinos de controle do motor DC da Julieta como saídas do sistema com um nível lógico baixo inicial, os pinos conectados aos botões embutidos da Julieta como entradas com "pull-up" ativado (INPUT_PULLUP
), e os pinos conectados aos canais do encoder como entradas do sistema. Por fim, inicializamos as duas interrupções do código, uma para cada porta de interrupção usada (os mesmos pinos conectados aos canais do encoder), que são responsáveis por chamar as funções contador_pulso1()
e contador_pulso2()
a cada mudança de nível lógico da porta da placa (CHANGE
), seja ele de alto ("HIGH") para baixo ("LOW"), ou vice versa.
A repetição do código, por sua vez, inicia com a verificação se um dos botões internos da Julieta foi pressionado, com a condição if (digitalRead(PINO_BOTAO1) == LOW || digitalRead(PINO_BOTAO2) == LOW)
, e então, depois de um debounce (delay(30)
), verificamos qual dos botões foi pressionado usando a condição if (digitalRead(PINO_BOTAO1) == LOW)
, que é seguida da condição else
para o segundo botão do sistema. Caso um dos botões seja pressionado, o motor DC é controlado para o sentido correspondente. Juntamente com isso e independentemente do botão pressionado, nós zeramos os contadores do código, atualizamos a contagem de tempo do sistema, paramos o motor por meio do comando analogWrite(PINO_ENA, 0)
, aguardamos um segundo (delay(1000)
) para o motor parar completamente, e, por fim, realizamos a rampa de aceleração do motor.
Em seguida, verificamos se já se passou um minuto da contagem de tempo do sistema, pela condição if ((millis() - tempo_antes) > MINUTO)
. Se sim, o código verifica por meio da condição if (sentido)
se a variável sentido
é verdadeira ou não. Para o sentido horário, a variável sentido
é verdadeira ("true"), e para o sentido anti-horário ela é falsa ("false"). Além disso, declaramos a variável media
sendo igual à média de contagem dos dois sensores, que é equivalente à soma dos dois contadores (contador1
e contador2
) dividida pela variável NUMERO_CONTADORES
, que é igual a "2". Com a variável media
calculada, nós a utilizamos na declaração e atribuição de valor da variável velocidade
, que recebe o valor da média calculada dividida pelo produto da variável NUMERO_DENTES
, que é igual a "6", com a variável NUMERO_LEITURAS
, que é igual a "2" porque lemos as bordas de subida e de descida. Para finalizar esse laço, os contadores são zerados e atualizamos a contagem de tempo do sistema.
Ao final do código, temos as duas funções chamadas pelas interrupções. A função contador_pulso1()
é responsável apenas por incrementar em uma unidade o contador contador1
. Já a função contador_pulso2()
, além de incrementar o contador contador2
, também verifica o sentido de rotação do motor.
Essa lógica de verificação de sentido do motor começa atribuindo a leitura digital do pino conectado ao canal 2 do encoder à variável estado
. Feito isso, verificamos através da condição if (ultimo_estado == LOW && estado == HIGH)
se o sinal do canal 2 passou de baixo ("LOW") para alto ("HIGH") entre as interrupções. Se essa condição for verdadeira, verificamos se a leitura digital do pino conectado ao canal 1 do encoder está em nível lógico baixo ("LOW"). Se essa condição for verdadeira, sabemos que o eixo do motor está girando no sentido horário, então atribuímos o valor "true" à variável sentido
. Entretanto, se a condição for falsa, sabemos que o eixo do motor está girando no sentido anti-horário, portanto atribuímos o valor "false" à variável sentido
. Por fim, atualizamos a variável ultimo_estado
com o valor que foi atribuído anteriormente à variável estado
.
O Que Deve Acontecer
Após carregar o código para a placa, alimente-a com a fonte de 9 V e pressione o botão "Btn0" ou "Btn1" para que o motor gire em um dos sentidos. Após um minuto, o monitor serial apresentará o sentido de rotação atual do motor e sua velocidade em Rotações por Minuto (RPM), como na imagem abaixo. Se quiser alterar o sentido de rotação do motor, basta pressionar o outro botão da placa, que o motor irá parar, e então partir no sentido contrário.
Indo Além
Com os conceitos que aprendemos neste tutorial, é possível controlar a velocidade do eixo do motor, basicamente como um servomotor, como mostramos em nosso tutorial Controle de Velocidade com Encoder E2-Q2. Outra possibilidade com o módulo encoder é o cálculo da distância percorrida por uma roda, por exemplo.
Conclusão
Neste tutorial aprendemos sobre o funcionamento de um encoder de quadratura e como aproveitar os seus sinais de saída para identificar o sentido de rotação do eixo do motor, assim como calcular a sua rotação.