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

nRF52840 BLE Transfer speed issues

Hi all,

I have a custom nRF52840 board that transmits 32-byte packets to mobile device and I want to achieve maximum transfer speed.

The code is based on the ble_app_uart project

The BLE settings in my project are as follow:

//sdk_config
NRF_SDH_BLE_GAP_DATA_LENGTH 251
NRF_SDH_BLE_GATT_MAX_MTU_SIZE 247
NRF_SDH_BLE_GAP_EVENT_LENGTH 6

//main
MIN_CONN_INTERVAL   MSEC_TO_UNITS(8, UNIT_1_25_MS)
MAX_CONN_INTERVAL   MSEC_TO_UNITS(8, UNIT_1_25_MS)
 
ble_stack_init();
gap_params_init();
gatt_init();
services_init();
advertising_init();
sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_ADV,m_advertising.adv_handle,8); // Max  ADV Power = 8dB
sd_ble_gap_tx_power_set(BLE_GAP_TX_POWER_ROLE_CONN,m_advertising.adv_handle,8); // Max CONN Power = 8dB

The transmission data rate from the custom device to the mobile is 8kB/sec +/- ~400B

I want to reach maximum transfer speed but I don't know what the upper limit is.

Based on table 2 of the following link, I see that the max transfer speed is ~165kB/sec. So I try to figure out what I am doing wrong and my device's transfer speed is so low.

(https://infocenter.nordicsemi.com/index.jsp?topic=%2Fsds_s140%2FSDS%2Fs1xx%2Fble_data_throughput%2Fble_data_throughput.html)

From the debug session I get the following Information where the connection is established with DLE (247Byte / BLE_packet)

So I assume that something else keeps the transmission speed from my board to the mobile so low.

Also, I have a few questions :

1. How can I increase NRF_SDH_BLE_GATT_MAX_MTU_SIZE from 247 to 512? Because it is a 1-byte value and 512 needs 2-bytes  will need to mess with the SD libraries
2. Is it possible to increase the NRF_SDH_BLE_GAP_EVENT_LENGTH  higher than 6? Because when I set it to 7 or 8 the whole system stops.

If there is something else that I have not taken into account please correct me.

Thank you for your time

Regards

Parents
  • Hi,

    1. How can I increase NRF_SDH_BLE_GATT_MAX_MTU_SIZE from 247 to 512? Because it is a 1-byte value and 512 needs 2-bytes  will need to mess with the SD libraries

     It should be enough to just set it to 512. But, 247 will give you the max throughput. By setting NRF_SDH_BLE_GAP_DATA_LENGTH = 251 (this is max for this setting), and NRF_SDH_BLE_GATT_MAX_MTU_SIZE = 247, we avoid fragmentation of the ATT packet into several on-air data packets.

    2. Is it possible to increase the NRF_SDH_BLE_GAP_EVENT_LENGTH  higher than 6? Because when I set it to 7 or 8 the whole system stops.

     Yes, but you would likely need to allocate more RAM to the SoftDevice. How this is done depends on what toolchain/IDE you are using.

    Also, as long as the phone does not limit the amount of BLE packets per connection interval, you might be able to get slightly higher throughput with a higher connection interval.

    Also, I recommend enabling connection event length extension. You can enable Connection Event Length Extension with a function like this:

    void conn_evt_len_ext_set(bool status)
    {
        ret_code_t err_code;
        ble_opt_t  opt;
    
        memset(&opt, 0x00, sizeof(opt));
        opt.common_opt.conn_evt_ext.enable = status ? 1 : 0;
    
        err_code = sd_ble_opt_set(BLE_COMMON_OPT_CONN_EVT_EXT, &opt);
        APP_ERROR_CHECK(err_code);
    
    }

    Then call conn_evt_len_ext_set(true) after you have enabled the SoftDevice.

    If you still are having issues with throughput, please do a sniffer trace with nRF Sniffer.

  • Hi, I will try what you suggest.

    Now, regarding the max packets per connection interval,I read in post that the S140 has a maximum of 6 packets.

    Does it mean that  6 packets are transferred to one direction such as from the peripheral (nRF52840) to mobile or, 3 packets from each direction meaning three packets from the peripheral side and three packets from the central side?


    I am confused with the concept of data packets because if I get it right the data packets for one connection interval increase if I increase the connection interval. But from comparison tables and the fact that android devices can handle up to 6 packets per interval I understand that this is not true.

    Also I haven't found some definition in the softdevice documentation that specifies the exact number of maximum packets that it can handle.

  • The slave sets the MD(MoreData) bit to 1 when it sends the first packet, so it has more data to send. The master continues the connection event by sending a new empty packet, but the slave is not sending the packet in reply to that, and the connection event ends. In a 1-to-1 connection setup, I would have expected the slave to send another packet.

    Is the peripheral connected to several master devices when you tested this ?

  • Hi,

    No the peripheral is connected to a single central device (tablet). The tablet app is configured such a way that it can connect up to 5 peripherals. The good thing is that the speed is increasedto 50kBps by changing  the GAP_EVENT_LENGTH from 5 to 10. Further increments did not increase the speed. 

    Also, I noticed that although I set the PHY to 2M (inside ble_evt_handler) the tablet keeps it at 1M all the time.

    Any suggestions?

  • Regarding 2MPHY, did you e.g. add something like this to the BLE_GAP_EVT_CONNECTED event ?

                ble_gap_phys_t const phys =
                {
                    .rx_phys = BLE_GAP_PHY_2MBPS,
                    .tx_phys = BLE_GAP_PHY_2MBPS,
                };
                err_code = sd_ble_gap_phy_update(p_ble_evt->evt.gap_evt.conn_handle, &phys);
                APP_ERROR_CHECK(err_code);

    If yes, then you should be able to see a LL_PHY_REQ packet from the slave, and a LL_PHY_UPDATE_IND packet sent from the master in the sniffer log, indicating if it accepts the 2MPHY request or not.

  • Yes I set both at 2Mpbs in the EVT_CONNECTED event.

    Ok, I will check it out tomorrow morning first thing.

    Any suggestions, on how to add more 244-byte packets in one connection interval? Because as you can see in the sniffer log, for the duration of the connection interval only one 244-byte package is being sent to the peer and the rest of the interval is idle...

  • Good News at  last!! ! I reached 100kBps +/- 20kBps for a single connection between one peripheral device and the tablet.

    To sum up, In order to reach maximum throughput with BLE 5 PHY_2Mbps I performed the following changes (Slave Device = Custom nRF52840 Board & Master Device = Samsung Tab S6 with BLE 5)

    • In the ble_nus_data_send function() I use most of the length of the ATT package (244)
    • Set the GAP_EVENT_LENGTH = 10
    • Set both connection interval MIN and MAX = 10

    Sigurt, thank you for your valuable time and help on this issue!

Reply
  • Good News at  last!! ! I reached 100kBps +/- 20kBps for a single connection between one peripheral device and the tablet.

    To sum up, In order to reach maximum throughput with BLE 5 PHY_2Mbps I performed the following changes (Slave Device = Custom nRF52840 Board & Master Device = Samsung Tab S6 with BLE 5)

    • In the ble_nus_data_send function() I use most of the length of the ATT package (244)
    • Set the GAP_EVENT_LENGTH = 10
    • Set both connection interval MIN and MAX = 10

    Sigurt, thank you for your valuable time and help on this issue!

Children
Related