/
/
Monitor de Áudio Bluetooth com ESP32

Monitor de Áudio Bluetooth com ESP32

Sumário

Baixe agora a apostila Arduino Iniciante e comece seus projetos

Compartilhe seu conhecimento e receba em dinheiro ou produtos.

Lista de materiais

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

 

O artigo apresenta o desenvolvimento de um Monitor de Áudio Bluetooth programável utilizando o ESP32, explorando a recepção de áudio via A2DP aliada ao controle de reprodução diretamente pelo microcontrolador.

Precisa dos componentes para este projeto?

Encontre tudo na Loja Eletrogate com frete grátis para compras acima de R$ 200