XIAO nRF52840 Sense pushing BLE throughput

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;

  1. Increasing MTU, past 182 it seems to decrease the throughput
  2. 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;
        }
    }
}

Although the purpose is different, I were able to transfer at a throughput of more than 50 kB/sec.

XIAO nRF52840, Efficiently Uploads Peripheral On-Board Flash ROM Data to Central