Módulos Wifi

Monitor de Áudio Bluetooth com ESP32

Erwin de Mattos 10 de abril de 2026

Introdução

No artigo anterior, “Reproduzindo Áudio WAV no ESP32”, exploramos o uso do ESP32 como plataforma de reprodução de áudio local, utilizando seu DAC interno para gerar sinal analógico diretamente a partir de dados digitais armazenados no próprio microcontrolador.

O passo seguinte nessa evolução é natural: se o ESP32 consegue reproduzir áudio localmente, por que não utilizá-lo também como receptor de áudio via Bluetooth?

É exatamente essa a proposta deste projeto.

Neste artigo será apresentado o desenvolvimento de um Monitor de Áudio Bluetooth programável, no qual o ESP32 se torna uma interface inteligente de mídia. A ideia central é transformar um simples receptor Bluetooth em uma plataforma aberta e totalmente programável, na qual o desenvolvedor possui controle sobre cada etapa do fluxo de áudio.

ESP32 vs Módulos Receptores Bluetooth Prontos

Módulos receptores Bluetooth dedicados são extremamente práticos para aplicações diretas — como transformar uma caixa ativa em Bluetooth. Nesses casos, essas soluções são suficientes.

Entretanto, o desenvolvedor não tem acesso ao protocolo, não controla os comandos de mídia e não pode interferir no processamento interno do áudio.

Ao utilizar o ESP32, a abordagem muda completamente. Torna-se possível implementar o perfil A2DP diretamente no firmware e também controlar o protocolo AVRCP, responsável pelos comandos de reprodução.

Instalando a biblioteca ESP32-A2DP

Para implementar a recepção de áudio Bluetooth via A2DP utilizaremos a biblioteca ESP32-A2DP, desenvolvida por Phil Schatzmann.

Essa biblioteca utiliza recursos da biblioteca AudioTools, também desenvolvida pelo mesmo autor.

Passo 1 – Baixar as bibliotecas

Acesse o repositório oficial da biblioteca ESP32-A2DP no GitHub

Acesse o repositório oficial da biblioteca AudioTools no GitHub

Em cada repositório, clique em Code → Download ZIP para baixar os arquivos.

Passo 2 – Instalar na Arduino IDE

Abra a Arduino IDE

Vá em Sketch → Incluir Biblioteca → Adicionar Biblioteca .ZIP

Selecione o arquivo ZIP baixado

Repita o processo para a segunda biblioteca

Passo 3 – Verificar o core do ESP32

A biblioteca depende do suporte oficial ao ESP32 na Arduino IDE.

Verifique em: Ferramentas → Placa → Gerenciador de Placas

Instale (ou atualize) o pacote oficial da Espressif para o ESP32.

Após esses passos, o ambiente estará pronto para compilar exemplos básicos de recepção A2DP.

 


Desenvolvimento

Fundamentos do Áudio Bluetooth no ESP32

O áudio Bluetooth no ESP32 utiliza o perfil A2DP (Advanced Audio Distribution Profile), responsável por transmitir áudio estéreo de alta qualidade entre dispositivos, como celular e receptor. A biblioteca ESP32-A2DP implementa esse protocolo de forma simplificada, permitindo que o microcontrolador atue como um receptor Bluetooth.

Após o recebimento e a decodificação do áudio via Bluetooth, o próximo passo é a conversão do sinal digital para analógico — etapa necessária para que o som possa ser amplificado e reproduzido em um alto-falante, essa conversão pode ser feita utilizando o DAC interno onboard ou enviando o áudio digital para um DAC externo via interface I²S.

A diferença entre as duas abordagens está principalmente na qualidade sonora e na arquitetura do projeto. O DAC interno oferece simplicidade, menos componentes e montagem mais direta. Já o DAC externo via I²S adiciona um módulo ao sistema, mas entrega menor nível de ruído, melhor resposta de frequência e maior fidelidade sonora.

