Hi,
I am trying to stream audio over BLE, I only manage to get 11k bytes per second transmit speed. Is there anyway to push this further? at 16k sampling rate and 16 bit depth I would require at least 32k bytes per second.
Things I tried;
- Increasing MTU, past 182 it seems to decrease the throughput
- Playing around with connection interval, seems to have no impact.
I read on nRF52840 documentation that transfer speeds of up to 2MB/s are possible, so it definitely should be posible. But perhaps arduinoBLE is not the way to go?
This is the code I am using right now:
#include <ArduinoBLE.h>
#include <mic.h>
#define MIC_SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define MIC_CHAR_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
BLEService micService(MIC_SERVICE_UUID);
BLECharacteristic micDataChar(MIC_CHAR_UUID, BLERead | BLENotify, 182);
mic_config_t mic_config{
.channel_cnt = 1,
.sampling_rate = 16000,
.buf_size = 364,
.debug_pin = LED_BUILTIN // Toggles each DAC ISR (if DEBUG is set to 1)
};
NRF52840_ADC_Class Mic(&mic_config);
#define SAMPLES 364
int16_t recording_buf[SAMPLES];
volatile static bool record_ready = false;
void setup()
{
Serial.begin(500000);
while (!Serial)
{
delay(10);
}
// Set callback to the mic
Mic.set_callback(audio_rec_callback);
Mic.setGain(-15);
if (!Mic.begin())
{
Serial.println("Mic initialization failed");
while (1)
;
}
if (!BLE.begin())
{
Serial.println("starting BLE failed");
while (1)
;
}
BLE.setAdvertisedService(micService);
// BLE.setAdvertisingInterval(20);
Serial.println("Before");
BLE.setConnectionInterval(0x0006, 0x0090);
Serial.println("After");
micService.addCharacteristic(micDataChar);
BLE.addService(micService);
BLE.advertise();
Serial.println("Bluetooth device active, waiting for connections...");
}
void loop()
{
BLEDevice central = BLE.central();
if (central)
{
Serial.print("Connected to central: ");
Serial.println(central.address());
digitalWrite(LED_BUILTIN, HIGH);
uint8_t buff[300];
memset(buff, 'a', 300);
while (central.connected())
{
micDataChar.writeValue(buff, 182);
}
digitalWrite(LED_BUILTIN, LOW);
Serial.print("Disconnected from central: ");
Serial.println(central.address());
}
}
static void audio_rec_callback(uint16_t *buf, uint32_t buf_len)
{
static uint32_t idx = 0;
// Copy samples from DMA buffer to inference buffer
for (uint32_t i = 0; i < buf_len; i++)
{
recording_buf[idx++] = buf[i];
if (idx >= SAMPLES)
{
idx = 0;
record_ready = true;
break;
}
}
}