Como Funciona um Encoder? Aprenda na Prática com ESP32 e Sensor Hall KY-003


ESP32 e KY-003: Entenda Como um Encoder Gera Pulsos
Demonstração prática do funcionamento de um encoder utilizando um ESP32 DevKit, sensor Hall KY-003 e ímãs de neodímio. Cada ímã gera um pulso quando passa em frente ao sensor. O ESP32 detecta esses eventos através de interrupções e realiza a contagem dos pulsos para calcular velocidade, RPM e posição.

Como Funciona um Encoder? Aprenda na Prática com ESP32 e Sensor Hall KY-003

Quando começamos a trabalhar com motores, robôs e controle de velocidade, logo aparece uma palavra muito importante: encoder.

Mas afinal, o que é um encoder?

Como ele consegue medir a velocidade de um motor?

E por que praticamente todo robô mais avançado utiliza esse componente?

Neste artigo vamos entender esse conceito de forma simples utilizando um ESP32, um sensor Hall KY-003 e alguns ímãs de neodímio.

O objetivo é visualizar exatamente como os pulsos são gerados e como o ESP32 consegue contá-los através de interrupções.


O Que é um Encoder?

Um encoder é um dispositivo capaz de gerar pulsos conforme um eixo gira.

Esses pulsos podem ser contados por um microcontrolador para determinar:

  • Velocidade do motor
  • RPM (Rotações por Minuto)
  • Distância percorrida
  • Posição do eixo

Quanto maior a quantidade de pulsos gerados por volta, maior será a precisão da medição.


Simulando um Encoder com um Sensor Hall

Para facilitar o entendimento, vamos criar um encoder simples utilizando:

  • ESP32 DevKit
  • Sensor Hall KY-003
  • Motor DC de 50 RPM
  • Ímãs de neodímio

O princípio é muito simples.

Sempre que um ímã passar em frente ao sensor Hall, um pulso será gerado.

O ESP32 detecta esse pulso e incrementa um contador.

Sensor Hall KY-003 com ESP32: Contando Pulsos com Interrupções
ESP32 DevKit, um sensor Hall KY-003 e ímãs de neodímio para demonstrar na prática como funcionam os pulsos utilizados para medir velocidade e posição.


Como Funciona o Sensor Hall KY-003?

O KY-003 utiliza o efeito Hall para detectar campos magnéticos.

Normalmente sua saída permanece em nível lógico alto.

Quando um ímã passa próximo ao sensor, a saída muda de estado.

Essa mudança é suficiente para gerar uma interrupção no ESP32.

Na prática temos:

Ímã → Sensor Hall → Pulso → ESP32

Como um Encoder Funciona? ESP32 + KY-003 na Prática
ESP32, um sensor Hall KY-003 e quatro ímãs para demonstrar na prática como os pulsos são gerados e contados pelo microcontrolador.

Teste com Um Ímã

Começamos colocando apenas um ímã na roda.

Cada vez que a roda completa uma volta, o ímã passa uma vez em frente ao sensor.

Resultado:

  • 1 volta
  • 1 pulso

Ou seja:

1 ímã = 1 pulso por volta

Esse é o cenário mais simples possível.


Teste com Dois Ímãs

Agora adicionamos um segundo ímã.

Sem alterar nenhuma linha do código.

A única diferença é que o sensor passa a detectar dois eventos durante cada volta da roda.

Resultado:

  • 1 volta
  • 2 pulsos

Ou seja:

2 ímãs = 2 pulsos por volta


Teste com Três Ímãs

Adicionando mais um ímã:

  • 1 volta
  • 3 pulsos

Temos agora uma resolução maior.

O ESP32 recebe mais informações sobre o movimento da roda.


Teste com Quatro Ímãs

Com quatro ímãs distribuídos igualmente:

  • 1 volta
  • 4 pulsos

Resultado:

4 ímãs = 4 pulsos por volta

É exatamente esse conceito que existe dentro de muitos encoders comerciais.


O Que São Interrupções?

Imagine que o ESP32 está executando várias tarefas ao mesmo tempo.

Enquanto isso, o ímã passa rapidamente pelo sensor.

Como garantir que nenhum pulso seja perdido?

A resposta é: interrupções.

Uma interrupção funciona como um aviso urgente para o microcontrolador.

Quando o sensor detecta o ímã:

  1. O ESP32 interrompe temporariamente o que estava fazendo.
  2. Executa uma função específica.
  3. Conta o pulso.
  4. Retorna para a execução normal.

Tudo acontece em poucos microssegundos.