Controle de Mídia via Microcontrolador

Uma das maiores vantagens de usar o ESP32 como receptor Bluetooth é a possibilidade de criar uma interface física personalizada, utilizando a própria biblioteca para enviar comandos de controle de mídia ao dispositivo conectado (celular, tablet ou computador).

Isso significa que você pode construir seu próprio painel físico utilizando: Botões táteis, Chaves seletoras, Potenciômetros, Displays informativos, e muito mais!

Você pode começar com dois botões simples e evoluir para um painel completo com display, indicador de volume, nome da faixa e até integração com outros sistemas. O hardware se torna apenas a interface física — enquanto a biblioteca faz o trabalho pesado da comunicação Bluetooth.


Interface de Controle

A biblioteca ESP32-A2DP fornece um conjunto direto de métodos para inicialização do Bluetooth, controle de reprodução, ajuste de volume, monitoramento de conexão e configuração da interface I²S no ESP32.

Essas funções representam uma camada de abstração que encapsula a complexidade do protocolo Bluetooth A2DP e do controle AVRCP. Em vez de lidar diretamente com a implementação de baixo nível, o desenvolvedor interage com métodos objetivos e diretos, simplificando a lógica do sistema.

A tabela a seguir reúne os principais comandos utilizados na construção de um receptor A2DP, servindo como referência prática para implementação, personalização e expansão do projeto.

 


Lista de Materiais

1x Módulo Amplificador de Áudio Com LM386 ou Módulo Amplificador MAX98357A
Obs.: iremos apresentar duas versões do projeto:
Modelo 1: ESP32 (dac interno) + amplificador externo + autofalante passivo
Modelo 2: ESP32 + dac externo com amplificador + autofalante passivo

Diagramas

Diagrama DAC interno – áudio mono (pin25)

Diagrama interface física


Código DAC INTERNO

#include "AudioTools.h"
#include "BluetoothA2DPSink.h"

// ======================================================
// =============== CONFIGURAÇÃO GERAL ===================
// ======================================================

// --------- Pinos de Controle ---------
const int BTN_PLAY = 32;
const int BTN_NEXT = 33;
const int POT_PIN  = 35;

// --------- Parâmetros de Áudio ---------
#define SAMPLE_RATE     44100
#define BITS_PER_SAMPLE 16

// ===== ESCOLHA DO MODO DE SAÍDA =====

#define AUDIO_MONO     // ← Descomente para MONO
//#define AUDIO_STEREO    // ← Descomente para ESTÉREO


// ======================================================
// ================= OBJETOS ============================
// ======================================================

// DAC interno do ESP32 (GPIO25 ou GPIO26)
AnalogAudioStream analog_out;
BluetoothA2DPSink a2dp_sink(analog_out);


// ======================================================
// ================= CONTROLE ===========================
// ======================================================

bool isPlaying = true;
int lastVolume = -1;

unsigned long lastDebouncePlay = 0;
unsigned long lastDebounceNext = 0;
const unsigned long debounceDelay = 200;


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

void setup() {

  Serial.begin(115200);

  pinMode(BTN_PLAY, INPUT_PULLUP);
  pinMode(BTN_NEXT, INPUT_PULLUP);

  // --------- Configuração do DAC Interno ---------
  auto config = analog_out.defaultConfig();
  config.sample_rate     = SAMPLE_RATE;
  config.bits_per_sample = BITS_PER_SAMPLE;

#ifdef AUDIO_MONO
  config.channels = 1;
  a2dp_sink.set_mono_downmix(true);
  Serial.println("Modo MONO (DAC interno)");
#endif

#ifdef AUDIO_STEREO
  config.channels = 2;
  a2dp_sink.set_mono_downmix(false);
  Serial.println("Modo ESTÉREO (DAC interno)");
#endif

  analog_out.begin(config);

  // --------- Configuração Bluetooth ---------
  a2dp_sink.set_volume(80);
  a2dp_sink.start("AudioMonitorBT_ESP32");

  Serial.println("Monitor de Audio via DAC interno iniciado");
}


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

