Arduino UNO R4 - Encoder Rotativo

Neste guia, vamos aprender a usar um encoder incremental com o Arduino UNO R4. Vamos ver:

Arduino UNO R4 encoder rotativo

Sobre o Encoder Rotativo

Um encoder rotativo é um dispositivo que transforma o movimento de rotação em um sinal elétrico. Ele verifica a rotação e a posição de um eixo ou botão giratório. Existem dois tipos principais:

  • Encoder incremental: cria pulsos para medir mudanças de posição.
  • Encoder absoluto: fornece um código digital único para cada posição, o que o torna perfeito para posicionamento preciso, mesmo se a energia acabar.

Este tutorial é sobre o encoder incremental.

Pinagem do Módulo Encoder Rotativo

pinagem do encoder rotativo

Um módulo encoder rotativo vem com quatro pinos:

  • Pino CLK (Saída A): este pino envia um sinal toda vez que você gira o botão um clique em qualquer direção, mostrando um ciclo completo de sinal de LOW para HIGH e para LOW. Isso nos diz o quanto o botão foi girado.
  • Pino DT (Saída B): semelhante ao pino CLK, mas o sinal deste pino chega um pouco atrasado, ocorrendo 90 graus depois do sinal CLK. Esse atraso nos ajuda a determinar se a rotação é no sentido horário ou anti-horário.
  • Pino SW: ele se conecta ao botão de pressão interno do encoder, que normalmente fica aberto. Usando um resistor pull-up neste pino, ele mostra HIGH quando o botão não está pressionado e LOW quando está pressionado.
  • Pino VCC (+): conecte este pino a uma fonte de alimentação que forneça entre 3,3 e 5 volts.
  • Pino GND: conecte este pino ao terra (0V).

Encoder Rotativo vs Potenciômetro

Você pode confundir o encoder rotativo com o potenciômetro, mas são componentes diferentes. Veja como eles se comparam:

  • Um encoder rotativo pode girar completamente e de forma contínua, mas um potenciômetro só pode girar cerca de três quartos de uma volta completa.
  • Um encoder rotativo envia pulsos, enquanto um potenciômetro envia tensão analógica.
  • Um encoder rotativo é útil para saber quanto um botão girou, mas não sua posição exata. Um potenciômetro é bom para descobrir a posição precisa de um botão.

Como o Encoder Rotativo Funciona

saída do encoder rotativo

No encoder, há um disco com ranhuras ligado a um pino chamado C, que atua como um terra comum. Também há dois pinos adicionais, A e B.

  • Quando você gira o botão, os pinos A e B fazem contato com o pino de terra comum C, mas em uma sequência específica que depende da direção da rotação, horária ou anti-horária.
  • Esse contato gera dois sinais com temporização ligeiramente diferente, porque um pino se conecta ao terra antes do outro. Esses sinais ficam defasados em 90 graus, e isso se chama codificação em quadratura.
  • Girar o botão no sentido horário faz o pino A tocar o terra antes do pino B. Girá-lo no sentido anti-horário faz o pino B tocar o terra antes do pino A.
  • Observando quando cada pino faz ou desfaz o contato com o terra, podemos determinar a direção de rotação do botão. Fazemos isso analisando as mudanças do pino B em relação ao pino A.
Como o encoder rotativo funciona

Quando A muda de LOW para HIGH:

  • Girou no sentido horário se B estiver LOW.
  • Girou no sentido anti-horário se B estiver HIGH.

※ Nota:

Os pinos A e B estão ligados aos pinos CLK e DT. A disposição pode variar de acordo com o fabricante. Os códigos apresentados aqui foram testados com o encoder rotativo da DIYables.

Como Programar para o Encoder Rotativo

  • Verifique o sinal do pino CLK.
  • Quando o sinal mudar de LOW para HIGH, verifique o que o pino DT está mostrando.
    • Se o pino DT mostrar HIGH, o botão foi girado no sentido anti-horário. Some 1 ao contador.
    • Se o pino DT mostrar LOW, o botão foi girado no sentido horário. Subtraia 1 do contador.

Diagrama de Ligação

Diagrama de Ligação do encoder rotativo com Arduino UNO R4

This image is created using Fritzing. Click to enlarge image

