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

Data loss while sending large data by notifications with custom BLE service

Hello everyone,

A nRF52832 with SDK 15.0 was used for my application. I am trying to send a large amount of data via BLE with a custom BLE service. I extended MTU size so that it can meet my demand in both Client and Server. My Android app was developed to get the data. To check whether data sent by BLE device are lost or not, I added an index after a data package of 48-byte long. The following image is about index I got. 

There are 1, 2 or even 3 packages lost during data transmission. In this case, I tried to set the value of interval connection as low as possible (9ms). If I increased this interval as I have tested (24ms), there are more data packages lost.

Interestingly, if I use NUS BLE service instead and UART Android app to collect data,  this issue didn't happen and I can send up to 60 byte data per package without data loss. I double-checked my update data in custom BLE service, it is similar to that in NUS BLE service. 

Thus, are there any suggestion for me to solve this issue on the custom BLE service?

Thanks!

Parents
  • Ah-ha! You raise an interesting question. The Nordic Uart Service (NUS BLE Service) is not the same as the code you have above - the transfer of data from the Peripheral to the Central in NUS uses a Write Request, which requires an acknowledgement and therefore can only occur once every Connection Interval. The code you are using above uses a Write Command, which does not require an acknowledgement and can therefore be significantly faster with multiple packets possible in a Connection Interval. Note the NUS uses Write Command when the Central sends data to the Peripheral; Write Request is only Peripheral to Central in NUS.

    Does it matter? Well I didn't think so, as the handshake indicating packet success should occur at the LL level, but maybe that is not the case. In this post I asked about basically the same thing, and got a good response from martinbl which I recommend you read.

  • the transfer of data from the Peripheral to the Central in NUS uses a Write Request

    I don't think so as it uses notification to transmit data. I quoted what Martinbl answered in your post: The NUS peripheral example on the other hand, uses notifications. It is done with the function sd_ble_gatts_hvx() and happens in the function ble_nus_string_send() at the bottom of the file ble_nus.c.

    Btw, this post and this one mentioned about this term NRF_SDH_BLE_GAP_DATA_LENGTH which negotiates the BLE GAP data exchange. My project has been set this term with value of 27, I'll increase this and see what happens.

  • Good point. I have the following

    #ifndef NRF_SDH_BLE_GAP_DATA_LENGTH
    #define NRF_SDH_BLE_GAP_DATA_LENGTH 251
    #endif

  • Can't wait to test this. Will let you know what happens. Thanks for your discussion, !

  • I captured traces of both ends of the link on my sensor, although I am indeed using the NUS for these traces and so the case is a little different to yours; I am also using 2MHz PHY. I am changing from Notifications to Write Commands on the sensor transmissions, but don't yet have the throughput I am trying to achieve. I can post those traces when I get back to that part of the project.

    Sensor nRF52832 SES 15.3.0
    ==========================
    <info> app: Debug logging for UART over RTT
    <info> app: Connected (16 Connected to peer)
    <info> app: p_ble_evt: 85 85 Exchange MTU Request
    <info> app: Data len is set to 0xF4(244)
    <info> app: p_ble_evt: 58 58 Exchange MTU Response event
    <info> app: BLE_GAP_EVT_DATA_LENGTH_UPDATE: tx 251, rx 251 Times  tx 2120, rx 2120 usec
    <info> app: PHY updated: Tx 2, Rx 2 (34 PHY Update Procedure is complete)
    <info> app: BBLE_GATTS_EVT_WRITE: uuid 0x2902, type 1 (80 Write operation performed)

    Central nRF52832 - 15.3.0
    =========================
    <info> app: BLE Central Interface 2.0.1
    <info> app: Adv  Id 28842D1988DB
    <info> app: Scan Match Id: 28842D1988DB
    <info> app: Connect to Id 28842D1988DB
    <info> app: Connected to target
    <info> app: Issue PHY update request.
    <info> app: p_ble_evt: 85 85 Exchange MTU Request
    <info> app: BLE_GAP_EVT_DATA_LENGTH_UPDATE: tx 251, rx 251 Times  tx 2120, rx 2120 usec
    <info> app: ATT MTU data length was updated.
    <info> app: BLE_GAP_EVT_DATA_LENGTH_UPDATE: tx 251, rx 251 Times  tx 2120, rx 2120 usec
    <info> app: ATT MTU exchange completed.
    <info> app: Ble NUS max data length set to 0xF4(244)
    <info> app: p_ble_evt: 58 58 Exchange MTU Response event
    <info> app: BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: count 1, uuid 1 0x0001 (48 Primary Service Discovery Response event)
    <info> app: BLE_GATTC_EVT_CHAR_DISC_RSP: count 2, uuid 1 0x0002 (50 Characteristic Discovery Response event)
    <info> app: BLE_GAP_EVT_PHY_UPDATE: tx 2, rx 2 (34 PHY Update Procedure is complete)
    <info> app: BLE_GATTC_EVT_CHAR_DISC_RSP: count 0, uuid 1 0x0002 (50 Characteristic Discovery Response event)
    <info> app: Discovery complete.
    <info> app: Connected to sensor
    <info> app: BLE_GATTC_EVT_DESC_DISC_RSP: count 1, uuid 1 0x2902 (51 Descriptor Discovery Response event)
    <info> app: p_ble_evt: 56 56 Write Response event
    <info> app: BLE_GAP_EVT_CONN_PARAM_UPDATE: (18) Connection Parameters updated min 6, max 6, latency 0

    These are the sensor and central transmission code

    Sensoe - SES 15.3.0
    ===================
        hvx_params.handle = p_nus->tx_handles.value_handle;
        hvx_params.p_data = p_data;
        hvx_params.p_len  = p_length;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        return sd_ble_gatts_hvx(conn_handle, &hvx_params);
    
    Central 15.3.0
    ==============
        ble_gattc_write_params_t const write_params =
        {
            .write_op = BLE_GATT_OP_WRITE_CMD,
            .flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
            .handle   = p_ble_nus_c->handles.nus_rx_handle,
            .offset   = 0,
            .len      = length,
            .p_value  = p_string
        };
        return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);
    

