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

Increase data transfer rate for nRF52840 for queued write

Hi

I am using the provided example ble_app_queued_writes to send 256 bytes in each call.

It is taking around 13 seconds to transfer 3136 bytes:

12 calls of 256 and one for 64. Around 1 second per transfer. This seems very slow to me.

I checked many posts on this site and refered the throughput and long range demo to make the data transfer faster.

I got slight improvement of a second overall when i made following changes:

1) Updated BLE_GAP_DATA_LENGTH_DEFAULT to 128 from 27 (Successful)

2) Updated 

MIN_CONN_INTERVAL to MSEC_TO_UNITS(10, UNIT_1_25_MS) (Successful)

MAX_CONN_INTERVAL to MSEC_TO_UNITS(20, UNIT_1_25_MS) (Successful)

Other useful changes sugested gives error once the hex is uploaded:

1) ATT MTU :  NRF_SDH_BLE_GATT_MAX_MTU_SIZE more than 23 results in error:

<warning> app: System reset
<info> app_timer: RTC: initialized.
<warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
<warning> nrf_sdh_ble: Change the RAM start location from 0x20002300 to 0x20002C80.
<warning> nrf_sdh_ble: Maximum RAM size for application is 0x3D380.
<error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
<error> app: Fatal error

2) When updating to BLE_GAP_PHY_2MBPS getting again System reset

I am using Iphone 8 Plus to transfer data: on printing character maximumWriteValueLength i get value as 512

SDK: nRF5_SDK_16.0.0_98a08e2

Kit: nRF52840-DK

Am i correct thinking using queued write will be the fasted way to transfer data in volume? Is updating MTU, DLE not possible with it?

Please advice how i can make the data transfer faster?

