ESP32 com Encoder e TB6612FNG: Controle de Velocidade e Leitura de RPM do Motor N20


omparativo entre os drivers TB6612FNG e DRV8833 utilizados com ESP32, motores N20 com encoder e display OLED para medição de RPM em tempo rea
Comparação entre os drivers TB6612FNG e DRV8833 em um projeto com ESP32 e motor N20 com encoder. O TB6612FNG oferece maior eficiência e é mais indicado para aplicações avançadas, como controle de velocidade, PID e robôs equilibristas.

Encoder, DRV8833 e TB6612FNG: Entenda a Evolução do Nosso Robô com ESP32

Introdução

Em um projeto anterior, utilizamos um robô de duas rodas baseado em ESP32, motores N20 de 50 RPM sem encoder e o driver DRV8833. Essa configuração foi excelente para aprender os conceitos básicos de acionamento de motores e movimentação de robôs.

Agora vamos dar um passo adiante.

O projeto foi atualizado com motores N20 de 750 RPM equipados com encoder e um novo driver, o TB6612FNG. Essa mudança não apenas aumenta a velocidade do robô, mas também abre caminho para projetos mais avançados, como controle preciso de velocidade, navegação autônoma e até robôs equilibristas.

Neste artigo vamos entender o que mudou e por que essa evolução faz sentido.


Como o Encoder Funciona?

Imagine uma roda com várias marcas igualmente espaçadas.

Sempre que uma dessas marcas passa diante do sensor, um pulso elétrico é gerado.

Quanto mais rápido o motor gira:

  • Mais marcas passam pelo sensor.
  • Mais pulsos são gerados.
  • Maior será a frequência dos pulsos.

O ESP32 simplesmente conta quantos pulsos chegam durante um intervalo de tempo.

Por exemplo:

  • 100 pulsos em 1 segundo
  • 200 pulsos em 1 segundo
  • 500 pulsos em 1 segundo

Quanto maior o número de pulsos por segundo, maior a velocidade do motor.

Encoder Óptico e Magnético

Existem dois tipos principais de encoder.

Encoder Óptico

Utiliza um LED infravermelho e um fotossensor.

Entre eles existe um disco com furos.

Quando um furo passa pelo feixe de luz, o sensor detecta a passagem e gera um pulso.

Vantagens:

  • Alta precisão
  • Boa resolução

Desvantagens:

  • Sensível à poeira e sujeira

Encoder Magnético

Utiliza ímãs e sensores magnéticos.

Cada vez que o campo magnético muda, um pulso é produzido.

Vantagens:

  • Mais resistente
  • Menor desgaste

Desvantagens:

  • Geralmente possui resolução menor

O Encoder dos Motores N20

Nos motores N20 mais comuns para robótica, o encoder fica instalado na parte traseira do motor.

Ele normalmente possui:

  • Alimentação VCC
  • GND
  • Canal A
  • Canal B

Os canais A e B produzem sinais digitais que podem ser lidos pelo ESP32.

O Que São os Canais A e B?

Os encoders mais modernos utilizam dois canais.

Esses canais geram pulsos ligeiramente defasados.

Essa diferença permite descobrir:

  • Quantos pulsos ocorreram
  • Qual a direção da rotação

Por exemplo:

Se o Canal A mudar antes do Canal B, o motor está girando para frente.

Se o Canal B mudar antes do Canal A, o motor está girando para trás.

Esse sistema é chamado de Encoder em Quadratura.

Como os Pulsos do Encoder Representam o Movimento?

Uma dúvida muito comum é pensar que cada pulso do encoder representa uma volta completa do motor.

Na prática, isso normalmente não acontece.

O encoder gera vários pulsos durante uma única volta do eixo. A quantidade de pulsos depende da construção do encoder e determina sua precisão.

Por exemplo:

  • Encoder com 1 marca: 1 volta = 1 pulso
  • Encoder com 7 marcas: 1 volta = 7 pulsos
  • Encoder com 20 marcas: 1 volta = 20 pulsos

