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.
O 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.
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.
Caso você esteja utilizando somente o encoder (sem o módulo, siga o esquema ligação abaixo:
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:
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.
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.