2023年11月25日 星期六

ESP32 Bluetooth Speaker

Purpose:
Use ESP32 A2DP Sink (Music Receiver) to build your own Bluetooth Speaker.
This creates a new Bluetooth device with the name “MyMusic” and the output will be sent to the output directly to the internal DAC of the ESP32.
The output goes now to the DAC pins GPIO25 (Channel 1) and GPIO26 (Channel 2).
Architectures:
BOM(Bill of Material):
Single Speaker

Single Speaker

ESP32

Amplifier

Fundamental:

Features of the ESP32 include the following:
Processors:
CPU: Xtensa dual-core (or single-core) 32-bit LX6 microprocessor, operating at 160 or 240 MHz and performing at up to 600 DMIPS
Ultra low power (ULP) co-processor
Memory: 520 KiB RAM, 448 KiB ROM
Wireless connectivity:
Wi-Fi: 802.11 b/g/n
Bluetooth: v4.2 BR/EDR and BLE (shares the radio with Wi-Fi)
Peripheral interfaces:
34 × programmable GPIOs
4 × SPI
2 × I²S interfaces
2 × I²C interfaces
3 × UART

I2S is an electrical serial bus interface standard used for connecting digital audio devices together. It is used to communicate PCM audio data between integrated circuits in an electronic device.

ESP32 A2DP Library
Reference https://github.com/pschatzmann/ESP32-A2DP

XHM189 2 x 50W TPA3116D2 2-Channel High-end Digital Amplifier Board 24V Stereo
YouTube Demo:

ESP32 Code:
#include "BluetoothA2DPSink.h"

BluetoothA2DPSink a2dp_sink;

//----------------------------------------------------------------
//---------------------------------------------------------------------------------
#ifndef LED_BUILTIN
#define LED_BUILTIN 2
#endif
TaskHandle_t hled;
void initial()
{
  Serial.println(F("Create Task"));
  //--------------- create task----------------------------------
  xTaskCreatePinnedToCore(
    vLEDTask, "LEDTask" // A name just for humans
    ,
    1024 // This stack size can be checked & adjusted by reading the Stack Highwater
    ,
    NULL, 2 // Priority, with 3 (configMAX_PRIORITIES - 1) being the highest, and 0 being the lowest.
    ,
    &hled //handle
    ,
    0);
  //----------------------------------------
  //----------------------------------------------------------------------
  //vTaskSuspend(hfunction); //暫停TASK運行
  //----------------------------------------------------------------------
}

void setup()
{
  Serial.begin(9600);
  Serial.println(F("init"));
  initial();
  static const i2s_config_t i2s_config = {
        .mode = (i2s_mode_t) (I2S_MODE_MASTER | I2S_MODE_TX | I2S_MODE_DAC_BUILT_IN),
        .sample_rate = 44100, // corrected by info from bluetooth
        .bits_per_sample = (i2s_bits_per_sample_t) 16, /* the DAC module will only take the 8bits from MSB */
        .channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
        .communication_format = (i2s_comm_format_t)I2S_COMM_FORMAT_STAND_MSB,
        .intr_alloc_flags = 0, // default interrupt priority
        .dma_buf_count = 8,
        .dma_buf_len = 64,
        .use_apll = false
    };

  a2dp_sink.set_i2s_config(i2s_config);
  a2dp_sink.start("MyMusic");  

}


void loop() {
  Serial.print(F("Main at core:"));
  Serial.println(xPortGetCoreID());
  while(1)
  {
    vTaskDelay(5);
  }
}

//-------------------------------------------------------------------------
static void vLEDTask(void *pvParameters)
{
  (void)pvParameters;

  Serial.println(F("LEDTask at core:"));
  Serial.println(xPortGetCoreID());
  pinMode(LED_BUILTIN, OUTPUT);
  for (;;) // A Task shall never return or exit.
  {
    digitalWrite(LED_BUILTIN, HIGH); // turn the LED on (HIGH is the voltage level)
    vTaskDelay(200);
    digitalWrite(LED_BUILTIN, LOW); // turn the LED off by making the voltage LOW
    vTaskDelay(200);
  }
}

沒有留言:

張貼留言