ESP32-C3 + ESP-NOW: Controle Sem Fio com 5 Botões Analógicos e Display OLED


ESP32-C3 utilizando ESP-NOW para enviar comandos de um módulo analógico de 5 botões para outro ESP32-C3 com display OLED mostrando os comandos recebidos.
Projeto utilizando dois ESP32-C3 comunicando-se através do ESP-NOW. O transmissor lê um módulo analógico de 5 botões usando apenas um pino ADC e envia os comandos sem fio para outro ESP32-C3, que exibe as informações em um display OLED.

ESP-NOW com Dois ESP32-C3 + Módulo de 5 Botões Analógicos + OLED

O ESP-NOW é uma das tecnologias mais interessantes da família ESP32.
Com ela podemos criar comunicação sem fio entre placas ESP32 sem precisar de roteador Wi-Fi.

Neste projeto vamos usar:

  • 2 placas ESP32-C3
  • módulo analógico de 5 botões
  • display OLED SSD1306
  • comunicação ESP-NOW

O objetivo é simples:

Quando um botão for pressionado no ESP32-C3 transmissor, o comando será enviado sem fio para outro ESP32-C3 receptor, que mostrará o nome do botão no display OLED.


ESP32-C3: Por Que o Serial.print() Não Aparece? Entenda o USB CDC On Boot

Se você já programou um ESP32-C3 Super Mini e percebeu que o Serial.print() não mostra nada no Monitor Serial da Arduino IDE, mas tudo funciona normalmente ao ativar USB CDC On Boot: Enabled, você não está sozinho.

Esse é um comportamento comum nas placas com USB nativa, como o ESP32-C3.

Neste artigo, você vai entender:

  • O que é USB CDC
  • Por que o Serial.print() pode não aparecer
  • Como configurar corretamente a Arduino IDE
  • Código de teste para verificar a comunicação serial
  • Dicas para evitar problemas

O Que é USB CDC?

USB CDC (Communication Device Class) é um padrão que permite que o microcontrolador seja reconhecido pelo computador como uma porta serial virtual (COM).

Na prática, isso significa que o código abaixo envia dados diretamente pela porta USB:

Serial.begin(115200);
Serial.println("Olá, mundo!");

Sem o CDC habilitado, a porta USB pode não funcionar como Monitor Serial.


Diferença Entre ESP32 Tradicional e ESP32-C3

ESP32 Tradicional

Muitas placas usam um conversor USB-Serial externo, como Silicon Labs CP2102 ou WCH CH340.

ESP32-C3

O chip possui USB nativa, dispensando conversores externos em muitas placas.

Isso reduz custo e tamanho, mas exige configuração correta no ambiente de desenvolvimento.


O Que Faz a Opção “USB CDC On Boot”?

Essa opção define se o ESP32-C3 inicializa já com a interface serial USB habilitada.

Enabled

  • Cria automaticamente uma porta COM virtual.
  • Serial.print() funciona pela USB.
  • Ideal para depuração.

Disabled

  • A interface CDC não é ativada no boot.
  • Serial.print() pode não aparecer.
  • Útil apenas em casos específicos.

Por Que o Serial.print() Não Aparece?

Com USB CDC On Boot = Disabled:

  1. O ESP32-C3 não ativa a interface USB serial.
  2. O computador não recebe os dados.
  3. O Monitor Serial permanece em branco.

Ao ativar Enabled, a USB passa a funcionar como porta serial virtual e as mensagens aparecem normalmente.


Configuração Recomendada na Arduino IDE

Menu Ferramentas do Arduino IDE mostrando a opção USB CDC On Boot habilitada para a placa ESP32-C3
Configuração necessária no ESP32-C3: habilite USB CDC On Boot na Arduino IDE para que o Monitor Serial exiba corretamente os valores lidos pelo ADC, os comandos dos botões e as informações transmitidas via ESP-NOW.


Código de Teste

/***********************************************************************
Teste de Serial no ESP32-C3
Autor: RodRobot
************************************************************************/

void setup() {
Serial.begin(115200);
delay(2000); // Aguarda a porta USB ser reconhecida
Serial.println("ESP32-C3 funcionando!");
}

void loop() {
Serial.println("Teste...");
delay(1000);
}

Resultado Esperado no Monitor Serial

ESP32-C3 funcionando!
Teste...
Teste...
Teste...

Por Que Usar delay(2000)?

