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've also increased hvn_tx_queue_size to 7 and event_length to 320 (per other posts) in an attempt to increase the packets per interval (and adjusted ram start as needed). I am now calling ble_nus_string_send (effectively sd_ble_gatts_hvx) until the response is no longer NRF_SUCCESS - at this point, I wait until I receive BLE_GATTS_EVT_HVN_TX_COMPLETE before calling ble_nus_string_send again. Based on a simple counter, upon the second call ble_nus_string_send, I receive a NRF_ERROR_RESOURCES error. What am I missing?

  • 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-

    Thanks, it will take me a bit to work through this but I'll try to get back to you later today/tomorrow with my successes or failures - I appreciate the feedback! For reference, I am not requesting the MTU update, I am initializing with NRF_SDH_BLE_GATT_MAX_MTU_SIZE and the negotiation occurs to get to a data length of 182 (I believe this is a limitation of an SE running iOS 11.2).

    Yesterday I did try requesting a connection parameter update with the same parameters used during initial negotiation (15ms min, 75 ms max) - initial negotiation resulted in a 30ms connection interval, but the update request resulted in a 60ms interval!?! Its like iOS was punishing me for making the request:) I'll review your code vs. mine to see if there are any differences.

    I'll also see if I can borrow someone's iPhone8 to confirm your results.

    -Chris

  • Hung- I should add to the above that, when operating with a 60ms interval, I still was not sending more than 1 or 2 packets per interval. Is there anything else I should be doing to increase the number of packets sent per interval?

    -Chris

  • Have you make sure you queued the notification packets until the buffer is full (on the nRF52 side) ? I don't see any other way to increase the number of packets per interval except for queuing as quick as possible. As far as I understand, iOS will give a connection a limited event length in each connection event. I have seen at least 3 packets per connection interval (30ms) with 251 bytes each packet.

Related