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

Parents
  • Hi Chris,

    If you have a look at this presentation, you can find information about the 15ms firmware update mode and the estimated through put on new iOS (v11.x I assume) (page 119).

    We found some tricks that might be useful for you:

    • Try to request connection parameter update with both max and min interval to 15ms

    • Try not to request MTU, but let the phone does it, we got 247 bytes MTU.

    • Request data length extension (DLE).

    • Request 2Mbps.

    We tested with an iPhone 8 iOS 11.1 and got ~300kbps at 1Mbps and 650kbps at 2Mbps

    However, I'm not sure about the iPhone SE if it supports those 4.2 features and 5.0 features.

    You can have a look at our image demo here for your reference (the demo is without the first two "tricks" I mentioned above)

    Bellow is the main.c I modified to have it optimized for iOS, MTU request is delayed for 2 seconds to let the phone requests.

    main.c

  • Hung- Apologies I did not send the actual output, I was too focused on the details. Using an iPhone SE, I hit, on average, 124kpbs with a 182B data length and an average buffer length of 90. Based on the log in either lightBlue explorer or nRF toolbox, packets are being sent at ~15ms intervals, with occasional multiple packets per interval. Based on a quick calc, this makes sense - 182Bytes8bits(1/15ms) = 97kbps, 2 packets per interval is of course double this, so occasional multiple packets per interval would yield a throughput between these two numbers.

    With a S7, a ~480kbps throughput is achieved with a 244B data length and an average buffer length around 250. The log file on this device always crashes, so I can't be sure of the interval, but assuming 15ms, then given the 244B data length, multiple packets must be sent during a given interval.

    With a iPhone X, I was still only able to hit a 182B data length, but an average transfer speed of ~500kbps was achieved. Again, obviously multiple packets were sent.

    So, it seems that multiple packets are being sent per interval, but it also seems that, based on my code testing, making calls to sd_ble_gatts_hvx before receiving BLE_GATTS_EVT_HVN_TX_COMPLETE is not the mechanism which enables multiple packets per interval to be sent and actually doesn't seem to do anything since, until BLE_GATTS_EVT_HVN_TX_COMPLETE is received, sd_ble_gatts_hvx returns NRF_ERROR_RESOURCES.

    Apologies that I kind of backed in to this as an answer, but based off of documentation/threads elsewhere, I was led to believe that the multiple calls to sd_ble_gatts_hvx before receiving BLE_GATTS_EVT_HVN_TX_COMPLETE was necessary to maximize throughput. I just want to be sure that I have a (somewhat) reasonable understanding about how the examples work before I start working on my own code.

    Please let me know if you disagree or find any issues with what I've stated above.

    -Chris

Reply
  • Hung- Apologies I did not send the actual output, I was too focused on the details. Using an iPhone SE, I hit, on average, 124kpbs with a 182B data length and an average buffer length of 90. Based on the log in either lightBlue explorer or nRF toolbox, packets are being sent at ~15ms intervals, with occasional multiple packets per interval. Based on a quick calc, this makes sense - 182Bytes8bits(1/15ms) = 97kbps, 2 packets per interval is of course double this, so occasional multiple packets per interval would yield a throughput between these two numbers.

    With a S7, a ~480kbps throughput is achieved with a 244B data length and an average buffer length around 250. The log file on this device always crashes, so I can't be sure of the interval, but assuming 15ms, then given the 244B data length, multiple packets must be sent during a given interval.

    With a iPhone X, I was still only able to hit a 182B data length, but an average transfer speed of ~500kbps was achieved. Again, obviously multiple packets were sent.

    So, it seems that multiple packets are being sent per interval, but it also seems that, based on my code testing, making calls to sd_ble_gatts_hvx before receiving BLE_GATTS_EVT_HVN_TX_COMPLETE is not the mechanism which enables multiple packets per interval to be sent and actually doesn't seem to do anything since, until BLE_GATTS_EVT_HVN_TX_COMPLETE is received, sd_ble_gatts_hvx returns NRF_ERROR_RESOURCES.

    Apologies that I kind of backed in to this as an answer, but based off of documentation/threads elsewhere, I was led to believe that the multiple calls to sd_ble_gatts_hvx before receiving BLE_GATTS_EVT_HVN_TX_COMPLETE was necessary to maximize throughput. I just want to be sure that I have a (somewhat) reasonable understanding about how the examples work before I start working on my own code.

    Please let me know if you disagree or find any issues with what I've stated above.

    -Chris

Children
No Data
Related