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
  • Hi run_ar,

    I am going to try to sniff it tomorrow. My protocol analyzer is at the home office, so I will do what I can with the DK.

    I don't timestamp NRF_LOG_PRINTF. I am using RTT, so the baudrate is not specified and it is very low latency. The peripheral stops advertising on connect. The central stops scanning 5s before the connection to the peripheral is made (I scan for 10s, then stop, then wait for 5, then connect to the two devices it found). On connection, BLE DB Discovery is performed and discovers all characteristics on each of the devices. After I receive the DB discovey completed message, I start pressing buttons. At that time, to my knowledge, no other BLE events are received other than the TX events.

    Thanks, -Alex

Reply
  • Hi run_ar,

    I am going to try to sniff it tomorrow. My protocol analyzer is at the home office, so I will do what I can with the DK.

    I don't timestamp NRF_LOG_PRINTF. I am using RTT, so the baudrate is not specified and it is very low latency. The peripheral stops advertising on connect. The central stops scanning 5s before the connection to the peripheral is made (I scan for 10s, then stop, then wait for 5, then connect to the two devices it found). On connection, BLE DB Discovery is performed and discovers all characteristics on each of the devices. After I receive the DB discovey completed message, I start pressing buttons. At that time, to my knowledge, no other BLE events are received other than the TX events.

    Thanks, -Alex

Children
No Data
Related