Parents
  • 1) ATT MTU :  NRF_SDH_BLE_GATT_MAX_MTU_SIZE more than 23 results in error:

     You need to actually do these ram adjustments in your IDE settings. What do you use? Segger Embedded Studio?

     

    2) When updating to BLE_GAP_PHY_2MBPS getting again System reset

     What does the log say? Try to define DEBUG in your preprocessor definitions to see what the error handler points to.

    I just answered a very similar question. Check out the answer, and the project I attached in that ticket:

    https://devzone.nordicsemi.com/f/nordic-q-a/62363/nrf52832-throughput-test-with-nordic-uart-service

    Best regards,

    Edvin

  • I see currently this is the RAM settings in segger:

    FLASH_PH_START=0x0

    FLASH_PH_SIZE=0x100000

    RAM_PH_START=0x20000000

    RAM_PH_SIZE=0x40000

    FLASH_START=0x27000

    FLASH_SIZE=0xd9000

    RAM_START=0x20002300

    RAM_SIZE=0x3dd00

    From the link above attached project  \examples\nus_throughput\ble_app_uart\pca10056\s140\ses

    I get RAM settings as:

    FLASH_PH_START=0x0

    FLASH_PH_SIZE=0x100000

    RAM_PH_START=0x20000000

    RAM_PH_SIZE=0x40000

    FLASH_START=0x27000

    FLASH_SIZE=0xd9000

    RAM_START=0x20002bf0

    RAM_SIZE=0x3d410

    When i changed to this i get this error:


    <warning> app: System reset
    <info> app_timer: RTC: initialized.
    <warning> nrf_sdh_ble: Insufficient RAM allocated for the SoftDevice.
    <warning> nrf_sdh_ble: Change the RAM start location from 0x20002BF0 to 0x20002C80.
    <warning> nrf_sdh_ble: Maximum RAM size for application is 0x3D380.
    <error> nrf_sdh_ble: sd_ble_enable() returned NRF_ERROR_NO_MEM.
    <error> app: Fatal error

    Do you have a similar project for queued write?

    Please advice

  • Hi Edvin,

    As per your advice i have updated the event length as:

    in main.c

    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS) 
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(30, UNIT_1_25_MS) 

    in sdk_config.h

    #ifndef NRF_SDH_BLE_GAP_EVENT_LENGTH
    #define NRF_SDH_BLE_GAP_EVENT_LENGTH 30
    #endif

    But i was able to see the slight difference in the speed, now instead of 2 mins and 30 seconds it is taking 2 min and 20 seconds to transfer the data. But still the performance is very poor.

    For the ACK, do you mean i need to send data without response? For this i have been going through the blogs and and articled on this site and found a tutorial  but it does not show how to implement it.

    So i changed char to write without response as, i hope this is the correct way?

    add_char_params.char_props.write_wo_resp = true;

    In another post i found was this and i implemented the following:

    ble_cfg.conn_cfg.params.gattc_conn_cfg.write_cmd_tx_queue_size = 25;


    static void ble_stack_init(void)
    {
        ret_code_t err_code;
    
        err_code = nrf_sdh_enable_request();
        APP_ERROR_CHECK(err_code);
    
        // Configure the BLE stack using the default settings.
        // Fetch the start address of the application RAM.
        uint32_t ram_start = 0;
        err_code = nrf_sdh_ble_default_cfg_set(APP_BLE_CONN_CFG_TAG, &ram_start);
        APP_ERROR_CHECK(err_code);
    
    //---- UPDATE START
    
        ble_cfg_t ble_cfg;
    
        memset(&ble_cfg, 0, sizeof(ble_cfg));
        ble_cfg.conn_cfg.conn_cfg_tag = APP_BLE_CONN_CFG_TAG;
        ble_cfg.conn_cfg.params.gattc_conn_cfg.write_cmd_tx_queue_size = 25;
    
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTC, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);
    
    //---- UPDATE END
    
        // Enable BLE stack.
        err_code = nrf_sdh_ble_enable(&ram_start);
        APP_ERROR_CHECK(err_code);
    
        // Register a handler for BLE events.
        NRF_SDH_BLE_OBSERVER(m_ble_observer, APP_BLE_OBSERVER_PRIO, ble_evt_handler, NULL);
    }

    I even disabled the logs #define NRF_LOG_ENABLED 0

    This gave me no performance change at all. I am bit stuck on this. Please can you help me on this? Do you have any sample program where nRF52840 can receive data fast atleast 20-30KBPS?

    On the iOS side i checked we are ok we are getting maximumWriteValueLength as 512, Also iPhone is writing data without response so i think the problem is in firmware side.

    I look forward for your reply. I am really stuck here with speed issue.

    Thanks

  • Raja said:
    Do you have any sample program where nRF52840 can receive data fast atleast 20-30KBPS?

     Yes, I do. Please check my reply in the link from my very first reply. Without any changes the devices will have approximately 7-800 KBPS (bit not byte). 

    I suspect that your bottleneck is how you send your packets from the phone. If you send one packet every second, it doesnt help that your link supports 700KBPS. 

    Are you trying to send 20-30 KBPS from your phone?

  • Hi Edvin,

    Thanks for the reply Edvin.

    I followed the iOS example from Nordc github IOS-Pods-DFU-Library-master and IOS-nRF-Toolbox-master. I am sending data immediately without any delay from iPhone:

    Following statement is executed in loop until the data (153600 bytes) is fully transferred, i have not added any wait or delay:

    peripheral.writeValue(data, for: characteristic, type: .withoutResponse)

    Yes i am passing 153600 bytes of data from iPhone to nRF52840-DK

    These are the sample code i followed on iOS side:

    https://github.com/NordicSemiconductor/IOS-Nordic-Thingy/blob/develop/IOSThingyLibrary/Classes/Services/SoundService/ThingySoundService.swift

    https://github.com/NordicSemiconductor/IOS-Pods-DFU-Library/blob/master/iOSDFULibrary/Classes/Implementation/LegacyDFU/Characteristics/DFUPacket.swift

    Do you have any expert on the iOS side, i mean who wrote the above nordic libraries to kindly confirm if this is not correct?

    Thanks

  • What is the variable "data" when you call this? And do you do this in a loop? How often is it called?

    Have you tried capturing a sniffer trace of the connection? Perhaps that can show how often one of these packets are captured, what connection interval you are actually using, the MTU size that your connection is using and so on. Please be aware that it is the central/master in the connection that decides what connection parameters that will be used, so even if you set MIN and MAX CONN_INTERVAL in your peripheral, it doesn't mean that these are necessarily used. When you see the connection parameters that you have, you can compare this to what you get if you use the same parameters in the example:

    SDK\examples\ble_central_and_peripheral\experimental\ble_app_att_mtu_throughput.

    Best regards,

    Edvin

  • Hi Edvin,

    Thanks for all the help.

    My issue is resolved. The queued write was the bootle neck.

    I created a normal service and with that i was able to get speed of 500 Kbps.

Reply Children
No Data
Related