We have a connection between our nRF52832 (server) and a tablet (client). We're trying to transmit some data at a rather high throughput. The connection parameters are as follows:
Connection interval: 60ms
Slave latency: 0
Connection supervision timeout: 1000ms
The data we try to transmit is as follows (in the priority we try to transmit):
Characteristic 1: 20 bytes, 5 packages / s
Characteristic 2: 20 bytes, 2 packages / s
Characteristic 3: 12 bytes, 2 packages / s
This works out to 9 packages / s. With a connection interval of 60ms, I figured we should have a max throughput of 1000ms / 60ms ≈ 16 packages / s. The way we transmit is essential as follows:
// Run once every 5ms
void HandleIndications(void) {
for (uint8_t i_char = 0; i_char < 3; i_char++) {
Char* p_char = chars[i_char];
if(p_char->HasIndication()) {
ble_gatts_hvx_params_t params;
params.handle = p_char->Handle();
params.type = BLE_GATT_HVX_INDICATION);
params.offset = 0U;
params.p_len = &len;
params.p_data = nullptr; // Use characteristics data buffer
// This will often return 0x08 or 0x11.
// If so, there will be no HVC event, and p_char->HasIndication()
// will still return true.
// Characteristic does not modify its data until it has received
// IndicationCallback (see HandleHavEvent()).
sd_ble_gatts_hvx(conn_handle, ¶ms);
break;
}
}
}
// SoftDevice event handler (for HVC)
void HandleHvcEvent(const ble_gatts_evt_hvc_t& hvc) {
if (p_char->Handle() == hvc.handle) {
const Codes::Result char_res =
p_char->IndicationCallback(Codes::Result::kOK);
if ((f_res == Codes::Result::kOK) &&
(char_res != Codes::Result::kOK)) {
f_res = char_res;
}
}
// Handle pending indications
HandleIndications();
}
If we compare the number of HVX's with HVC's they match.
If we compare the number of HVX's with the expected number of transfers only 3/4 of Characteristic 2 are transfered and only 1/3 of Characteristic 3. Due to the prioritisation, they don't transfer equally. Its also confirmed that the data being pushed to the characteristics will fill their internal buffers and data is discarded.
As far as I can tell, the application is responding to the HVC event promptly and there is little delay on the application side to send new HVX requests to the SoftDevice.
Using nRF Connect I have tried changing the connection interval to 7.5ms and then all works as intended. But that is not possible on the tablet (where 60ms is the minimum connection interval).
What are likely culprits in the reduced throughput in this scenario and what steps can be taken to improve the situation?
nRF52832
SoftDevice 132 v3.0.0
No SDK