BLE settings for max data transfer speed to iOS


I'm trying to send a dataset from the nRF51-DK over BLE to an iOS device. The total data to be sent is around 500 kB. What is the best method for transmitting this data quickly and what are the optimum BLE settings to achieve this? I am testing this using the iOS nRF UART app.

I am currently using the ble_app_uart_s110_pca10028 example in Keil v5. I have the code working sending strings of bytes using ble_nus_string_send command but it seems a bit slow. From reading other questions here on Devzone such as that linked below, sending 6 packets per interval is the maximum that can be achieved, how do I setup the code to transfer 6 packets on every interval?

What baud rate should I set the UART to, the default in the example code is 38400 with hardware flow control enabled. Or is UART over BLE even the best approach to transmit a reasonably large dataset with? Does iOS support hardware flow control?


  • Hi, kilianod.

    Here's a link that might be useful.

    In the link, it uses the HRS(Heart Rate Service).

    You can apply the same way by using NUS (Nordic UART Service).

    About the "optimum BLE settings", I'm not sure of the meaning.

    Is it about power consumption or adjusting the connection parameter?

    The NUS packet's maximum length is 20 bytes.

    Whereas the HRS packet sends 2 byte.

    I'm not sure but, maybe the UART over BLE could be a better option for you.

    -Regards, Mango922

  • Hi,

    The minimum connection interval on iOS is 20ms. With 6 packets per connection interval and a maximum of 20 bytes per packet, you are able to send 120 bytes every 20ms = 48kbit/s (6kB/s). You must send a connection parameter update request to change to these parameters, because Apple does not read the PPCP value you set. If your device is a HID device, the interval could be as low as 11.25ms, but their guidelines only state that they may accept these parameters.

    To have enough data to send, the UART baud rate should be larger than 48000, to account for overhead. I would try to use the fastest setting your source has tolerances for. The Master Control Panel application is able to send on 1Mbit to the dongles just fine, and 115200 should work fine if you have communication issues at the highest settings.

    The hardware flow control is strictly between the two devices talking UART, to make sure you do not send data when the chip is not able to hold more. This does not affect the iOS device in any way. If the source device does not support hardware flow control, you must send at a low enough speed to guarantee that there is no data loss - as talked about in the thread you linked.

    There is no setting to enable 6 packets per CI. The SoftDevice will send as many packets as it can (up to 6), so you only need to queue data fast enough so that the application buffers are always filled.

  • Thanks for your reply.

    So would I be correct in saying that I should disable Hardware flow control since an iOS device such as an iPhone does not support it?

    I'm using a Baud rate of 115200 and I am getting a transfer rate of approximately 1.5kB/s to the nRF UART App. Do you have any suggestions on how to increase this to close to the 6kB/s you mentioned? I have attached a small snippet of the code I'm using, I think the fact that I'm using the nrf_delay_ms function is probably a bad idea. This code is based off the ble_app_uart_s110_pca10028 sample app. In the code I'm sending 6 packets at a time with an increasing ascii character in the first byte.


    for (;;) { power_manage();

    for(int i=0; i<6; i++){
    	error_message=ble_nus_string_send(&m_nus, test, 20);
    	printf("%x \n",error_message);


  • You should be able to get a connection interval of 11.25ms with iOS whe using it as a HID keyboard and it should be possible a add a proprietary service along with it. You can then discover that proprietary Service on your iOS app and use it to transfer data. This should get you a faster link and better bandwidth. The other parts of the answer by the other poster still stands in addition.

    Edit: Unfortunately when the link is at 11.25ms for HID, iOS 9.x and lower seems to restrict the number of packets in a connection interval to 1, which means this will not improve your bandwidth.

  • I suggest that you do not have the UART in the transfer loop and get the wireless bandwidth that you want with just a application using the softdevice. Once you do that you can then add the UART to the transfer loop. UART over BTLE is as good as any other Service for the maximum bandwidth.