void loop() {

  // ===== BOTÃO PLAY / PAUSE =====
  if (digitalRead(BTN_PLAY) == LOW) {
    if (millis() - lastDebouncePlay > debounceDelay) {
      if (isPlaying) {
        a2dp_sink.pause();
        Serial.println("Pause");
      } else {
        a2dp_sink.play();
        Serial.println("Play");
      }
      isPlaying = !isPlaying;
      lastDebouncePlay = millis();
    }
  }

  // ===== BOTÃO NEXT =====
  if (digitalRead(BTN_NEXT) == LOW) {
    if (millis() - lastDebounceNext > debounceDelay) {
      a2dp_sink.next();
      Serial.println("Next track");
      lastDebounceNext = millis();
    }
  }

  // ===== POTENCIÔMETRO (VOLUME) =====
  int potValue = analogRead(POT_PIN);     // 0–4095
  int volume = map(potValue, 0, 4095, 0, 127);

  /* ===== DEBUG ADC =====
  Serial.println(potValue);
  */

  // ===== ATUALIZA VOLUME (evita ruído excessivo) =====
  if (abs(volume - lastVolume) > 2) {
    a2dp_sink.set_volume(volume);
    lastVolume = volume;

    Serial.print("Volume: ");
    Serial.println(volume);
  }

  delay(10);
}

Código I2S

#include "AudioTools.h"
#include "BluetoothA2DPSink.h"

// ======================================================
// ======== CONFIGURAÇÃO DE HARDWARE E ÁUDIO ===========
// ======================================================

// --------- Pinos I2S ---------
const int I2S_BCK  = 26;  // Bit Clock
const int I2S_WS   = 27;  // Word Select (LRCK)
const int I2S_DATA = 25;  // Data Out

// --------- Controles ---------
const int btnPlay = 32;
const int btnNext = 33;
const int potPin  = 35;

// --------- Configuração de Áudio ---------

#define SAMPLE_RATE     44100
#define BITS_PER_SAMPLE 16

// ===== ESCOLHA DO MODO DE SAÍDA =====

#define AUDIO_MONO      // ← Descomente para MONO
//#define AUDIO_STEREO    // ← Descomente para ESTÉREO


// ======================================================
// ================= OBJETOS ============================
// ======================================================

I2SStream i2s;
BluetoothA2DPSink a2dp_sink(i2s);

// ======================================================
// ================= CONTROLE ===========================
// ======================================================

bool isPlaying = true;
int lastVolume = -1;

unsigned long lastDebouncePlay = 0;
unsigned long lastDebounceNext = 0;
const unsigned long debounceDelay = 200;


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

void setup() {

  Serial.begin(115200);

  pinMode(btnPlay, INPUT_PULLUP);
  pinMode(btnNext, INPUT_PULLUP);

  // --------- Configuração I2S ---------
  auto config = i2s.defaultConfig(TX_MODE);

  config.sample_rate     = SAMPLE_RATE;
  config.bits_per_sample = BITS_PER_SAMPLE;

#ifdef AUDIO_MONO
  config.channels = 1;
  a2dp_sink.set_mono_downmix(true);
  Serial.println("Modo MONO ativado");
#endif

#ifdef AUDIO_STEREO
  config.channels = 2;
  a2dp_sink.set_mono_downmix(false);
  Serial.println("Modo ESTÉREO ativado");
#endif

  // --------- Pinos I2S explícitos ---------
  config.pin_bck  = I2S_BCK;
  config.pin_ws   = I2S_WS;
  config.pin_data = I2S_DATA;

  i2s.begin(config);

  a2dp_sink.set_volume(80);
  a2dp_sink.start("AudioMonitorBT_ESP32");

  Serial.println("Monitor de Audio I2S iniciado");
}


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