Após o reset, o sistema operacional pode levar alguns segundos para reconhecer a porta USB.

Sem esse atraso, as primeiras mensagens podem ser perdidas.


Quando Desativar o USB CDC On Boot?

Na maioria dos projetos, deixe Enabled.

Desative apenas quando:

  • Você quiser usar outra interface serial.
  • Estiver desenvolvendo firmware USB personalizado.
  • Precisar liberar recursos específicos do USB.

Solução de Problemas

Nada aparece no Monitor Serial

  • Ative USB CDC On Boot: Enabled
  • Verifique a velocidade em 115200 baud
  • Feche e reabra o Monitor Serial
  • Regrave o firmware

Porta COM desaparece

  • Reconecte o cabo USB
  • Use um cabo de dados (não apenas carregamento)
  • Atualize os drivers do sistema

ESP32-C3 vs ESP32 Tradicional

Recurso            ESP32 Tradicional   ESP32-C3
USB nativa            Não (na maioria das placas)   Sim
Conversor externo            Geralmente sim  Geralmente não
Requer USB CDC On Boot             Não
  Sim, para usar Serial pela USB


Como descobrir o MAC do receptor

Use este código no ESP32 receptor:

/***********************************************************************
 * Projeto : Mostrar MAC Address do ESP32
 * Função  : Exibe o endereço MAC no Monitor Serial
 * Placa   : ESP32 DevKit V1
 * Autor   : RodRobot
 ***********************************************************************/

#include <WiFi.h>

void setup() {
  Serial.begin(115200);          // Inicia Serial
  delay(1000);                   // Aguarda estabilizar

  WiFi.mode(WIFI_STA);           // Modo Station
  WiFi.disconnect();             // Garante inicialização completa
  delay(500);                    // Pequena espera

  Serial.print("MAC Address: ");
  Serial.println(WiFi.macAddress());
}

void loop() {
}

Resultado esperado

MAC Address: 24:6F:28:AA:BB:CC



Artigo comleto como descobrir o MAC do receptor.
https://rodrobot.blogspot.com/2026/05/esp-now-com-esp32-c3-e-esp32.html

Configurando a Serial do ESP32-C3 (USB CDC On Boot)

Em algumas placas ESP32-C3, o Monitor Serial não mostra mensagens sem habilitar a opção correta.

Na Arduino IDE:

  1. Ferramentas -> Selecione a placa ESP32C3 Dev Module.
  2. Vá em Tools (Ferramentas).
  3. Encontre USB CDC On Boot.
  4. Selecione Enabled.
  5. Compile e grave novamente.

Como funciona o projeto

ESP32-C3 transmissor



Diagrama de ligação do ESP32-C3 com módulo de teclado analógico de 5 botões utilizando um pino ADC e comunicação sem fio ESP-NOW.
Esquema de conexão entre o ESP32-C3 e o módulo de teclado analógico de 5 botões. O sistema utiliza apenas uma entrada ADC para identificar todos os botões e transmitir os comandos via ESP-NOW.

O transmissor:

  • lê o módulo de 5 botões
  • identifica qual botão foi pressionado
  • envia o comando usando ESP-NOW

ESP32-C3 receptor


Diagrama de ligação do ESP32-C3 com display OLED I2C mostrando a configuração do receptor para comunicação sem fio via ESP-NOW.
Esquema do módulo receptor utilizando ESP32-C3 e display OLED I2C. Os comandos recebidos via ESP-NOW são exibidos em tempo real no display.

O receptor:

  • recebe os dados via ESP-NOW
  • mostra no OLED:
    • FRENTE
    • RE
    • DIREITA
    • ESQUERDA
    • OK

O segredo do módulo de 5 botões

O módulo utiliza um circuito chamado:

Divisor de tensão com resistores

Em vez de usar:

  • 5 fios
  • 5 GPIOs

ele usa:

  • apenas 1 pino analógico (ADC)

Isso é possível graças aos resistores internos do módulo.


Como o divisor de tensão funciona

Guia Definitivo: Teclado de 5 Botões Usando Um Único Pino Analógico
Circuito prático de divisor de tensão para identificar múltiplos 
comandos (Esquerda, Frente, Ré, Direita e OK) através de um único 
canal analógico (ADC).

O circuito utiliza vários resistores em série.

Cada botão conecta um ponto diferente da escada resistiva ao GND, criando uma tensão diferente no pino ADC.

