Conhece o encoder rotativo? Por fora, ele é um componente muito parecido com um potenciômetro, mas internamente funciona de uma forma bem diferente, sendo um componente interessante para você utilizar com seus projetos para Arduino. Eu utilizei um módulo encoder KY-040 para criar um pequeno sistema de seleção com display LCD 20×4.

como utilizar um encoder rotatico com Arduino

encoder é um componente utilizado para conversão de movimentos rotativos (ou lineares) em impulsos elétricos de onda quadrada. Esse impulsos podem ser lidos por um microcontrolador (no nosso caso, vamos utilizar o Arduino), e geram uma quantidade exata de impulsos por volta.

O encoder que utilizamos tem rotação contínua, e também um botão (basta empurrar o eixo) que vamos usar para selecionar uma das opções do “menu” no display. 

Módulo Encoder KY-040

Ligando o encoder no Arduino

O primeiro circuito de testes utiliza somente o encoder. Vamos utilizar 3 pinos do Arduino para ligar o componente, sendo que os pinos analógicos A2 e A3 serão ligados nos pinos de medição, e o pino digital 7 no pino do botão, junto com um resistor pull-up.

Circuito básico módulo

Caso você esteja utilizando somente o encoder (sem o módulo, siga o esquema ligação abaixo:

Circuito básico encoder rotativo

Teste esse circuito carregando o programa abaixo, que utiliza a biblioteca RotaryEncoder(download). Baixe a biblioteca e coloque-a na pasta LIBRARIES da IDE do Arduino.

//Programa : Teste basico encoder Arduino
//Autor : Arduino e Cia

//Carrega a biblioteca do encoder
#include <RotaryEncoder.h>

//Pinos de ligacao do encoder
RotaryEncoder encoder(A2, A3);

//Variavel para o botao do encoder
int valor = 0;
int newPos = 0;

void setup()
{
  pinMode(7, INPUT);
  Serial.begin(9600);
  Serial.println("Gire o encoder....");
}

void loop()
{
  //Verifica se o botao do encoder foi pressionado
  valor = digitalRead(7);
  if (valor != 1)
  {
    Serial.println("Botao pressionado");
    while (digitalRead(7) == 0)
      delay(10);
  }

  //Le as informacoes do encoder
  static int pos = 0;
  encoder.tick();
  int newPos = encoder.getPosition();
  //Se a posicao foi alterada, mostra o valor
  //no Serial Monitor
  if (pos != newPos) {
    Serial.print(newPos);
    Serial.println();
    pos = newPos;
  }
}

O programa aguarda que o usuário gire o encoder para a direita ou para a esquerda, atualizando o valor de um contador. Girando para a direita, o contador aumenta, e para a esqueda, o contador diminui. Caso o botão seja pressionado, uma mensagem também aparece no serial monitor:

Teste encoder Arduino

Esse é um circuito bem simples que você pode usar para testar se o seu encoder está funcionando corretamente.

Sistema de menu com display LCD 20×4 e encoder rotativo

Neste segundo circuito, vamos manter as ligações do encoder que utilizamos anteriormente, e adicionar um display LCD 20×4 ao circuito. O potenciômetro é de 10K e serve para ajustar o contraste do display. O resistor utilizado como pull-up do botão do encoder é de 330 ohms.

Circuito Arduino LCD 20x4

No programa deste circuito, vamos primeiramente criar caracteres customizados para os números de 1 a 6 que forem selecionados (são os números “invertidos”). Conforme giramos o encoder, os números no display vão sendo substituídos por esses número invertidos.

No loop, testamos se o botão foi pressionado, e também limitamos as opções de seleção entre 1 e 6, através do comando encoder.setPosition(). O programa checa se o valor do encoder foi alterado e, em caso positivo, chama a rotina  destaque_selecionado(), que atualiza os dados da tela.

//Programa : Menu com encoder e LCD 20x4
//Autor : Arduino e Cia

//Carrega biblioteca LCD e encoder
#include <LiquidCrystal.h>
#include <RotaryEncoder.h>

//Inicializa o LCD
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);

//Pinos de ligacao do encoder
RotaryEncoder encoder(A2, A3);

int contador = 1;
int contador_anterior = 1;
int valor = 0;


byte Bloco_Cheio[8]  = {0b11111, 0b11111, 0b11111, 0b11111,
                        0b11111, 0b11111, 0b11111, 0b11111
                       };