Código



/***************************************************************************
 * Projeto : ESP32 + KY-003 + OLED SSD1306
 * Autor   : RodRobot
 *
 * Objetivo:
 * Demonstrar o funcionamento das interrupções do ESP32
 * utilizando um Sensor Hall KY-003.
 *
 * Conceito:
 * ---------------------------------------------------------
 * 1 ímã  = 1 pulso por volta
 * 2 ímãs = 2 pulsos por volta
 * 3 ímãs = 3 pulsos por volta
 * 4 ímãs = 4 pulsos por volta
 * ---------------------------------------------------------
 *
 * Cada vez que o ímã passa pelo sensor Hall,
 * uma interrupção é gerada no ESP32.
 *
 * Este é exatamente o mesmo conceito utilizado
 * por encoders para medir velocidade e posição.
 *
 * Ligações OLED SSD1306
 * ---------------------------------------------------------
 * VCC -> 3V3
 * GND -> GND
 * SDA -> GPIO 21
 * SCL -> GPIO 22
 *
 * Ligações KY-003
 * ---------------------------------------------------------
 * VCC -> 3V3
 * GND -> GND
 * OUT -> GPIO 4
 ***************************************************************************/

#include <Wire.h>                       // Comunicação I2C
#include <Adafruit_GFX.h>               // Biblioteca gráfica
#include <Adafruit_SSD1306.h>           // Biblioteca OLED


//======================================================================
// Configuração OLED
//======================================================================
#define SCREEN_WIDTH   128              // Largura display
#define SCREEN_HEIGHT   64              // Altura display

#define OLED_RESET      -1             // Sem pino reset

#define SDA_PIN         21             // SDA OLED
#define SCL_PIN         22             // SCL OLED

Adafruit_SSD1306 display(
  SCREEN_WIDTH,
  SCREEN_HEIGHT,
  &Wire,
  OLED_RESET
);


//======================================================================
// Sensor Hall
//======================================================================
const byte HALL_PIN = 4;               // Saída KY-003


//======================================================================
// Variáveis da interrupção
//======================================================================
volatile unsigned long pulsos = 0;     // Contador total

volatile bool novoPulso = false;       // Indica novo evento


//======================================================================
// Rotina de Interrupção
//======================================================================
void IRAM_ATTR detectarPulso()
{
  pulsos++;                            // Soma 1 pulso

  novoPulso = true;                    // Marca evento
}


//======================================================================
// Setup
//======================================================================
void setup()
{
  Serial.begin(115200);                // Monitor Serial

  Wire.begin(
    SDA_PIN,
    SCL_PIN
  );                                   // Inicializa I2C

  pinMode(
    HALL_PIN,
    INPUT_PULLUP
  );                                   // Entrada sensor Hall


  //--------------------------------------------------------------------
  // Inicializa OLED
  //--------------------------------------------------------------------
  if (!display.begin(
        SSD1306_SWITCHCAPVCC,
        0x3C))
  {
    Serial.println("OLED nao encontrado");

    while (true);                      // Para execução
  }


  //--------------------------------------------------------------------
  // Tela inicial
  //--------------------------------------------------------------------
  display.clearDisplay();

  display.setTextSize(1);
  display.setTextColor(WHITE);

  display.setCursor(0,0);
  display.println("ESP32 + KY-003");

  display.setCursor(0,15);
  display.println("Interrupcoes");

  display.setCursor(0,30);
  display.println("1 Ima = 1 Pulso");

  display.display();

  delay(3000);


  //--------------------------------------------------------------------
  // Configura interrupção
  //--------------------------------------------------------------------
  attachInterrupt(
    digitalPinToInterrupt(HALL_PIN),   // GPIO monitorado
    detectarPulso,                     // Função chamada
    FALLING                            // Borda de descida
  );

  Serial.println();
  Serial.println("Sistema iniciado");
  Serial.println("Aguardando pulsos...");
}