O ESP32-C3 converte essa tensão em um valor digital.

Quanto menor a tensão:

  • menor o valor ADC

Quanto maior a tensão:

  • maior o valor ADC

Alimentação em 3.3V

Como o ESP32-C3 trabalha em:

  • lógica 3.3V
  • ADC máximo 3.3V

Todo o circuito deve ser alimentado com 3.3V.

⚠️ Nunca utilize 5V diretamente no ADC do ESP32-C3.


Valores de Leitura

Com os resistores do circuito e alimentação em 3.3V, teremos aproximadamente:

Botão                           Valor ADC
ESQUERDA                           0 a 50
FRENTE                           70 a 200
                           350 a 430
DIREITA                           700 a 740
OK                           1400 a 1600

Faixas de Leitura

O ideal é trabalhar com faixas, pois pequenas variações podem acontecer.

Exemplo:

if(valor < 50){
// esquerda
}
else if(valor > 70 && valor < 200){
// frente
}
else if(valor > 350 && valor < 430){
// ré
}
else if(valor > 700 && valor < 740){
// direita
}
else if(valor > 1400 && valor < 1600){
// ok
}



Ligação no ESP32-C3

MóduloESP32-C3
VCC3.3V
GNDGND
ADOGPIO ADC

Você pode usar:

  • GPIO0
  • GPIO1
  • GPIO2
  • GPIO3
  • GPIO4

(desde que tenham ADC)

Como Calibrar

Cada ESP32 pode apresentar pequenas diferenças no ADC.


/***************************************************************

   TESTE MÓDULO 5 BOTÕES ANALÓGICOS

   PLACA: ESP32-C3 Super Mini

   FUNÇÃO:

   Identificar os botões usando

   faixas de valores ADC

   AUTOR: RodRobot

***************************************************************/

#define BUTTON_PIN 0          // Pino ADC dos botões

// ================= SETUP =================

void setup()

{

  Serial.begin(115200);       // Inicializa Serial

  Serial.println();

  Serial.println("Teste dos 5 botoes");

}

// ================= LOOP =================

void loop()

{

  int valor = analogRead(BUTTON_PIN);   // Leitura ADC

  Serial.print("ADC: ");

  Serial.print(valor);

  Serial.print("  ->  ");

  // ================= ESQUERDA =================

  if (valor >= 0 && valor <= 50)

  {

    Serial.println("ESQUERDA");

  }

  // ================= FRENTE =================

  else if (valor >= 70 && valor <= 200)

  {

    Serial.println("FRENTE");

  }

  // ================= RE =================

  else if (valor >= 350 && valor <= 430)

  {

    Serial.println("RE");

  }

  // ================= DIREITA =================

  else if (valor >= 700 && valor <= 740)

  {

    Serial.println("DIREITA");

  }

  // ================= OK =================

  else if (valor >= 1400 && valor <= 1600)

  {

    Serial.println("OK");

  }

  // ================= NENHUM BOTÃO =================

  else

  {

    Serial.println("SEM BOTAO");

  }

  delay(250);

}



Para calibrar:
  1. abra o Serial Monitor
  2. pressione cada botão
  3. anote os valores
  4. ajuste as faixas no código

Vantagens Deste Sistema

✅ Usa apenas 1 pino ADC
✅ Reduz quantidade de fios
✅ Ideal para robôs
✅ Ótimo para menus OLED
✅ Fácil de expandir


Onde Utilizar

Este circuito é perfeito para:

  • controle de robôs com ESP-NOW
  • menu em display OLED
  • joystick simples
  • interface de configuração
  • controle portátil
  • projetos alimentados por bateria

O que é o ADC do ESP32-C3

ESP32-C3 Super Mini possui conversor analógico digital.

O ADC:

  • converte tensão em números digitais
  • permite ler sensores analógicos
  • permite ler divisores de tensão

No projeto usamos:

GPIO0

que no ESP32-C3 corresponde ao:

ADC1_CH0

Como o ESP32-C3 lê os botões

O código usa:

analogRead(BUTTON_PIN);

Essa função:

  1. mede a tensão do pino
  2. converte para um valor digital
  3. retorna um número

Exemplo:

int value = analogRead(BUTTON_PIN);

Depois o programa compara os valores:

if (value >= 70 && value <= 200)

Se estiver nessa faixa:

  • o botão FRENTE foi pressionado

Como funciona o ESP-NOW