Isso significa que, quanto mais pulsos o encoder gerar por volta, mais precisamente será possível medir velocidade e posição.

Imagine um encoder que gere 7 pulsos por volta.

Quando o motor completar uma volta, o ESP32 receberá 7 pulsos.

Após duas voltas, serão 14 pulsos.

Após dez voltas, serão 70 pulsos.

Contando esses pulsos ao longo do tempo, o microcontrolador consegue calcular a velocidade do motor com grande precisão.

Por Que Isso é Importante?

Se o encoder gerasse apenas um pulso por volta, a medição seria menos precisa.

Ao gerar vários pulsos durante uma única rotação, o sistema consegue acompanhar pequenas variações de velocidade quase em tempo real.

Por isso os encoders são fundamentais em aplicações como:

  • Robôs equilibristas
  • Controle PID
  • Carrinhos autônomos
  • Braços robóticos
  • Tacômetros digitais

Em resumo, o encoder funciona como um "contador de movimento", enviando informações contínuas para que o ESP32 saiba exatamente o que o motor está fazendo.

Suponha que seu encoder gere:

  • 7 pulsos por volta do eixo do motor

E você conte:

  • 350 pulsos em 1 segundo

Primeiro calculamos as rotações por segundo:

350 ÷ 7 = 50 voltas por segundo

Agora convertemos para RPM:

50 × 60 = 3000 RPM

Portanto:

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

É exatamente essa fórmula que usamos em projetos com ESP32 para criar tacômetros digitais.

Por Que a Caixa de Redução Influencia?

Muitos motores N20 possuem uma caixa de redução.

O encoder geralmente mede a rotação do motor antes da redução.

Isso significa que:

  • O motor pode girar a milhares de RPM.
  • O eixo de saída gira muito mais devagar.

Por exemplo:

Motor interno: 3000 RPM

Redução: 30:1

Velocidade no eixo de saída:

3000 ÷ 30 = 100 RPM

Por isso é importante conhecer a relação de redução do motor ao calcular a velocidade real do eixo.

Aplicações Práticas

Os encoders estão presentes em diversos projetos:

Robôs Equilibristas

Permitem medir a velocidade das rodas e corrigir o equilíbrio.

Carrinhos Autônomos

Ajudam a calcular a distância percorrida.

Braços Robóticos

Permitem posicionamento preciso dos motores.

Tacômetros Digitais

Mostram RPM em displays OLED ou LCD.

Controle PID

Fornecem o feedback necessário para controlar velocidade e posição.

Vantagens do Uso de Encoders

Entre os principais benefícios estão:

  • Medição precisa de velocidade
  • Controle de posição
  • Controle de distância
  • Melhor resposta em sistemas PID
  • Maior precisão em robótica

Sem um encoder, o microcontrolador apenas envia energia ao motor, sem saber o que realmente está acontecendo.

Com o encoder, o sistema passa a receber informações em tempo real sobre o movimento.

Exemplo simples

Imagine uma bicicleta.

Sem velocímetro você sabe que está pedalando, mas não sabe sua velocidade.

Com velocímetro você consegue medir exatamente a velocidade.

O encoder funciona como um velocímetro para o motor.


Infográfico mostrando o funcionamento de um encoder em motor N20, geração de pulsos, contagem pelo ESP32 e cálculo da velocidade do motor em RPM.
Entenda como o encoder gera pulsos elétricos, como o ESP32 realiza a contagem desses pulsos e calcula a velocidade do motor em RPM. Uma explicação visual ideal para projetos de robótica, controle de velocidade, PID e robôs móveis.


Projeto Anterior

Componentes

  • ESP32

  • Driver DRV8833

  • Motores N20 50 RPM

  • Sem encoder

Vantagens

  • Simples de montar

  • Baixo custo

  • Ideal para iniciantes

  • Pouca programação

