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.

  • masterLee said:

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

    There was such a limit in the older versions of the SoftDevice(several years ago), but now the SoftDevice may transfer as many packets as can fit within the connection event as specified by the event length for the connection. This is mentioned in the SDS throughput chapter: https://infocenter.nordicsemi.com/topic/sds_s140/SDS/s1xx/ble_data_throughput/ble_data_throughput.html

  • Hi Sigurd,

    my main problem is that I cannot send more than one packet in one connection interval. This heavily reduces throughput. If I solve this issue I will be ok.

    When I try to send an array of data larger than 244 bytes with

    do
    {
        uint16_t length = (uint16_t)index;
        err_code = ble_nus_data_send(&m_nus, data_array, &length, m_conn_handle);
        if ((err_code != NRF_ERROR_INVALID_STATE) &&
            (err_code != NRF_ERROR_RESOURCES) &&
            (err_code != NRF_ERROR_NOT_FOUND))
        {
            APP_ERROR_CHECK(err_code);
        }
    } while (err_code == NRF_ERROR_RESOURCES);

    the transmission stops and an error 7 pops up.

    Since I have set the connection Interval at 10msec,  theoretically, I can include 7-8 packets of 244 bytes each.

    But the ble_nus_data_send() function returns an error 7 and the system freezes. How is this possible since the variable that holds the size of the data array is uint16_t ?

    For example, if I try to send an array of 488 bytes ( 2 packets of 244 bytes) and I set the length = 488  the function throws an error 7

    What am I doing wrong here?

  • masterLee said:
    error 7

     That is NRF_ERROR_INVALID_PARAM, if you take a look at the implementation of ble_nus_data_send(), you will see that you will get this error when you try to send a packet with length larger than NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH(1) - HANDLE_LENGTH(2)

     

    masterLee said:
    For example, if I try to send an array of 488 bytes ( 2 packets of 244 bytes) and I set the length = 488  the function throws an error 7

     You need to call ble_nus_data_send() 2 times instead then.(if NRF_SDH_BLE_GATT_MAX_MTU_SIZE == 247)

    One time with the first 244 bytes of the array, and then a second time with the last 244 bytes of the array.

Reply
  • masterLee said:
    error 7

     That is NRF_ERROR_INVALID_PARAM, if you take a look at the implementation of ble_nus_data_send(), you will see that you will get this error when you try to send a packet with length larger than NRF_SDH_BLE_GATT_MAX_MTU_SIZE - OPCODE_LENGTH(1) - HANDLE_LENGTH(2)

     

    masterLee said:
    For example, if I try to send an array of 488 bytes ( 2 packets of 244 bytes) and I set the length = 488  the function throws an error 7

     You need to call ble_nus_data_send() 2 times instead then.(if NRF_SDH_BLE_GATT_MAX_MTU_SIZE == 247)

    One time with the first 244 bytes of the array, and then a second time with the last 244 bytes of the array.

Children
Related