void loop() {

  // ===== BOTÃO PLAY / PAUSE =====
  if (digitalRead(btnPlay) == LOW) {
    if (millis() - lastDebouncePlay > debounceDelay) {
      if (isPlaying) {
        a2dp_sink.pause();
        Serial.println("Pause");
      } else {
        a2dp_sink.play();
        Serial.println("Play");
      }
      isPlaying = !isPlaying;
      lastDebouncePlay = millis();
    }
  }

  // ===== BOTÃO NEXT =====
  if (digitalRead(btnNext) == LOW) {
    if (millis() - lastDebounceNext > debounceDelay) {
      a2dp_sink.next();
      Serial.println("Next track");
      lastDebounceNext = millis();
    }
  }

  // ===== POTENCIÔMETRO =====
  int potValue = analogRead(potPin);
  int volume = map(potValue, 0, 4095, 0, 127);

  if (abs(volume - lastVolume) > 2) {
    a2dp_sink.set_volume(volume);
    lastVolume = volume;
    Serial.print("Volume: ");
    Serial.println(volume);
  }

  delay(10);
}

Funcionamento

Vídeo utilizando o ESP32 + Módulo amplificador LM386 + Interface de controle (com saída de áudio via DAC Interna do ESP32)


No vídeo seguinte, está sendo utilizado o ESP32 + módulo amplificador Max98357A (com saída de áudio I2S)

 


Conclusão

A proposta de utilizar o ESP32 como receptor Bluetooth demonstrou que é possível substituir módulos comerciais fechados por uma solução aberta, flexível e totalmente programável. Ao implementar diretamente os perfis A2DP e AVRCP, o projeto ultrapassa a simples reprodução de áudio e se consolida como uma plataforma de desenvolvimento para sistemas de mídia embarcados, oferecendo autonomia técnica e liberdade de personalização.

A análise das arquiteturas de saída de áudio evidenciou que a escolha entre o DAC interno e um conversor externo via I²S — como o MAX98357A — depende dos objetivos do projeto. Enquanto o DAC interno atende aplicações compactas e funcionais, a solução externa amplia significativamente a qualidade sonora e a robustez do sistema. Essa flexibilidade reforça o caráter modular do ESP32, permitindo equilibrar custo, complexidade e desempenho conforme a necessidade.

A utilização da biblioteca ESP32-A2DP, desenvolvida por Phil Schatzmann, demonstrou que a abstração de alto nível simplifica a implementação dos protocolos Bluetooth sem limitar a expansão do projeto. A possibilidade de integrar botões, potenciômetros e displays transforma o microcontrolador em uma interface física personalizada de mídia, consolidando o sistema como uma base escalável para futuras aplicações — desde monitores de áudio até controladores dedicados.


Referências

SCHATZMANN, Phil. ESP32-A2DP Library. GitHub. Disponível em:
SCHATZMANN, Phil. Arduino Audio Tools. GitHub. Disponível em:
Espressif Systems. ESP32 Technical Reference Manual.
Bluetooth SIG. Advanced Audio Distribution Profile (A2DP) Specification.
Bluetooth SIG. Audio/Video Remote Control Profile (AVRCP) Specification.

Sobre o Autor


Erwin de Mattos

 


Lista de materiais

Erwin de Mattos

10 de abril de 2026

Erwin desenvolve projetos com microcontroladores voltados à geração sonora e aplicações musicais embarcadas. Atua com Arduino, ESP32 e programação em C/C++ e MicroPython, integrando conceitos de eletrônica, acústica e linguagem musical. Possui formação em Licenciatura em Música pela UFRJ e atualmente estuda Redes de Computadores, realizando projetos e laboratórios práticos em sistemas embarcados que unem música e tecnologia.

Os comentários estão desativados.

Tenha a Metodologia Eletrogate dentro da sua Escola! Conheça nosso Programa de Robótica nas Escolas!

Eletrogate Robô

Assine nossa newsletter e
receba  10% OFF  na sua
primeira compra!