Hi, I'm interested in creating my own bluetooth speakers and wanted to know if anyone could suggest to me some suitable bluetooth receivers that i can use for my project. I'm going to be outputting audio signals from the bluetooth device to some speakers so i imagine it would need to handle higher impedance loads for an amplifier. I know that the device needs to support A2DP as well. It doesn't necessarily need to be compatible with arduino, just as long as it outputs an analog audio signal.
Apologies if this is the wrong place to ask, wasn't too sure which forum to post in.
Thanks in advance
Hi
There are two options here.
-
combine an ESP32 (£10) with a I2S stereo decoder . This will produce a high-quality line out signal that can be connected to an existing speaker with a line in.
-
combine The ESP32 with an audio amplifier that you then connect to a speaker.
The first option is the easiest as you don't have to worry about how to power the speaker(Which can be difficult a high volume). The second option is certainly possible though.
I have instructions on how to implement option 1 on Instructables and a library on github. The same code will work for both situations.
Hope this helps.
Is there any more information regarding as to how the ESP32 board works? Is btaudio.h a native library to the ESP32 Arduino Core or is that yours? If that library is yours, how would i output the digital signal to the I2S board from the ESP32 if i wanted to do it myself?
Thanks,
Hi,
Other than directly reading the ESP32 code it's pretty hard to work with features that are not officially supported by the core (Bluetooth audio and I2S). The available information is limited and while the examples provided by Espressif are thorough they are also complicated. That's why I made the library.
The library is my own but uses code from the ESP32 Arduino Core so it assumes that is installed. My library will automatically take care of the I2S output for you. You just need to tell it the required pins. All details are covered in the examples/readme/Instructables.
If you just want to use ESP32 code and not my library, The code below should work when using the ESP32 Arduino core.
// cricial audio bits taken from https://github.com/espressif/esp-idf/blob/master/examples/bluetooth/bluedroid/classic_bt/a2dp_sink/main/main.c
// bluetooth, config, discover and audio
#include "esp_bt_main.h"
#include "esp_bt_device.h"
#include "esp_gap_bt_api.h"
#include "esp_a2dp_api.h"
// the audio DAC and amp configuration.
#include "driver/i2s.h"
//globals
// the callback(processes bluetooth data).
// this is the most important function.
void bt_data_cb(const uint8_t *data, uint32_t len){
// number of 16 bit samples
int n = len/2;
// point to a 16bit sample
int16_t* data16=(int16_t*)data;
// create a variable (potentially processed) that we'll pass via I2S
int16_t fy;
// Records number of bytes written via I2S
size_t i2s_bytes_write = 0;
for(int i=0;i<n;i++){
// put the current sample in fy
fy=*data16;
//making this value larger will decrease the volume(Very simple DSP!).
fy/=1;
// write data to I2S buffer
i2s_write(I2S_NUM_0, &fy, 2, &i2s_bytes_write, 10 );
//move to next memory address housing 16 bit data
data16++;
}
}
void setup() {
// i2s configuration
static const i2s_config_t i2s_config = {
.mode = static_cast<i2s_mode_t>(I2S_MODE_MASTER | I2S_MODE_TX),
.sample_rate = 44100,
.bits_per_sample = I2S_BITS_PER_SAMPLE_16BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = static_cast<i2s_comm_format_t>(I2S_COMM_FORMAT_I2S|I2S_COMM_FORMAT_I2S_MSB),
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1, // default interrupt priority
.dma_buf_count = 8,
.dma_buf_len = 1000,
.use_apll = false,
.tx_desc_auto_clear = true
};
// i2s pinout
static const i2s_pin_config_t pin_config = {
.bck_io_num = 26,//26
.ws_io_num = 27,
.data_out_num = 25, //
.data_in_num = I2S_PIN_NO_CHANGE
};
// now configure i2s with constructed pinout and config
i2s_driver_install(I2S_NUM_0, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM_0, &pin_config);
i2s_set_clk(I2S_NUM_0, 44100, I2S_BITS_PER_SAMPLE_16BIT, I2S_CHANNEL_STEREO);
i2s_set_sample_rates(I2S_NUM_0, 44100);
// set up bluetooth classic via bluedroid
btStart();
esp_bluedroid_init();
esp_bluedroid_enable();
// set up device name
const char *dev_name = "ESP_SPEAKER";
esp_bt_dev_set_device_name(dev_name);
// initialize A2DP sink and set the data callback(A2DP is bluetooth audio)
esp_a2d_sink_register_data_callback(bt_data_cb);
esp_a2d_sink_init();
// set discoverable and connectable mode, wait to be connected
esp_bt_gap_set_scan_mode(ESP_BT_SCAN_MODE_CONNECTABLE_DISCOVERABLE);
}
void loop() {
// put your main code here, to run repeatedly:
delay(1000);
}
Okay, i think ill use the ESP32 Code then. But if that doesn't end up working for me do you have any other bluetooth device suggestions?
Sorry, I don't. I've only used the esp32 for Bluetooth audio. I haven't seen any other microcontrollers that can easily do this either.
If you do find other modules that work please post your experience with them.
My only bit of advice would still be to use an external DAC for the audio output unless you can verify that whatever module you use has a good enough DAC.