ESP-NOW é um protocolo da Espressif Systems.

Ele permite:

  • comunicação rápida
  • baixo consumo
  • comunicação direta entre ESP32

Sem:

  • roteador
  • internet
  • servidor


Artigo comleto como funciona o ESP-NOW
https://rodrobot.blogspot.com/2026/05/esp-now-com-esp32-c3-e-esp32.html

Como o transmissor envia os dados

O código cria uma estrutura:

typedef struct struct_message
{
char command[20];

} struct_message;

Essa estrutura armazena:

  • texto do comando

Exemplo:

  • FRENTE
  • RE
  • OK

Envio dos dados

esp_now_send(receiverMAC,
(uint8_t *) &data,
sizeof(data));

O ESP32-C3:

  1. pega o texto
  2. transforma em bytes
  3. envia sem fio para outro ESP32-C3


Código do Transmissor (ESP32-C3)



/***************************************************************
   PROJETO: ESP32-C3 + 5 BOTÕES + ESP-NOW
   FUNÇÃO: Ler botões analógicos e enviar:
            - Nome botão
            - Valor ADC
            - Tensão em Volts

   PLACA: ESP32-C3 Super Mini

   AUTOR: RodRobot
***************************************************************/

#include <WiFi.h>               // Biblioteca WiFi
#include <esp_now.h>            // Biblioteca ESP-NOW

// ================= PINO ANALÓGICO =================
#define BUTTON_PIN 0            // GPIO0 = ADC1_CH0

// ================= MAC DO RECEPTOR =================
// TROQUE PELO MAC DO ESP32-C3 RECEPTOR
uint8_t receiverMAC[] = {0xAC, 0xA7, 0x04, 0xD6, 0x9D, 0xC4};  // MAC ESP32-C3 SUPER MINI

// ================= ESTRUTURA DOS DADOS =================
typedef struct struct_message
{
  char button[20];              // Nome botão

  int adcValue;                 // Valor ADC

  float voltage;                // Valor tensão

} struct_message;

struct_message data;

// ================= FUNÇÃO ENVIO =================
void sendData(const char *name,
              int adc,
              float volt)
{
  strcpy(data.button, name);    // Copia nome botão

  data.adcValue = adc;          // Salva ADC

  data.voltage = volt;          // Salva tensão

  // ================= ENVIA DADOS =================
  esp_now_send(receiverMAC,
               (uint8_t *) &data,
               sizeof(data));

  // ================= SERIAL =================
  Serial.print("Botao: ");
  Serial.print(name);

  Serial.print(" | ADC: ");
  Serial.print(adc);

  Serial.print(" | Volts: ");
  Serial.println(volt);
}

// ================= SETUP =================
void setup()
{
  Serial.begin(115200);         // Inicializa Serial

  WiFi.mode(WIFI_STA);          // Modo Station

  // ================= INICIA ESP-NOW =================
  if (esp_now_init() != ESP_OK)
  {
    Serial.println("Erro ESP-NOW");
    return;
  }

  // ================= CONFIGURA PEER =================
  esp_now_peer_info_t peerInfo;

  memcpy(peerInfo.peer_addr,
         receiverMAC,
         6);

  peerInfo.channel = 0;

  peerInfo.encrypt = false;

  // ================= ADICIONA PEER =================
  if (esp_now_add_peer(&peerInfo) != ESP_OK)
  {
    Serial.println("Erro Peer");
    return;
  }

  Serial.println("ESP32-C3 transmissor iniciado");
}

// ================= LOOP =================
void loop()
{
  // ================= LEITURA ADC =================
  int value = analogRead(BUTTON_PIN);

  // ================= CONVERTE PARA VOLTS =================
  float volts = (value * 3.3) / 4095.0;

  // ================= ESQUERDA =================
  if (value >= 0 && value <= 50)
  {
    sendData("ESQUERDA",
             value,
             volts);

    delay(300);
  }

  // ================= FRENTE =================
  else if (value >= 70 && value <= 200)
  {
    sendData("FRENTE",
             value,
             volts);

    delay(300);
  }

  // ================= RE =================
  else if (value >= 350 && value <= 430)
  {
    sendData("RE",
             value,
             volts);

    delay(300);
  }

  // ================= DIREITA =================
  else if (value >= 700 && value <= 740)
  {
    sendData("DIREITA",
             value,
             volts);

    delay(300);
  }

  // ================= OK =================
  else if (value >= 1400 && value <= 1600)
  {
    sendData("OK",
             value,
             volts);

    delay(300);
  }

  delay(50);                    // Estabilidade leitura
}



