BLE UART data loss at speed

Hi,

We have an application based on BLE_UART TXing sensor data.

Most of our sensors are read through PPI with minimal code interaction (except for packet counters etc.)

It's running on our own hardware using the 52833 and S140 SD.

It's sending PDU's of 232 bytes to nRF toolbox running on an iPad (BLE 5.0)

The data rate is currently 25 PDU/s and it works quite reliably at this rate.

 

We want to increase this rate to 62.5 PDU/s.

However at this rate we lose a large proportion of the packets and also receive duplicates.

We also get an BLE_GAP_EVT_DISCONNECTED event after 90 seconds or so.

We have found the highest reliable data rate is 35 PDU/s

Even at 62.5 PDU/s that is only 116kbits/s well inside BLE 5.0 capability.

 

What can be done to fix this?

 

Thanks

 

 

 

Here is our setup parameters:

 

#define APP_BLE_CONN_CFG_TAG            1

#define APP_FEATURE_NOT_SUPPORTED       BLE_GATT_STATUS_ATTERR_APP_BEGIN + 2

#define DEVICE_NAME                     "Device8701"

#define NUS_SERVICE_UUID_TYPE           BLE_UUID_TYPE_VENDOR_BEGIN

#define APP_BLE_OBSERVER_PRIO           3

#define APP_ADV_INTERVAL                64

#define APP_ADV_TIMEOUT_IN_SECONDS      18000

#define MIN_CONN_INTERVAL               MSEC_TO_UNITS(20, UNIT_1_25_MS)

#define MAX_CONN_INTERVAL               MSEC_TO_UNITS(75, UNIT_1_25_MS)

#define SLAVE_LATENCY                   0

#define CONN_SUP_TIMEOUT                MSEC_TO_UNITS(4000, UNIT_10_MS)

#define FIRST_CONN_PARAMS_UPDATE_DELAY  APP_TIMER_TICKS(5000)

#define NEXT_CONN_PARAMS_UPDATE_DELAY   APP_TIMER_TICKS(30000)

#define MAX_CONN_PARAMS_UPDATE_COUNT    3

  • Hello,

    This is kind of classic development problem, meaning that something works until it doesn't work. So you need to try to narrow it down a bit, data should not be lost or corrupted by itself, so you need to look into whether any of the api call return an error code, and possible also look into adding additional buffers in both transmit and receive to handle the potential "overlap" due the increased throughput between BLE and UART occuring at the same time.

    Kenneth

  • Hi Kenneth,

    Just to clarify we are not using the UART we just adapted the example code.

    Data is simply sent from and received by the application.

    Most of the data is sent as a stream of packets from the IMU plus other peripherals (using PPI).  

    Below is our TX code with some debug error counters.

    The only error we are getting is: NRF_ERROR_RESOURCES

    At 140 PDUs/s we are loosing about 8 packets per minute.

    At 250 PDUs/s we are loosing about 800 packets per minute.

    What does NRF_ERROR_RESOURCES mean and what can we do to fix this problem?

    Also if we add the (commented out) do - while loop we get re-transmissions of PDUs, why would this be? 

    Thanks

    void nus_data_send(uint8_t * message, uint16_t length)
    {
    static uint32_t err_code;
    // If the message is too long set it to max
    if ( length > BLE_NUS_MAX_DATA_LEN )
    {
    length = BLE_NUS_MAX_DATA_LEN;
    }

    // do
    // {
    err_code = ble_nus_data_send(&m_nus, (uint8_t *)message, &length, m_conn_handle);

    if ( err_code == NRF_ERROR_INVALID_STATE )
    {
    err_invalid_state_count++;
    }
    else if ( err_code == NRF_ERROR_RESOURCES )
    {
    err_resources_count++;
    }
    else if ( err_code == NRF_ERROR_NOT_FOUND )
    {
    err_not_found_count++;
    }
    else
    {
    APP_ERROR_CHECK(err_code);
    }

    // } while (err_code == NRF_ERROR_RESOURCES);

    }

  • The NRF_ERROR_RESOURCES simply means that the softdevice buffer is full, and the application should wait for BLE_GATTS_EVT_HVN_TX_COMPLETE event before trying again. So I suggest to change your code a bit, either ignore NRF_ERROR_RESOURCES (which means packet will be lost) or the application need to buffer the packet on NRF_ERROR_RESOURCES event, and try again on BLE_GATTS_EVT_HVN_TX_COMPLETE event. You may also consider changing the connection interval (make it shorter) to allow more throughput in general. I am not sure how large packets you are sending for every notification, but typically combining more data into each notification is a good idea to increase throughput.

    Best regards,
    Kenneth

  • Hi Kenneth,

    If you send a packet ( call: ble_nus_data_send() ) and it returns NRF_ERROR_RESOURCES does that mean that that packet has been accepted and will be sent. i.e. does it indicate packet accepted send no more?

    Can the BLE SD buffer be increased?

    If we need our own FIFO buffer is there a library for that (or do we just write our own)? 

    How do we change the connection interval?

    BTW we are sending 232 bytes per packet so it's reasonably efficient.

    Thanks

    Ian

  • Ian Mellor said:
    If you send a packet ( call: ble_nus_data_send() ) and it returns NRF_ERROR_RESOURCES does that mean that that packet has been accepted

    No, that is the whole point of the return error, to tell the application that the packet was not buffered. If you want me to look at your throughput, then please provide an on-air sniffer log (e.g. using nrf sniffer for ble).

    Kenneth

Related