This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

1000-2000ms delay during sd_ble_gattc_write

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.

  1. BLE_GATT_OP_WRITE_CMD uses an internal buffer, for which I would receive BLE_ERROR_NO_TX_BUFFERS - this is not occurring
  2. In fact, err_code is always NRF_SUCCESS
  3. 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

Parents Reply Children
No Data
Related