Limitações

O ESP32 apenas enviava comandos ao motor.

Ele não sabia:

  • Se o motor realmente estava girando

  • Qual era sua velocidade

  • Se uma roda girava mais que a outra

Na prática era um sistema sem realimentação.


Novo Projeto

Componentes

  • ESP32

  • Driver TB6612FNG

  • Motores N20 750 RPM

  • Encoder integrado

  • Display OLED

Agora o ESP32 consegue:

  • Controlar os motores

  • Ler o encoder

  • Calcular RPM

  • Exibir informações em tempo real

Isso transforma o robô em um sistema muito mais inteligente.

Esquema de ligação mostrando um ESP32 conectado ao driver TB6612FNG, display OLED SSD1306 e dois motores N20 com encoder para controle e monitoramento de RPM.
Montagem completa utilizando ESP32, driver TB6612FNG, display OLED SSD1306 e dois motores N20 com encoder. O circuito permite controlar a velocidade dos motores e realizar a leitura de RPM em tempo real através dos sinais gerados pelos encoders.

Código



/***************************************************************
 * Projeto : RPM Estável com Encoder + TB6612FNG
 * Autor   : Rudi Souza - RodRobot
 * Placa   : ESP32
 * Driver  : TB6612FNG
 * Motor   : N20 com Encoder
 * Display : OLED SSD1306 I2C 128x64
 *
 * Descrição:
 * Leitura de RPM utilizando encoder com interrupções.
 * Inclui filtro anti-ruído e suavização exponencial,
 * produzindo valores mais estáveis para exibição e
 * preparação para futuros projetos com controle PID.
 *
 * Encoder (medição de velocidade).
 * PWM (controle da velocidade).
 * Filtragem de sinais (base para PID).
 ***************************************************************/

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

/*============================================================
  OLED SSD1306
============================================================*/
#define SCREEN_WIDTH   128          // Largura do display
#define SCREEN_HEIGHT   64          // Altura do display

Adafruit_SSD1306 display(
  SCREEN_WIDTH,
  SCREEN_HEIGHT,
  &Wire,
  -1
);

/*============================================================
  TB6612FNG - Motor A
============================================================*/
#define AIN1 18                     // Direção motor A
#define AIN2 19                     // Direção motor A
#define PWMA 23                     // PWM motor A

/*============================================================
  TB6612FNG - Motor B
============================================================*/
#define BIN1 25                     // Direção motor B
#define BIN2 26                     // Direção motor B
#define PWMB 27                      // PWM motor B

/*============================================================
  Encoders
============================================================*/
#define ENC_A 34                    // Encoder motor A
#define ENC_B 35                    // Encoder motor B

volatile long countA = 0;           // Contador motor A
volatile long countB = 0;           // Contador motor B

/*============================================================
  Configuração do Encoder
============================================================*/
//#define PULSOS_POR_VOLTA 20       // Ajustar após calibração
#define PULSOS_POR_VOLTA 144       // Encoder utilizado

/*============================================================
  Variáveis RPM
============================================================*/
float rpmA = 0;                     // RPM bruto motor A
float rpmB = 0;                     // RPM bruto motor B

float rpmA_filtro = 0;              // RPM filtrado motor A
float rpmB_filtro = 0;              // RPM filtrado motor B

unsigned long lastTime = 0;         // Controle de tempo

/*============================================================
  Filtro Anti-Ruído
============================================================*/
volatile unsigned long lastIntA = 0;
volatile unsigned long lastIntB = 0;

/*============================================================
  Interrupção Encoder A
============================================================*/
void IRAM_ATTR encoderA() {

  unsigned long now = micros();

  if (now - lastIntA > 300) {       // Ignora ruídos rápidos
    countA++;
    lastIntA = now;
  }
}

