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

How to increase notification throughput on nRF52840?

Hello there,

I'm developing a C++ application on the BLE654 development bord which shall be able to generate and send 100+ BLE notifications per second on a single BLE connection.

On my first try it managed 5.

After some digging, I found that the soft device (s140, Ver 6.1.0) got a BLE_GAP_EVT_CONN_PARAM_UPDATE event, which set the minimum and maximum connection interval to 200 ms, wich was the defined MAX_CONN_INTERVAL (the code burrowed from the blinky example). After setting this to 20 ms I could get (close to) 50 notifications per second, but further decreasing the value again reduced the throughput (maybe the Android on the 'other side' of the BLE connection prohibited a further decrease).

I read somewere that soft devices from s120 up were able to process up to 6 notifications in a 7.5 ms connectipon interval, but here it looks as is the sd only does one notification per interval. What can/must be done to further increase the througput to reach at least 100 notifications per second?

Notes:

-in our application, we send the notifications with sd_ble_gatts_hvx(). I don't have exact numbers, but the internal queue of the soft device seemd rather small and we got a NRF_ERROR_RESOURCES error quickly, after wich we wait for a BLE_GATTS_EVT_HVN_TX_COMPLETE until we call sd_ble_gatts_hvx() again. I am certain the soft device at all time had notifications in its queue.

-as recipient of the notifications we used two tablets with Android 6.0.1 and 7.0, respectively. Both showed similar throughputs, and the final application shall also run on an Android device.

Regards,

     Lasse

  • Ok. But when you try to send one single string of length 80 bytes, or even longer, what is shown in nRF Connect? do you see the entire string?

    BR,

    Edvin

  • Hi Edvin,

    Using nRF Connect I see the same *censored* 20 Bytes I saw with any other application so far.

    However, there is something curious: If I use the "Request MTU" command from the Menu besides "SERVER" to increase the MTU to x Bytes, nRF Connect shows x-3 Bytes (the header, I know) of my string. That's great, but...

    -The gatt_evt_handler() of my device still says that the nRF Connect requested 0xF7 Bytes regardless of the Value I entered. I have no confirmation that the actual x Value was send to the device.

    -Only the first time I use "Request MTU" triggers the gatt_evt_handler(). I have to dis- and reconnect the device for it to trigger the gatt_evt_handler() again.

    -If I increase the MTU twice (i.e to 40 and then 60 Bytes) the nRF Connect still only shows 37 Bytes. If I increase and then decrease the MTU (i.e to 40 ant then 30 Bytes) the nRF Connect doesn't show any new notifications (allthoug it will again if i increase the MUT back to 40 or more).

    Do you know if this behaviour is a (misunderstood) feature or a bug in the nRF Connect?

    I'd love to send you a sniffer log of this, but still, we can't get the sniffer to work.

    Best regards,

         Lasse

  • Hello Lasse,

    I am sorry, but I am starting to loose track of where we are. Your phone supports a higher MTU, and the ble_app_uart example from SDK15.2.0 does as well, so there is something missing from your project that is not allowing it, I think. 

    Do you have gatt_init as in the ble_app_uart example?

    void gatt_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_ble_gatt_init(&m_gatt, gatt_evt_handler);
        APP_ERROR_CHECK(err_code);
    
        err_code = nrf_ble_gatt_att_mtu_periph_set(&m_gatt, NRF_SDH_BLE_GATT_MAX_MTU_SIZE); //247
        APP_ERROR_CHECK(err_code);
    }

    What is your NRF_SDH_BLE_GAP_EVENT_LENGTH in sdk_config.h?

    Can you compare your gatt values from the log in the ble_app_uart example and your example?

    In both projects, set #define NRF_LOG_DEFAULT_LEVEL 4 in sdk_config.h, and make sure you are looking at the log, and not the uart output in ble_app_uart. You need to check the RTT log.

    Try to send a string larger than 20 bytes using the ble_app_uart example. You should see a string longer than 20 *cencored* bytes in the mobile application. Do you see a string longer than this in your example?

  • Hello Edvin,

    I finally managed to nail down the problem. It seems that the only thing wrong with my application was that I set BLE_GATT_ATT_MTU_DEFAULT to 247. This seems to produce some undefined/unexpected behaviour of yout BLE stack.

    I now have

    BLE_GATT_ATT_MTU_DEFAULT          23

    NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247

    The actual MTU of course is lower than 247 Bytes thanks to the phone on the other side.

    Still, I now can accumuate my data and can send one notification instead of ten, which is a tremendous help. Btw, I still use sd_ble_gatts_hvx() for this, I didn't have to use the nus.

    Thanks for your help (and patience) in the last weeks!

    Best Regards,

         Lasse

Related