BLE setValue is "slow" (about 90ms), why?

I noticed that updating the value of a BLE characteristic with setValue(buf, len) is quite “slow”, it takes about 90ms when a device is connected and receiving the characteristics notifications. If no device is connected, the update takes < 1ms.

  • Is this caused by the NRF hardware or softdevice or is it the DeviceOS which takes this time?
  • Is there a ways to make this update faster?

Some relevant code snippets:

BleCharacteristic c1 = BleCharacteristic("a", BleCharacteristicProperty::NOTIFY, BleUuid(0x0001), sensorService)
...
uint8_t buf[4];
...
c1.setValue(buf, sizeof(buf));
c2.setValue(buf, sizeof(buf));

Log output (look at time difference):

0001126481 [hal.ble] TRACE: hal_ble_gatt_server_notify_characteristic_value().
0001126598 [hal.ble] TRACE: hal_ble_gatt_server_notify_characteristic_value().

Boron 2G/3G, deviceOS 1.4.0

@nils are you hosting a mesh network on that device? Bluetooth and Mesh share a radio so there will be some delays. You can remove it by using the particle mesh remove <device ID/name> to see if that makes a difference.

A less nuclear option should be Mesh.off()

1 Like

Interested in BLE progress. Surely sharing a radio hasn’t to do with setting the internal value…

Thank you for the hints regarding mesh, didn't think about that! But...

No, the device is not hosting a mesh network.

I added this to my setup(), didn't change anything.

setValue() takes this time only if a device is connected and receiving the notifications. Without connection the function returns in <1ms.

Any update on this? I tried changing the BleTXRxType to NACK in setValue thinking it might have been waiting for an acknowledge, but it still 93 on my Boron, deviceOS 1.4.4 with Mesh.off().

I am also curious for an update on this topic. I am using an Argon and seeing typical times of around 80ms when calling .setValue(). However, as the BLE signal is weakened or if there is obstructions between my phone and the Argon, I have seen times as long as 10 seconds. This also blocks the rest of my code while transmitting. Is there a way to have .setValue() not block the rest of the code?