/*============================================================
  Interrupção Encoder B
============================================================*/
void IRAM_ATTR encoderB() {

  unsigned long now = micros();

  if (now - lastIntB > 300) {       // Ignora ruídos rápidos
    countB++;
    lastIntB = now;
  }
}

/*============================================================
  Configuração PWM
============================================================*/
void setupPWM() {

  ledcAttach(PWMA, 5000, 8);        // Canal PWM motor A
  ledcAttach(PWMB, 5000, 8);        // Canal PWM motor B
}

/*============================================================
  Controle dos Motores
============================================================*/
void setMotor(int a, int b) {

  digitalWrite(AIN1, a > 0);
  digitalWrite(AIN2, a < 0);

  digitalWrite(BIN1, b > 0);
  digitalWrite(BIN2, b < 0);

  ledcWrite(PWMA, abs(a));          // PWM motor A
  ledcWrite(PWMB, abs(b));          // PWM motor B
}

/*============================================================
  Setup
============================================================*/
void setup() {

  Serial.begin(115200);

  pinMode(AIN1, OUTPUT);
  pinMode(AIN2, OUTPUT);

  pinMode(BIN1, OUTPUT);
  pinMode(BIN2, OUTPUT);

  pinMode(ENC_A, INPUT_PULLUP);
  pinMode(ENC_B, INPUT_PULLUP);

  attachInterrupt(
    digitalPinToInterrupt(ENC_A),
    encoderA,
    RISING
  );

  attachInterrupt(
    digitalPinToInterrupt(ENC_B),
    encoderB,
    RISING
  );

  setupPWM();

  display.begin(
    SSD1306_SWITCHCAPVCC,
    0x3C
  );

  lastTime = millis();
}

/*============================================================
  Loop Principal
============================================================*/
void loop() {

  int pwm = 255;                    // PWM fixo para testes
  //int pwm = 100;

  setMotor(pwm, pwm);

  unsigned long now = millis();

  /*----------------------------------------------------------
    Atualiza RPM a cada 1 segundo
  ----------------------------------------------------------*/
  if (now - lastTime >= 1000) {

    noInterrupts();

    long pulsesA = countA;
    long pulsesB = countB;

    countA = 0;
    countB = 0;

    interrupts();

    /*--------------------------------------------------------
      Cálculo do RPM bruto
    --------------------------------------------------------*/
    rpmA = (pulsesA * 60.0) /
           PULSOS_POR_VOLTA;

    rpmB = (pulsesB * 60.0) /
           PULSOS_POR_VOLTA;

    /*--------------------------------------------------------
      Filtro Exponencial
      80% valor anterior
      20% valor novo
    --------------------------------------------------------*/
    rpmA_filtro =
      (rpmA_filtro * 0.8) +
      (rpmA * 0.2);

    rpmB_filtro =
      (rpmB_filtro * 0.8) +
      (rpmB * 0.2);

    lastTime = now;

    /*--------------------------------------------------------
      Monitor Serial
    --------------------------------------------------------*/
    Serial.print("PWM: ");
    Serial.print(pwm);

    Serial.print(" | RPM A: ");
    Serial.print(rpmA_filtro);

    Serial.print(" | RPM B: ");
    Serial.println(rpmB_filtro);
  }

  /*==========================================================
    Atualização OLED
  ==========================================================*/
  display.clearDisplay();

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

  display.setCursor(0, 0);
  display.print("RPM ESTAVEL");

  display.setCursor(0, 15);
  display.print("PWM: ");
  display.print(pwm);

  display.setCursor(0, 30);
  display.print("RPM A: ");
  display.print(rpmA_filtro, 0);

  display.setCursor(0, 45);
  display.print("RPM B: ");
  display.print(rpmB_filtro, 0);

  display.display();

  delay(30);
}



DRV8833 vs TB6612FNG

Uma dúvida comum é:

Se o DRV8833 funcionava, por que trocar?

A resposta está na evolução do projeto.


DRV8833