byte Um_invertido[8] = {0b11011, 0b10011, 0b11011, 0b11011,
                        0b11011, 0b11011, 0b10001, 0b11111
                       };
byte Dois_invertido[8] = {0b10001, 0b01110, 0b11110, 0b11101,
                          0b11011, 0b10111, 0b00000, 0b11111
                         };
byte Tres_invertido[8] =  {0b00000, 0b11101, 0b11011, 0b11101,
                           0b11110, 0b01110, 0b10001, 0b11111
                          };
byte Quatro_invertido[8] = {0b11101, 0b11001, 0b10101, 0b01101,
                            0b00000, 0b11101, 0b11101, 0b11111
                           };
byte Cinco_invertido[8] = {0b00000, 0b01111, 0b00001, 0b11110,
                           0b11110, 0b01110, 0b10001, 0b11111
                          };
byte Seis_invertido[8] = {0b11001, 0b10111, 0b01111, 0b00001,
                          0b01110, 0b01110, 0b10001, 0b11111
                         };

static int pos = 1;
int newPos = 0;
int selecionado = 0;

void setup()
{
  Serial.begin(9600);
  //Inicializa o botao do encoder no pino 7
  pinMode(7, INPUT);
  //Define o LCD com 20 colunas e 4 linhas
  lcd.begin(20, 4);
  //Cria os caracteres customizados
  lcd.createChar(0, Bloco_Cheio);
  lcd.createChar(1, Um_invertido);
  lcd.createChar(2, Dois_invertido);
  lcd.createChar(3, Tres_invertido);
  lcd.createChar(4, Quatro_invertido);
  lcd.createChar(5, Cinco_invertido);
  lcd.createChar(6, Seis_invertido);

  //Informacoes iniciais
  lcd.setCursor(0, 0);
  lcd.print("  1  2  3  4  5  6");
  lcd.setCursor(1, 2);
  lcd.print("Valor atual: 0");
  lcd.setCursor(1, 3);
  lcd.print("Selecionado: -");
}

void loop()
{
  //Verifica se o botao do encoder foi pressionado
  valor = digitalRead(7);
  Serial.println(valor);
  if (valor != 1)
  {
    Serial.println("Botao pressionado");
    lcd.setCursor(14, 3);
    selecionado = newPos;
    lcd.print(selecionado);
    //while (digitalRead(7) == 1)
    //  delay(10);
  }

  //Le as informacoes do encoder
  encoder.tick();
  newPos = encoder.getPosition();
  if (pos != newPos)
  {
    //Limite maximo menu
    if (newPos > 6)
    {
      encoder.setPosition(6);
      newPos = 6;
    }
    //Limite minimo menu
    if (newPos < 1)
    {
      encoder.setPosition(1);
      newPos = 1;
    }
    Serial.print("Posicao: ");
    Serial.println(newPos);
    //Atualiza o menu no display
    destaque_selecionado(newPos);
    pos = newPos;
  }
}

void destaque_selecionado(int conta)
{
  //Define posicao inicial
  int posicao = (conta * 3) - 1;
  //Apaga selecao anterior
  if (conta > pos)
  {
    lcd.setCursor(posicao - 4, 0);
    lcd.print(" ");
    lcd.print(conta - 1);
    lcd.print(" ");
  }
  //Apaga selecao posterior
  if (conta < pos)
  {
    lcd.setCursor(posicao + 2, 0);
    lcd.print(" ");
    lcd.print(conta + 1);
    lcd.print(" ");
  }

  //Imprime blocos cheios
  lcd.setCursor(posicao - 1, 0);
  lcd.write((uint8_t)0);
  lcd.write((uint8_t)0);
  lcd.write((uint8_t)0);

  //imprime valor
  lcd.setCursor(posicao, 0);
  lcd.write((uint8_t)(conta));

  //Imprime Opcao atual
  lcd.setCursor(14, 2);
  lcd.print(conta);
}

Achou a explicação muito complicada ? Dê uma olhada no vídeo abaixo, que mostra esse circuito em funcionamento:

O programa atualiza os valores somente na tela, mas você pode modificar facilmente este programa para que ele acione portas do Arduino ou envie e receba dados de algum sensor.

Gostou? Use este encoder também com Raspberry Pi! Confira no post Como usar encoder rotativo com Raspberry Pi.

5/5 - (2 votes)