Como o receptor recebe

O receptor usa um callback:

esp_now_register_recv_cb(onReceive);

Quando chega um pacote:

  • a função é executada automaticamente

Mostrando no display OLED

Após receber o comando:

display.println(data.command);

O OLED mostra:

  • FRENTE
  • RE
  • ESQUERDA
  • DIREITA
  • OK


Código do Receptor (ESP32-C3)



/***************************************************************
   PROJETO: ESP32-C3 RECEPTOR + OLED
   FUNÇÃO: Receber via ESP-NOW:
            - Nome botão
            - Valor ADC
            - Tensão em volts

   MOSTRAR NO OLED:
            - Botão
            - ADC
            - Volts

   PLACA: ESP32-C3 Super Mini

   AUTOR: RodRobot
***************************************************************/

#include <WiFi.h>                    // Biblioteca WiFi
#include <esp_now.h>                 // Biblioteca ESP-NOW

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

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

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

// ================= ESTRUTURA DADOS =================
typedef struct struct_message
{
  char button[20];                  // Nome botão

  int adcValue;                     // Valor ADC

  float voltage;                    // Tensão

} struct_message;

struct_message data;

// ================= CALLBACK RECEBIMENTO =================
void onReceive(const esp_now_recv_info_t *info,
               const uint8_t *incomingData,
               int len)
{
  memcpy(&data,
         incomingData,
         sizeof(data));

  // ================= SERIAL =================
  Serial.print("Botao: ");
  Serial.print(data.button);

  Serial.print(" | ADC: ");
  Serial.print(data.adcValue);

  Serial.print(" | Volts: ");
  Serial.println(data.voltage);

  // ================= OLED =================
  display.clearDisplay();

  display.setTextColor(WHITE);

  // ================= TITULO =================
  display.setTextSize(1);

  display.setCursor(0, 0);

  display.println("COMANDO RECEBIDO");

  // ================= BOTAO =================
  display.setTextSize(2);

  display.setCursor(0, 18);

  display.println(data.button);

  // ================= ADC =================
  display.setTextSize(1);

  display.setCursor(0, 45);

  display.print("ADC: ");

  display.println(data.adcValue);

  // ================= VOLTS =================
  display.setCursor(70, 45);

  display.print(data.voltage, 2);

  display.print("V");

  display.display();
}

// ================= SETUP =================
void setup()
{
  Serial.begin(115200);             // Inicializa Serial

  // ================= I2C ESP32-C3 =================
  Wire.begin(8, 9);                 // SDA GPIO8 | SCL GPIO9

  // ================= INICIA OLED =================
  if (!display.begin(SSD1306_SWITCHCAPVCC,
                     0x3C))
  {
    Serial.println("Erro OLED");

    while (true);
  }

  // ================= TELA INICIAL =================
  display.clearDisplay();

  display.setTextSize(1);

  display.setTextColor(WHITE);

  display.setCursor(10, 25);

  display.println("AGUARDANDO...");

  display.display();

  // ================= WIFI =================
  WiFi.mode(WIFI_STA);

  // ================= ESP-NOW =================
  if (esp_now_init() != ESP_OK)
  {
    Serial.println("Erro ESP-NOW");
    return;
  }

  // ================= CALLBACK =================
  esp_now_register_recv_cb(onReceive);

  Serial.println("ESP32-C3 receptor iniciado");
}

// ================= LOOP =================
void loop()
{

}


Vantagens desse projeto

Usa apenas 1 ADC para 5 botões

Excelente para economizar GPIOs.


Comunicação sem fio rápida

ESP-NOW é extremamente rápido.


Baixo consumo

Ótimo para projetos com bateria.


Projeto modular

Você pode evoluir para:

  • robô com motores N20
  • DRV8833
  • sensores ultrassônicos
  • controle remoto sem fio
  • automação

Conclusão

Esse projeto mostra uma combinação muito poderosa do ESP32-C3:

  • leitura analógica
  • divisor de tensão
  • ESP-NOW
  • OLED
  • comunicação sem fio

Além de ser excelente para aprendizado, ele também serve como base para projetos maiores de robótica e automação com ESP32.


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

ESP32 para Iniciantes: Projeto LED Piscando Passo a Passo