Reply
  • I captured traces of both ends of the link on my sensor, although I am indeed using the NUS for these traces and so the case is a little different to yours; I am also using 2MHz PHY. I am changing from Notifications to Write Commands on the sensor transmissions, but don't yet have the throughput I am trying to achieve. I can post those traces when I get back to that part of the project.

    Sensor nRF52832 SES 15.3.0
    ==========================
    <info> app: Debug logging for UART over RTT
    <info> app: Connected (16 Connected to peer)
    <info> app: p_ble_evt: 85 85 Exchange MTU Request
    <info> app: Data len is set to 0xF4(244)
    <info> app: p_ble_evt: 58 58 Exchange MTU Response event
    <info> app: BLE_GAP_EVT_DATA_LENGTH_UPDATE: tx 251, rx 251 Times  tx 2120, rx 2120 usec
    <info> app: PHY updated: Tx 2, Rx 2 (34 PHY Update Procedure is complete)
    <info> app: BBLE_GATTS_EVT_WRITE: uuid 0x2902, type 1 (80 Write operation performed)

    Central nRF52832 - 15.3.0
    =========================
    <info> app: BLE Central Interface 2.0.1
    <info> app: Adv  Id 28842D1988DB
    <info> app: Scan Match Id: 28842D1988DB
    <info> app: Connect to Id 28842D1988DB
    <info> app: Connected to target
    <info> app: Issue PHY update request.
    <info> app: p_ble_evt: 85 85 Exchange MTU Request
    <info> app: BLE_GAP_EVT_DATA_LENGTH_UPDATE: tx 251, rx 251 Times  tx 2120, rx 2120 usec
    <info> app: ATT MTU data length was updated.
    <info> app: BLE_GAP_EVT_DATA_LENGTH_UPDATE: tx 251, rx 251 Times  tx 2120, rx 2120 usec
    <info> app: ATT MTU exchange completed.
    <info> app: Ble NUS max data length set to 0xF4(244)
    <info> app: p_ble_evt: 58 58 Exchange MTU Response event
    <info> app: BLE_GATTC_EVT_PRIM_SRVC_DISC_RSP: count 1, uuid 1 0x0001 (48 Primary Service Discovery Response event)
    <info> app: BLE_GATTC_EVT_CHAR_DISC_RSP: count 2, uuid 1 0x0002 (50 Characteristic Discovery Response event)
    <info> app: BLE_GAP_EVT_PHY_UPDATE: tx 2, rx 2 (34 PHY Update Procedure is complete)
    <info> app: BLE_GATTC_EVT_CHAR_DISC_RSP: count 0, uuid 1 0x0002 (50 Characteristic Discovery Response event)
    <info> app: Discovery complete.
    <info> app: Connected to sensor
    <info> app: BLE_GATTC_EVT_DESC_DISC_RSP: count 1, uuid 1 0x2902 (51 Descriptor Discovery Response event)
    <info> app: p_ble_evt: 56 56 Write Response event
    <info> app: BLE_GAP_EVT_CONN_PARAM_UPDATE: (18) Connection Parameters updated min 6, max 6, latency 0

    These are the sensor and central transmission code

    Sensoe - SES 15.3.0
    ===================
        hvx_params.handle = p_nus->tx_handles.value_handle;
        hvx_params.p_data = p_data;
        hvx_params.p_len  = p_length;
        hvx_params.type   = BLE_GATT_HVX_NOTIFICATION;
        return sd_ble_gatts_hvx(conn_handle, &hvx_params);
    
    Central 15.3.0
    ==============
        ble_gattc_write_params_t const write_params =
        {
            .write_op = BLE_GATT_OP_WRITE_CMD,
            .flags    = BLE_GATT_EXEC_WRITE_FLAG_PREPARED_WRITE,
            .handle   = p_ble_nus_c->handles.nus_rx_handle,
            .offset   = 0,
            .len      = length,
            .p_value  = p_string
        };
        return sd_ble_gattc_write(p_ble_nus_c->conn_handle, &write_params);
    

Children
Related