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

nrf52832 - BLE UART performance with Android mobile clients

Hi,

i'm trying to sort out a performance problem I have with Android clients connecting to my nrf52832 using ble_nus service. Notice my problem is not about the absolute performance values, but the difference between iOS and Android. I'm trying to understand if anyone else here has encountered similar problems.

Here are some more details.

I have implemented a custom rx/tx protocol based on ble_nus service, SDK 14.2. Large response packets (max 4k) are sliced up to max available data length (considering DLE/MTU) and queued up with "sd_ble_gatts_hvx", while new packets are sent when a "BLE_GATTS_EVT_HVN_TX_COMPLETE" is received. Connection setup allows for 1M/2M phy, connection times from 7.5 to 500 ms, 0 latency, etc. I've been able to test with mobile phones using 2M PHY, DLE up to 251 bytes, larger MTU, etc. and the nrf52 side seems to be ok.

The problem is with mobile client implementation and seems to be unrelated to MTU, DLE or other performance tweeks. To sort our anything related to our client implementation, I am using nrf toolbox. This is what I see:

- nrf52 tries to send data. 4 packets are queued up, till NRF_ERROR_RESOURCES is received

- when BLE_NUS_EVT_TX_RDY is received and there is still data to be sent, try to queue up some more packes till NRF_ERROR_RESOURCES is received again

Both with iOS and Android the behavior is the sime, but the timings between last packet is queued and BLE_NUS_EVT_TX_RDY events are hugely different, just like if sending data to Android is way slower. In our code we tried with large MTU but it didn't change the fact that iOS even with basic 27 bytes MTU is enormously slower than Android. We've also tried different phones with different Android versions.

What's strange is that on some phones, it begins to become slow some time after connection: if the transmission starts right after connection, there are 3-4 seconds where performance is good, then it becomes slow. If instead transmission start 3-4 seconds after connection, it is slow from start.

I really don't know where to bang my head. Anyone noticed similar problems/has some suggestions?

Thanks!

  • What's strange is that on some phones, it begins to become slow some time after connection: if the transmission starts right after connection, there are 3-4 seconds where performance is good, then it becomes slow. If instead transmission start 3-4 seconds after connection, it is slow from start.

    This is leading my to think it may be related to some connection parameter update, where you are going from a fast connection interval with no slave latency, to a slow connection interval (possible with slave latency) enabled. If you have access to an on-air nRF sniffer log or similar we may take a look who is initiating this.

    You may in your code check if you have included conn_params_init() in your project and if it by accident is reducing your connection interval.

    You may also check out:
    https://devzone.nordicsemi.com/b/blog/posts/what-to-keep-in-mind-when-developing-your-ble-andr

  • Hi Kenneth,

    your comments made me wonder if it may be related to slave latency (or generically connection parameter updates), because it makes sense. Sadly I've not found anything in my code that may change them. I don't have a sniffer but I have enabled HCI logs in Android and again found an update sent from my firmware, but it contains exactly the parameters I've set and slave latency is 0.

  • I feel stupid since the problem was caused by me setting min connection time to 300ms. I could not imagine things could be so different because of this settings, since everything went so well with iOS and some old Android tablets. Setting the min to 7.5ms made other clients clients go faster.

    I still have some hard time understanding why things went so well with iOS or why the problems appeared after a few seconds with some phones (and not with others...). Probably iOS can send more packets between connection events.

    In any case, thanks for forcing me to recheck some stuff I took for good.

Related