A BLE disconnection issue occurred randomly after the device had been functioning without any problems for many hours

Hi everyone,

We have devices using the BLE module (nRF52) deployed in clinics for testing. They have been functioning without issues until recently when we noticed occasional BLE disconnections. The following image shows data from one of the affected devices. Its RSSI value dropped significantly to -90 dBm, indicating weak BLE signal strength that could explain the disconnect. However, the device was positioned close to a tablet running the application connected to it, where the BLE signal strength should have remained strong. This inconsistency is what we find puzzling.

In another case, the RSSI value was within acceptable range (-68dBm), which couldn't lead to the BLE disconnection. 

We're thinking of if any issue with code optimization. Any suggestions to further investigate this issue would be greatly appreciated. Thanks!

Parents
  • Moving back to main thread so easier to track replies. What are the sizes of the two device BLE packets sent to the tablet, and how often are they sent? What would be the worst-case delay in stream update that could be tolerated? These effectively dictate optimum settings.

  • Thank you so much for following up on this, !. The following describes ble packets from each device being sent to the tablet's application. The device 01 is worn on the patient's foot. 

    I've read several posts regarding multiple peripheral devices sending data to the central device. However, they used another nRF52 device serving as a central device instead of the phone app. For connection parameters selection, I was able to config that for 2 peripheral devices as the following. On the phone app, seems it automatically negotiated and assigned the set of parameters by itself.

    // DEVICE 01
    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.1 seconds). */
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_1_25_MS) /**< Maximum acceptable connection interval (0.2 second). */
    #define SLAVE_LATENCY 0                                    /**< Slave latency. */
    #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)   /**< Connection supervisory timeout (4 seconds). */
    
    // DEVICE 02
    
    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(15, UNIT_1_25_MS) /**< Minimum acceptable connection interval (0.1 seconds). */
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS) /**< Maximum acceptable connection interval (0.2 second). */
    #define SLAVE_LATENCY 0                                    /**< Slave latency. */
    #define CONN_SUP_TIMEOUT MSEC_TO_UNITS(4000, UNIT_10_MS)   /**< Connection supervisory timeout (4 seconds). */

    What would be the worst-case delay in stream update that could be tolerated?

    Regarding the way I configure 2 devices to send data to the phone app, whenever data is available on each device, it notifies the phone app and sends data right away. The main limitation of the phone app when receiving data from 2 devices is that it only handles data from a device at a time. Say if it is receiving data from Device 01, while Device 02 keeps transmitting data to the phone app. Device 02's data will be queued on the air and arrived at the phone app as several ble packets as opposed to individual ble packet. 

    Edit: Fortunately, although we notice this limitation, we're able to retain most data without any packet loss happening in both devices.

  • Several BLE packets? Something not right there; are you not requesting increased data length? Some older tablets might restrict MTU to 23 byte packets. Lots of posts on this here, some notes:

    // <i> The SoftDevice handler will configure the stack with these parameters when calling @ref nrf_sdh_ble_default_cfg_set.
    // <i> Other libraries might depend on these values; keep them up-to-date even if you are not explicitely calling @ref nrf_sdh_ble_default_cfg_set.
    //==========================================================
    // <o> NRF_SDH_BLE_GAP_DATA_LENGTH   <27-251> 
    
    
    // <i> Requested BLE GAP data length to be negotiated.
    
    #ifndef NRF_SDH_BLE_GAP_DATA_LENGTH
    #define NRF_SDH_BLE_GAP_DATA_LENGTH 251
    #endif
    

    ATT Payload up to 244 bytes 251-4=247 247-3=244
    ATT MTU Determines the max amount of data that can be handled by the transmitter and receiver and which they can hold in their buffers.
    The MTU value affects the amount of overhead data (specifically the ATT header which is 3 bytes). The minimum ATT MTU allowed is 27 bytes. This allows a max of 20 bytes of ATT payload (3 bytes are used for the ATT header, and 4 bytes for the L2CAP header).
    There is no limit per the spec on how high the MTU value can be, but the specific stack in use may have its own limitations. For example, if you enable DLE then you can transfer up to 251 4 = 247 bytes (after deducting the L2CAP Header size). After taking into account the ATT header (3 bytes), we are left with 244 bytes for the actual ATT payload data. If the MTU is at least 247 bytes then the MTU will fit into one single packet. If the MTU is greater than 247 bytes, then the MTU will span multiple packets causing the throughput to go down (because of the packet overhead and timing in between the packets).

  • Totally agree with the ATT payload explanation. 

    For the device sending 48 bytes/packet, I set the NRF_SDH_BLE_GAP_DATA_LENGTH of 58 while another one sending 10 bytes/packet, I set the NRF_SDH_BLE_GAP_DATA_LENGTH of 27. I think these values satisfied the requirement such that the MTU won't span multiple packets, causing the low throughput due to increasing the overhead.

    Say if it is receiving data from Device 01, while Device 02 keeps transmitting data to the phone app. Device 02's data will be queued on the air and arrived at the phone app as several ble packets as opposed to individual ble packet.

    In my app, data collection from both devices works as follows: the app listens for notifications from each device and uses a switch-case structure to handle the data accordingly when a notification is received. Since the two devices have different sampling rates—100 Hz for one device and 250 Hz for the other—the app receives notifications from each device at different intervals, corresponding to their respective sampling rates.

    The following is what I captured from the app to illustrate what I mentioned above.

