Início›Módulos›Encoder Rotativo
⬤ Intermédio · Grupo 5 — Toque, Inclinação e Pressão

🎛️ Encoder Rotativo

⏱️ 35 min 🧩 Módulo encoder · 2× Digital + botão 📦 Módulo #28

Nesta página

🔬 Sobre o Módulo Encoder Rotativo

O encoder rotativo incremental gera dois sinais digitais desfasados (CLK e DT) que permitem determinar tanto a direção como o número de passos de rotação. Diferente de um potenciómetro, não tem fim de curso — pode girar indefinidamente. Inclui também um botão ao pressionar (SW).

Tipo
Incremental
Conta passos relativos
Saídas
CLK + DT
2 fases desfasadas 90°
Botão SW
Digital
LOW quando premido
Passos/volta
20
Tipicamente 20 detentes
Sem fim de curso
✓
Rotação contínua
Pinos
D2 + D3 + D4
Ou outros digitais
ℹ️
Os dois sinais CLK e DT estão desfasados 90° (quadratura). Ao girar para a direita, CLK muda antes de DT. Ao girar para a esquerda, DT muda antes de CLK. Esta diferença de fase determina a direção.

🔌 Pinagem

VCCAlimentação → 5V do Arduino
GNDMassa → GND do Arduino
CLKSinal de relógio → D2 (INT0 — interrupção)
DTSinal de dados → D3
SWBotão push → D4 (INPUT_PULLUP)
💡
Liga CLK ao pino D2 do Arduino UNO — este pino suporta interrupções externas (attachInterrupt), o que garante que nenhum passo é perdido mesmo com código complexo no loop().

💻 Contar Pulsos — Método Simples

ex_encoder_basico.ino
#define CLK_PIN 2
#define DT_PIN  3
#define SW_PIN  4

int contador = 0;
int ultimoCLK;

void setup() {{
  pinMode(CLK_PIN, INPUT);
  pinMode(DT_PIN,  INPUT);
  pinMode(SW_PIN,  INPUT_PULLUP);
  ultimoCLK = digitalRead(CLK_PIN);
  Serial.begin(9600);
}}

void loop() {{
  int clk = digitalRead(CLK_PIN);

  if (clk != ultimoCLK) {{     // Flanco detetado
    if (digitalRead(DT_PIN) != clk)
      contador++;               // Sentido horário
    else
      contador--;               // Sentido anti-horário
    Serial.println(contador);
  }}
  ultimoCLK = clk;

  if (digitalRead(SW_PIN) == LOW) {{
    contador = 0;
    Serial.println("RESET");
    delay(300);  // debounce
  }}
}}

🔄 Deteção Robusta com Interrupção

ex_encoder_interrupcao.ino
#define CLK_PIN 2   // INT0
#define DT_PIN  3
#define SW_PIN  4

volatile int posicao = 0;

void IRAM_ATTR encoderISR() {{
  if (digitalRead(DT_PIN) != digitalRead(CLK_PIN))
    posicao++;
  else
    posicao--;
}}

void setup() {{
  pinMode(CLK_PIN, INPUT);
  pinMode(DT_PIN,  INPUT);
  pinMode(SW_PIN,  INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(CLK_PIN), encoderISR, CHANGE);
  Serial.begin(9600);
}}

void loop() {{
  static int ultimaPosicao = 0;
  if (posicao != ultimaPosicao) {{
    Serial.print("Posição: "); Serial.println(posicao);
    ultimaPosicao = posicao;
  }}
  if (digitalRead(SW_PIN) == LOW) {{
    posicao = 0; Serial.println("Reset"); delay(300);
  }}
}}

💡 Controlo de Brilho do LED RGB

ex_encoder_brilho.ino
#define CLK_PIN 2
#define DT_PIN  3
#define LED_PWM 9

volatile int brilho = 127;  // 0–255

void encoderISR() {{
  if (digitalRead(DT_PIN) != digitalRead(CLK_PIN))
    brilho = min(brilho + 5, 255);
  else
    brilho = max(brilho - 5, 0);
}}

void setup() {{
  pinMode(LED_PWM, OUTPUT);
  attachInterrupt(digitalPinToInterrupt(CLK_PIN), encoderISR, CHANGE);
  Serial.begin(9600);
}}

void loop() {{
  analogWrite(LED_PWM, brilho);
  Serial.println(brilho);
  delay(20);
}}
ex_encoder_menu.ino
#define CLK_PIN 2
#define DT_PIN  3
#define SW_PIN  4
const char* opcoes[] = {{"Temperatura","Humidade","Luminosidade","Relé"}};
#define N_OPCOES 4

volatile int sel = 0;

void encoderISR() {{
  if (digitalRead(DT_PIN) != digitalRead(CLK_PIN))
    sel = (sel + 1) % N_OPCOES;
  else
    sel = (sel - 1 + N_OPCOES) % N_OPCOES;
}}

void setup() {{
  pinMode(SW_PIN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(CLK_PIN), encoderISR, CHANGE);
  Serial.begin(9600);
}}

void loop() {{
  static int ultimoSel = -1;
  if (sel != ultimoSel) {{
    Serial.print("> "); Serial.println(opcoes[sel]);
    ultimoSel = sel;
  }}
  if (digitalRead(SW_PIN) == LOW) {{
    Serial.print("Selecionado: "); Serial.println(opcoes[sel]);
    delay(400);
  }}
}}

🏆 Para ir mais longe

Kit B 37 · PR.FT6_15 · Arduino UNO · Raspberry Pi · Início · led.dge.medu.pt