Hello all,
In controlling two devices simultaneously from one central controller, I have noticed significant time delays in processing the second call to sd_ble_gattc_write() but only some of the time (~25%). The code is basically below, some things renamed -
// Write characteristic to all connected devices
void write_charas(uint16_t uuid, uint8_t val) {
uint32_t err_code;
static ble_gattc_write_params_t write_params;
static uint8_t tmp_data;
tmp_data = val;
write_params.write_op = BLE_GATT_OP_WRITE_CMD;
write_params.offset = 0;
write_params.len = 1;
write_params.flags = 0;
write_params.p_value = &tmp_data;
for(uint8_t i = 0; i < rbcf.num_devices; i++) {
if(rbcf.devices[i].connected) {
// Check each of the characteristics for the UUID we are asking for
for(uint8_t c = 0; c < rbcf.devices[i].dev_db.services[0].char_count; c++) {
if(rbcf.devices[i].dev_db.services[0].charateristics[c].characteristic.uuid.uuid == uuid) {
// We found it, so set the handle to the chara handles and write the characteristic
write_params.handle = rbcf.devices[i].dev_db.services[0].charateristics[c].characteristic.handle_value;
NRF_LOG_PRINTF("Writing %d to characteristic value %d\r\n", val, write_params.handle);
err_code = sd_ble_gattc_write(rbcf.devices[i].conn_handle, &write_params);
NRF_LOG_PRINTF("Write result for CH %d was %d\r\n", rbcf.devices[i].conn_handle, err_code);
}
}
}
}
}
The above code pretty much just wraps a characteristic write call with some logic to delegate that call to a number of connected devices.
- BLE_GATT_OP_WRITE_CMD uses an internal buffer, for which I would receive BLE_ERROR_NO_TX_BUFFERS - this is not occurring
- In fact, err_code is always NRF_SUCCESS
- BLE_GATT_OP_WRITE_REQ always works immediately, if it works - but it's not guaranteed to work because technically, you would need to wait for a RESP event. Sometimes, it receives NRF_ERROR_BUSY, which is to be expected.
The next thing I was going to try was to implement a transmit queue that sends BLE_GATT_OP_WRITE_REQ, and on RESP event, sends the next item in the queue. However, it sounds like writes using BLE_GATT_OP_WRITE_CMD should already be buffered, and I never get any errors from it, but it's incredibly slow. Why is there a difference in the timing characteristics of BLE_GATT_OP_WRITE_CMD and BLE_GATT_OP_WRITE_REQ? If the timing were fixed, I wouldn't need to re-develop the transmit queue.
Obviously, I don't need these two events to happen absolutely simultaneously; within a few connection intervals is acceptable. Above 500ms is when it starts getting noticeably incorrect, and the 2s I am seeing feels like an error in the configuration somewhere since nearly everything else happens imperceptibly fast. It shouldn't take 100ms to scan 2 devices for all of their characteristics, and 20 times that time to send a queued characteristic write.
Just in case, I am using Eclipse/GCC, SD120, and the 10.0 SDK.
Any insight would be appreciated,
Thanks! -Alex