PCM1808 BT Sender Working... 99% of the time. #735
Replies: 5 comments 3 replies
-
Beta Was this translation helpful? Give feedback.
-
Cool, I am surprised that this is working: In you fritzing you use the masterclock, but in your sketch it is commented out. ps. I do not recommend to use the depricated I2S API. Here is a similar much shorter sketch using the AudioTools which uses the I2S API, depending on your installed ESP32 core version. You would just need to define your pins: auto cfg = i2s.defaultConfig(RX_MODE);
cfg.i2s_format = I2S_STD_FORMAT; // or try with I2S_LSB_FORMAT
cfg.copyFrom(info32);
cfg.pin_mck = I2S_MCK;
cfg.pin_bck = I2S_BCK;
cfg.pin_ws = I2S_WS;
cfg.pin_data = I2S_DATA_IN;
//cfg.auto_clear = true;
cfg.use_apll = true; // from your logic: not sure if this works with the new API?
i2s.begin(cfg); |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
-
Latest software update: /* Copyright (C) 2020 Phil Schatzmann AudioInfo info24(44100, 2, 24); BluetoothA2DPSource a2dp_source; #define I2S_NUM I2S_NUM_0 // MD0 and MD1 left to float // The supported audio codec in ESP32 A2DP is SBC. SBC audio stream is encoded I2SStream i2s; #define SAMPLE_BUFFER_SIZE 128 // I2S New API Form
} bool isValid(const char* ssid, esp_bd_addr_t address, int rssi) void setup() // I2S configuration auto cfg = i2s.defaultConfig(RX_MODE); cfg.pin_mck = I2S_MCK; Serial.println("I2S Activate"); /// Info Serial.println("Activate BT Functions"); /// Info a2dp_source.set_ssid_callback(isValid); } void button_handler(uint8_t id, bool isReleased) void loop() |
Beta Was this translation helpful? Give feedback.
-
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Hello,
So, the main element of this is that the PCM1808 is sampling at 24 bits per channel. So, here is the code I tested till it worked.
Start with the BT_Sender from the examples then:
/*
Streaming of sound data with Bluetooth to other Bluetooth device.
We generate 2 tones which will be sent to the 2 channels.
Copyright (C) 2020 Phil Schatzmann
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see http://www.gnu.org/licenses/.
*/
#include "BluetoothA2DPSource.h"
#include <driver/i2s.h>
#include <math.h>
#define c3_frequency 130.81
BluetoothA2DPSource a2dp_source;
#define I2S_NUM I2S_NUM_0
#define SAMPLE_RATE 44100
#define I2S_BCK 14
#define I2S_WS 15
#define I2S_DATA_IN 32
#define I2S_MCLK 0
// MD0 and MD1 left to float
// FMT set to HIGH
// Clean power need to prevent interference with signal
// The supported audio codec in ESP32 A2DP is SBC. SBC audio stream is encoded
// from PCM data normally formatted as 44.1kHz sampling rate, two-channel 16-bit sample data
#define SAMPLE_BUFFER_SIZE 128
// I2S Data
int32_t get_i2s_frames(Frame *frame, int32_t frame_count)
{
size_t bytes_read = 0;
struct Xrame
{
uint32_t left_sample;
uint32_t right_sample;
} xrame[SAMPLE_BUFFER_SIZE];
i2s_read(I2S_NUM, (void*)xrame, frame_count * sizeof(Xrame), &bytes_read, portMAX_DELAY);
for (int sample = 0; sample < frame_count; ++sample)
{
frame[sample].channel1 = xrame[sample].left_sample>>12;
frame[sample].channel2 = xrame[sample].right_sample>>12;
}
return frame_count;
}
bool isValid(const char* ssid, esp_bd_addr_t address, int rssi)
{
Serial.print("available SSID: ");
Serial.println(ssid);
if (strcmp(ssid,"CMA3569") ==0)
return true;
else
return false;
}
void setup()
{
Serial.begin(115200);
Serial.println("Start"); ///Info
// I2S configuration
Serial.println("I2S Configure Data Loaded"); /// Info
i2s_config_t i2s_config =
{
.mode = i2s_mode_t (I2S_MODE_MASTER | I2S_MODE_RX),
.sample_rate = SAMPLE_RATE,
.bits_per_sample = I2S_BITS_PER_SAMPLE_32BIT,
.channel_format = I2S_CHANNEL_FMT_RIGHT_LEFT,
.communication_format = I2S_COMM_FORMAT_I2S,
.intr_alloc_flags = ESP_INTR_FLAG_LEVEL1,
.dma_buf_count = 8,
.dma_buf_len = 128,
.use_apll = true ///
// .tx_desc_auto_clear = true,
// .fixed_mclk = 0
};
i2s_pin_config_t pin_config =
{ // .mck_io_num = I2S_MCLK,
.bck_io_num = I2S_BCK,
.ws_io_num = I2S_WS,
.data_out_num = -1, // Not used
.data_in_num = I2S_DATA_IN
};
Serial.println("I2S Activate"); /// Info
i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM, &pin_config);
// i2s_set_clk(I2S_NUM, SAMPLE_RATE, I2S_BITS_PER_SAMPLE_32BIT, I2S_CHANNEL_STEREO);
i2s_start(I2S_NUM);
Serial.println("Activate BT Functions"); /// Info
a2dp_source.set_ssid_callback(isValid);
a2dp_source.set_auto_reconnect(false);
a2dp_source.set_data_callback_in_frames(get_i2s_frames);
a2dp_source.set_avrc_passthru_command_callback(button_handler);
a2dp_source.start("Quixote");
}
void button_handler(uint8_t id, bool isReleased)
{
if (isReleased) {
Serial.print("button id ");
Serial.print(id);
Serial.println(" released");
}
}
void loop()
{
delay(1000);
}
And there it is. The BT sink is hardcoded for my test speaker. There are a few stray lines of code and comments.
The PCM1808 module I used is a common Amazon type, purple pcb with 5 large capacitors and surface mount parts. I am using a ESP32-WROVER-IE dev module. Done in the Arduino IDE with the "ESP Wrover Module" as the board.
This was done on solderless breadboard. This part of a BT Zune console I am building.
I couldn't find much on this PCM1808 that worked, so here is one.
Beta Was this translation helpful? Give feedback.
All reactions