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.

Reply
  • 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.

Children
  • 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).

Related