Veja A melhor forma de alimentar o Arduino Uno R4 e outros componentes.

Código Arduino UNO R4 – Encoder Rotativo sem Interrupção

Este código do Arduino UNO R4 realiza as seguintes ações:

  • Detecta como e quanto o encoder gira.
    • Se detectar que o botão foi girado um clique para a direita, soma um ao contador.
    • Se detectar que o botão foi girado um clique para a esquerda, reduz o contador em um.
  • Percebe se o botão foi pressionado.
/* * Este código de Arduino UNO R4 foi desenvolvido por pt.newbiely.com * Este código de Arduino UNO R4 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 2 // The Arduino UNO R4 pin connected to the CLK pin of encoder #define DT_PIN 3 // The Arduino UNO R4 pin connected to the DT pin of encoder #define SW_PIN 4 // The Arduino UNO R4 pin connected to the SW pin of encoder #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction int counter = 0; int direction = DIRECTION_CW; int CLK_state; int prev_CLK_state; ezButton button(SW_PIN); // create ezButton object that attach to pin 4 void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // read the initial state of the rotary encoder's CLK pin prev_CLK_state = digitalRead(CLK_PIN); } void loop() { button.loop(); // MUST call the loop() function first // read the current state of the rotary encoder's CLK pin CLK_state = digitalRead(CLK_PIN); // If the state of CLK is changed, then pulse occurred // React to only the rising edge (from LOW to HIGH) to avoid double count if (CLK_state != prev_CLK_state && CLK_state == HIGH) { // if the DT state is HIGH // the encoder is rotating in counter-clockwise direction => decrease the counter if (digitalRead(DT_PIN) == HIGH) { counter--; direction = DIRECTION_CCW; } else { // the encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } Serial.print("DIRECTION: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" | COUNTER: "); Serial.println(counter); } // save last CLK state prev_CLK_state = CLK_state; if (button.isPressed()) { Serial.println("The button is pressed"); } }

Usamos a biblioteca ezButton para simplificar o código de debounce do botão.

Passos Rápidos

Siga estas instruções passo a passo:

  • Se esta é a sua primeira vez usando o Arduino Uno R4 WiFi/Minima, consulte o tutorial sobre como configurar o ambiente para o Arduino Uno R4 WiFi/Minima na Arduino IDE.
  • Conecte o encoder rotativo ao Arduino UNO R4 de acordo com o diagrama fornecido.
  • Conecte a placa Arduino Uno R4 ao seu computador usando um cabo USB.
  • Abra a Arduino IDE no seu computador.
  • Selecione a placa Arduino Uno R4 apropriada (por exemplo, Arduino Uno R4 WiFi) e a porta COM.
  • Adicione a biblioteca ezButton à Arduino IDE. Para ver as instruções, acesse este link: [biblioteca ezButton](https://arduinogetstarted.com/tutorials/arduino-button-library#content_how_to_install
  • Copie o código fornecido e abra-o na Arduino IDE.
  • Clique no botão Upload na Arduino IDE para carregar o código no Arduino UNO R4.
  • Gire o botão no sentido horário e depois no sentido anti-horário.
  • Pressione o botão.
  • Verifique os resultados no Serial Monitor.
∞
Newbiely | Arduino IDE 2.3.8
──
☐
✕
File
Edit
Sketch
Tools
Help
Arduino Uno R4 WiFi
Newbiely.ino
···
8 Serial.println("Hello World!");
Output
Serial Monitor
Message (Enter to send message to 'Arduino Uno R4 WiFi' on 'COM15')
New Line
9600 baud
DIRECTION: Clockwise | COUNTER: 1 DIRECTION: Clockwise | COUNTER: 2 DIRECTION: Clockwise | COUNTER: 3 DIRECTION: Clockwise | COUNTER: 4 DIRECTION: Clockwise | COUNTER: 5 DIRECTION: Counter-clockwise | COUNTER: 4 DIRECTION: Counter-clockwise | COUNTER: 3 DIRECTION: Counter-clockwise | COUNTER: 2 DIRECTION: Counter-clockwise | COUNTER: 1 DIRECTION: Counter-clockwise | COUNTER: 0 The button is pressed
Ln 11, Col 1
Arduino Uno R4 WiFi on COM15
2

Explicação do Código

Veja os comentários no código para cada linha.

Código Arduino UNO R4 – Encoder Rotativo com Interrupção

No exemplo de código anterior, usamos o método de polling, que fica verificando o estado do pino o tempo todo. Esse método tem duas desvantagens:

  • Usa os recursos do Arduino UNO R4 de forma ineficiente
  • Algumas contagens podem ser perdidas se outro trecho de código demorar muito para executar.

Uma forma de controlar isso é por meio de interrupções. As interrupções evitam a necessidade de verificar constantemente um evento específico. Isso permite que o Arduino UNO R4 execute outras tarefas enquanto continua monitorando os eventos.

Vamos ver o código abaixo, que usa interrupção para ler o valor do encoder.

/* * Este código de Arduino UNO R4 foi desenvolvido por pt.newbiely.com * Este código de Arduino UNO R4 é disponibilizado ao público sem nenhuma restrição. * Para tutoriais completos e diagramas de ligação, visite: * https://pt.newbiely.com/tutorials/arduino-uno-r4/arduino-uno-r4-rotary-encoder */ #include <ezButton.h> // the library to use for SW pin #define CLK_PIN 2 // The Arduino UNO R4 pin connected to the CLK pin of encoder #define DT_PIN 3 // The Arduino UNO R4 pin connected to the DT pin of encoder #define SW_PIN 4 // The Arduino UNO R4 pin connected to the SW pin of encoder #define DIRECTION_CW 0 // clockwise direction #define DIRECTION_CCW 1 // counter-clockwise direction volatile int counter = 0; volatile int direction = DIRECTION_CW; volatile unsigned long last_time; // for debouncing int prev_counter; ezButton button(SW_PIN); // create ezButton object that attach to pin 4 void setup() { Serial.begin(9600); // configure encoder pins as inputs pinMode(CLK_PIN, INPUT); pinMode(DT_PIN, INPUT); button.setDebounceTime(50); // set debounce time to 50 milliseconds // use interrupt for CLK pin is enough // call ISR_encoderChange() when CLK pin changes from LOW to HIGH attachInterrupt(digitalPinToInterrupt(CLK_PIN), ISR_encoderChange, RISING); } void loop() { button.loop(); // MUST call the loop() function first if (prev_counter != counter) { Serial.print("DIRECTION: "); if (direction == DIRECTION_CW) Serial.print("Clockwise"); else Serial.print("Counter-clockwise"); Serial.print(" | COUNTER: "); Serial.println(counter); prev_counter = counter; } if (button.isPressed()) { Serial.println("The button is pressed"); } // TO DO: your other work here } void ISR_encoderChange() { if ((millis() - last_time) < 50) // debounce time is 50ms return; if (digitalRead(DT_PIN) == HIGH) { // the encoder is rotating in counter-clockwise direction => decrease the counter counter--; direction = DIRECTION_CCW; } else { // the encoder is rotating in clockwise direction => increase the counter counter++; direction = DIRECTION_CW; } last_time = millis(); }
  • Copie o código fornecido e abra-o na Arduino IDE.
  • Clique no botão Upload na Arduino IDE para carregar o código no Arduino UNO R4.

Agora, ao girar o botão, você vai ver as informações aparecerem no Serial Monitor, de forma semelhante ao que você viu no código anterior.

※ Nota:

  • Para conectar o pino CLK do encoder a um Arduino UNO R4 usando uma interrupção, você deve usar os pinos 2 ou 3. Esses são os únicos pinos que suportam interrupções.
  • Alguns guias online podem sugerir o uso de duas interrupções para um encoder, mas isso não é necessário. Usar apenas uma interrupção é suficiente.
  • Use a palavra-chave volatile em todas as variáveis globais usadas na interrupção para evitar problemas.
  • Mantenha o código dentro da interrupção simples. Não use Serial.print() nem Serial.println() ali.

Vídeo

Referências de Funções

Tutoriais Relacionados

※ NOSSAS MENSAGENS

  • Fique à vontade para compartilhar o link deste tutorial. Porém, por favor, não use nosso conteúdo em outros sites. Investimos muito esforço e tempo para criar este conteúdo, por favor respeite nosso trabalho!