//======================================================================
// Loop Principal
//======================================================================
void loop()
{
  static unsigned long ultimoValor = 0;

  //--------------------------------------------------------------------
  // Copia variáveis da interrupção com segurança
  //--------------------------------------------------------------------
  noInterrupts();                      // Desabilita interrupções

  unsigned long total = pulsos;        // Copia contador

  bool evento = novoPulso;             // Copia flag

  novoPulso = false;                   // Limpa flag

  interrupts();                        // Reabilita interrupções


  //--------------------------------------------------------------------
  // Exibe no Serial quando houver novo pulso
  //--------------------------------------------------------------------
  if (total != ultimoValor)
  {
    ultimoValor = total;

    Serial.print("Pulso detectado: ");
    Serial.println(total);
  }


  //--------------------------------------------------------------------
  // Atualiza OLED
  //--------------------------------------------------------------------
  display.clearDisplay();


  display.setTextSize(1);

  display.setCursor(0,0);
  display.println("KY-003 ESP32");

  display.drawLine(
    0,
    10,
    128,
    10,
    WHITE
  );


  //--------------------------------------------------------------------
  // Total de pulsos
  //--------------------------------------------------------------------
  display.setCursor(0,18);
  display.print("Pulsos:");

  display.setCursor(70,18);
  display.print(total);


  //--------------------------------------------------------------------
  // Estado da interrupção
  //--------------------------------------------------------------------
  display.setCursor(0,35);
  display.print("INT:");

  display.setCursor(70,35);

  if (evento)
  {
    display.print("DISPAROU");
  }
  else
  {
    display.print("OK");
  }


  //--------------------------------------------------------------------
  // Informação didática
  //--------------------------------------------------------------------
  display.setCursor(0,52);
  display.print("1 Ima = 1 Pulso");


  display.display();                   // Atualiza OLED

  delay(50);                           // Pequena pausa
}




Configurando a Interrupção

No código utilizamos:

attachInterrupt(
  digitalPinToInterrupt(HALL_PIN),
  detectarPulso,
  FALLING
);

Essa linha informa:

  • Qual pino será monitorado
  • Qual função será executada
  • Qual evento deve disparar a interrupção

O Que Significa FALLING?

O sensor normalmente mantém sua saída em nível alto.

Quando o ímã é detectado:

HIGH → LOW

Essa transição é chamada de:

Falling Edge

Por isso utilizamos:

FALLING

para disparar a interrupção.


Como o ESP32 Conta os Pulsos?

A função de interrupção é extremamente simples:

void IRAM_ATTR detectarPulso()
{
    pulsos++;
}

Cada vez que um ímã passa pelo sensor:

  • Uma interrupção ocorre
  • O contador aumenta
  • Um novo pulso é registrado

Exemplo:

Antes:

10

Depois:

11


Calculando RPM

Agora vem a parte interessante.

Sabendo quantos pulsos existem por volta, podemos calcular o RPM do motor.

A fórmula é:

RPM = (Pulsos por Segundo × 60) ÷ Pulsos por Volta

Suponha um motor de 50 RPM com 4 ímãs.

Temos:

  • 50 voltas por minuto
  • 4 pulsos por volta

Logo:

50 × 4 = 200 pulsos por minuto

Ou aproximadamente:

3,33 pulsos por segundo

Calculando:

RPM = (3,33 × 60) ÷ 4

Resultado:

50 RPM

Exatamente a velocidade do motor.


O Que Acontece Dentro de um Encoder Real?

Agora que entendemos esse experimento, ficou fácil compreender um encoder verdadeiro.

Em vez de ímãs colados na roda, o encoder possui sensores internos capazes de gerar dezenas ou centenas de pulsos por volta.

O ESP32 faz exatamente o mesmo processo:

  • Recebe pulsos
  • Conta pulsos
  • Calcula velocidade
  • Calcula posição
  • Calcula RPM

Ou seja, o conceito é exatamente o mesmo.


Conclusão

Neste projeto utilizamos um sensor Hall KY-003 para demonstrar de forma visual e prática como um encoder funciona.

Vimos que:

✔ Um ímã gera um pulso por volta

✔ Dois ímãs geram dois pulsos por volta

✔ Quatro ímãs geram quatro pulsos por volta

✔ O ESP32 utiliza interrupções para não perder nenhum pulso

✔ A partir dos pulsos é possível calcular RPM, velocidade e posição

Esse é um dos conceitos mais importantes para quem deseja trabalhar com motores DC, encoders, PID e robôs equilibrando.

E o melhor de tudo: usando componentes simples e de baixo custo é possível compreender exatamente o que acontece dentro de um encoder real.


🔧 Acompanhe o RodRobot

Projetos maker com ESP32, Arduino, eletrônica e programação.

RodRobot – Projetos maker, eletrônica e programação na prática.

Comentários

Postagens mais visitadas deste blog

ESP32-C3 Super Mini: Características, Vantagens, Pinagem, Matter.

ESP32 para Iniciantes: Projeto LED Piscando Passo a Passo

ESP32 Botão Touch: Como Usar o Sensor Touch (Tutorial com LED e Relé)