Reply
  • Totally agree with the ATT payload explanation. 

    For the device sending 48 bytes/packet, I set the NRF_SDH_BLE_GAP_DATA_LENGTH of 58 while another one sending 10 bytes/packet, I set the NRF_SDH_BLE_GAP_DATA_LENGTH of 27. I think these values satisfied the requirement such that the MTU won't span multiple packets, causing the low throughput due to increasing the overhead.

    Say if it is receiving data from Device 01, while Device 02 keeps transmitting data to the phone app. Device 02's data will be queued on the air and arrived at the phone app as several ble packets as opposed to individual ble packet.

    In my app, data collection from both devices works as follows: the app listens for notifications from each device and uses a switch-case structure to handle the data accordingly when a notification is received. Since the two devices have different sampling rates—100 Hz for one device and 250 Hz for the other—the app receives notifications from each device at different intervals, corresponding to their respective sampling rates.

    The following is what I captured from the app to illustrate what I mentioned above.

Children
  • 250Hz sounds suspiciously like ECG or similar; in a similar application I send 5 packets per second with 50 24-bit samples in each packet. The packets are bigger, of course, but the overall traffic is reduced. 5Hz display refresh rate allows smooth display scrolling of the waveforms. May not help, of course.

    Edit: By this I mean fewer packets per second means less blocking/waiting time for each device

    Edit2: I see there are in fact two RSSI; this means the 4mSec may be retransmitting frequently enough to hold off the 10mSec where the 4mSec has poor RSSI and the 10mSec RSSI is good, as perhaps in the original trace above. Worth trying much bigger and less frequent packets, methinks

  • Oh interesting. Can you elaborate more on the Edit2 you just mentioned? From my understanding, due to the limit of receiving data from the tablet, it only can receive data from one device at a time while another one is buffering its data and then sending several packets to the tablet.

    It seems you have another explanation of the above image in my previous reply. It's more about retransmitting data packets?

    Edit: the BLE disconnect mostly happens at the device with 100 Hz sampling rate (10mSec). This device has 48 bytes/packet being transmitted to the tablet. Since you brought up the RSSI, although 4mSec device sends data more frequently, if it has a poor RSSI, will 10mSec device take over to transmit the data to the tablet?

  • Worth trying much bigger and less frequent packets, methinks

    Will definitely try this! I read some articles about this. Seems it could help improve BLE stability:

    • Frequent transmissions increase the likelihood of packet collisions in environments with many BLE devices or RF interference (e.g., Wi-Fi, microwave ovens).
    • Reducing the frequency of transmissions can lower the risk of collisions and reduce retransmissions, improving stability.
Related