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

Multiple packets per connection interval - s132/IOS

Target - NRF52832 populated on a custom PCB using SDK 14.0.0 and s132 5.0

Background - end device will be used to send logged IMU data to the cloud via a smart device, 2-3mB expected to be sent at a time

Looking for a bit of help to increase the throughput using an IOS master (or really any device, but I'm currently using an iphoneSE). I'm running a lightly modified version of the peripheral ble_app_uart example - no UART functionality is now used, I am simply sending dummy data to evaluate throughput. Data length is successfully negotiated to 182 bytes. Connection interval is confirmed at 30ms. I am sending 182 byte packets (using ble_nus_string_send) upon every receipt of BLE_GATTS_EVT_HVN_TX_COMPLETE. Reviewing a log of packets received on the iphone (using lightBlue), I am predominately seeing a packet sent every ~30ms, with occasional packets separated by a few milliseconds. This results in a functional throughput of about 7kB/s.

I expected (hoped) that I would see multiple packets received within that 30ms window.

My questions:

  1. I've read that the connection interval can be dropped to 15ms with iOS devices - can you provide guidance with regards to the best way to complete this. I attempted to negotiate after a connection was made (using ble_conn_params_change_conn_params), but the 30ms interval was maintained. I understand that it may be better to stick with a longer connection interval given the bigger packet size (and assuming I can get to 6 or 7 packets per interval), but if I am limited to fewer packets per interval, a shorter connection interval would be better.

  2. What might be limiting me to 1, occasionally 2, packets per interval? Should I be attempting to send more frequently than waiting for BLE_GATTS_EVT_HVN_TX_COMPLETE?

Any help appreciated, I have searched, and turned up a number of good threads that have helped me get this far, but I think I've hit a bit of a wall.

-Chris

  • I don't think there is anything else. Note that you can always look at the MD (More Data) bit in a BLE packet (Link layer) to see if the slave saying that it still have more data to send but the master didn't send more packet or it's the opposite that the slave didn't have more data to send (MD = 0).

    I would suggest to test also with different central, Android, or another NRF52 acts as central for example.

  • I dropped the packet size down to 20B, now I am seeing 9-10 packets per interval being sent. This is with an interval set to 30ms or 60ms. Good news - does not seem to be a limitation on the iOS side. BUT, I also now realize that I am seeing a NRF_ERROR_RESOURCES error upon consecutive calls to "ble_nus_string_send" (really sd_ble_gatts_hvx) - even with a packet size of only 20B. It seems like I can only call "ble_nus_string_send" once I've received " BLE_GATTS_EVT_HVN_TX_COMPLETE" - but my understanding was that I could repeatedly call "ble_nus_string_send" until the buffer was full. Based on my current testing, the "buffer" fills after 20B - doesn't seem right. Should I be doing something differently to queue up packets?

    -Chris

  • Hung- The questions above still apply, but I was able to achieve a 15ms connection interval using the max and min interval set to 15 - I thought I had previously tried this, but apparently not. So, while I still cannot achieve more than a packet per interval for whatever reason, this shortened interval time effectively doubled my throughput - great news. Please let me know what I might be doing wrong in terms of sending packets to be queued, clearly I must be doing something incorrectly given how quickly I receive the RESOURCES error.

    I did also try an iPhone 10, curiously enough, the negotiated MTU size was still 185 bytes.

    -Chris

  • Hi Chris,

    Please try with this example and let us know what throughput you have. Note that you may tune it to have 15ms interval. And also to get 247 bytes MTU, you shouldn't request MTU update, let the phone do it.

    ble_UART_TP_examples.zip

  • Hung- Same result. If I modify the code to count the number of NRF_SUCCESS returns while "loop" = 1, and then I write this number to an array (length = 100) when NRF_ERROR_RESOURCES is returned, if I breakpoint on the array index rollover at any point during data transmission, the array is filled with "1" at every location. This is with sending the "asdf" array as-is, and with the byte count dropped to 20. Tested on both an iPhone SE and Samsung S7. Are you able to replicate/test on your end?

    Based on these results, it seems like you cannot call ble_nus_string_send again until BLE_GATTS_EVT_HVN_TX_COMPLETE is received.

    My understanding was that consecutive calls to ble_nus_string_send (sd_ble_gatts_hvx) would queue up packets in the buffer, and therefore would enable multiple packets per interval (if connection time allowed). What is the proper way to do this?

Related