O DRV8833 é um dos drivers mais populares para pequenos robôs.

Pontos positivos

✓ Compacto

✓ Fácil de usar

✓ Baixo consumo

✓ Excelente para motores pequenos

✓ Ótimo para iniciantes

Quando usar?

  • Carrinhos simples

  • Seguidor de linha básico

  • Projetos educacionais

  • Motores N20 de baixa velocidade

  • Primeiros projetos com ESP32


TB6612FNG

O TB6612FNG é considerado um dos melhores drivers para robótica educacional.

Pontos positivos

✓ Alta eficiência

✓ Menor aquecimento

✓ Excelente resposta PWM

✓ Muito utilizado em robôs móveis

✓ Ideal para projetos com encoder

✓ Excelente para futuras implementações de PID

Quando usar?

  • Robôs com encoder

  • Controle de velocidade

  • Robôs autônomos

  • Projetos avançados

  • Robôs equilibristas

  • Guia Visual do TB6612FNG – Alimentação, PWM, Controle de Direção e Saídas para Motores
    Diagrama completo da pinagem do driver TB6612FNG, mostrando os pinos de alimentação (VM, VCC e GND), controle PWM (PWMA e PWMB), direção dos motores (AIN1, AIN2, BIN1 e BIN2), pino STBY e conexões para os motores A e B. Ideal para projetos com ESP32, Arduino, robôs móveis e controle de velocidade por PWM.


Comparativo Rápido

Característica  DRV8833         TB6612FNG
Facilidade            Excelente              Excelente
Projetos iniciantes           ⭐⭐⭐⭐⭐             ⭐⭐⭐⭐
Projetos avançados           ⭐⭐⭐             ⭐⭐⭐⭐⭐
Encoder            Sim              Sim
PWM            Bom              Excelente
Robô Equilibrista            Limitado              Recomendado
Eficiência            Boa              Excelente

Por que trocar um N20 de 50 RPM por um N20 de 750 RPM?

Essa foi outra grande mudança do projeto.

Motor de 50 RPM

Vantagens:

  • Fácil de controlar

  • Mais torque

  • Movimento suave

Desvantagens:

  • Muito lento

  • Pouca agilidade

Ideal para:

  • Demonstrações

  • Plataformas lentas

  • Projetos educacionais básicos


Motor de 750 RPM com Encoder

Vantagens:

  • Muito mais rápido

  • Resposta dinâmica

  • Permite medir RPM

  • Melhor para experimentos avançados

Desvantagens:

  • Exige mais controle

  • Necessita encoder para aproveitar seu potencial

Ideal para:

  • Controle de velocidade

  • Navegação

  • PID

  • Robô Equilibrista


O que mudou na prática?

Antes:

ESP32 → Driver → Motor

Agora:

ESP32 → Driver → Motor com Encoder

ESP32 ← Encoder

O microcontrolador passou a receber informações do motor em tempo real.

Essa comunicação é o primeiro passo para sistemas inteligentes de controle.


Próximos Passos

Com os motores de 750 RPM e encoder, várias possibilidades se tornam viáveis:

  • Controle automático de velocidade

  • Controle PID

  • Odometria

  • Navegação autônoma

  • Robôs seguidores de trajetória

  • Robôs equilibristas


Conclusão

A troca dos motores N20 de 50 RPM sem encoder por motores N20 de 750 RPM com encoder representa uma grande evolução no projeto.

Da mesma forma, a substituição do DRV8833 pelo TB6612FNG prepara a plataforma para aplicações mais avançadas.

Se o objetivo é aprender robótica desde os conceitos básicos até sistemas inteligentes de controle, essa combinação de ESP32, TB6612FNG e motores N20 com encoder é um excelente caminho para evoluir seus projetos.


🔧 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 Botão Touch: Como Usar o Sensor Touch (Tutorial com LED e Relé)

ESP32 para Iniciantes: Projeto LED Piscando Passo a Passo