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

Question regarding the transfer speed of the BLE on nrf52832 using nordic uart service

Hi Everyone

I have been trying to send a text file(reading from SD card) , The size of the file is 2MB. 
I am using softdevice s132 for nrf52832 to transfer the text file via the Bluetooth to the Android application(nrf Connect). 
I am able to transmit the file to the nrf connect app , but the problem is that the transfer is too slow , it gives me an average speed of around 20KBPS , which is very less for our application.

What  i would like to know is 
1. Is there any specification of the softdevice which i should enable to receive the maximum throughput(or atleast 3/4th of it). 
2. Is it related to the service that i am using , I am using Nordic Uart Service. 

Here are the settings that i have been using
PHY - LE 1M for both Tx and Rx
Here is a log file , i am attaching , if that helps.

5001.Log 2020-10-07 12_34_02.txt

  • It goes in a breakpoint if i change this value

  • NRF_SDH_BLE_GAP_EVENT_LENGTH 50 , makes my software go to breakpoint

  • NRF_SDH_BLE_GAP_EVENT_LENGTH 50 , makes my software go to breakpoint

    You need to allocate more RAM to the SoftDevice, after increasing NRF_SDH_BLE_GAP_EVENT_LENGTH 

  • Please explain the below mentioned behaviour as well , i think it is something related to the nrf Connect for android
    Because , if i manually change the PHY from nrf connect , everything seems to work fine and at reasonable speeds


    1. With the nrf Dongle connected to PC and data transfer via nrf Connect for PC gives me desirable result and following result are seen on connection


      Sending PHY Update, 2 Mbps.
      ATT MTU exchange completed. MTU set to 247 bytes.
      Data length updated to 251 bytes.
      PHY update accepted
      PHY set to 2 Mbps.


    2. With any Android device and nrf Connect for android gives me the following results on connection(My android mobile is oneplus 7pro , it supports BLE5.0 with PHY-2M)


    Sending PHY Update, 2 Mbps.
    ATT MTU exchange completed. MTU set to 247 bytes.
    Data length updated to 251 bytes.
    PHY update rejected
    PHY set to 1 Mbps.Connection interval updated: 0x6, 0x6.
    ATT MTU exchange completed. MTU set to 247 bytes.
    Connection interval updated: 0x24, 0x24.
    Data length updated to 251 bytes.

  • Most phones will only use 7.5m connection interval when connecting, and after service discovery is done, change it to a higher value.

    On Android you can “Request connection priority”,

    High: 11.25 – 15 ms

    Balanced: 30 – 50 ms

    Low Power: 100- 125 ms

    But you can also adjust the CONN_INTERVAL_MIN , and CONN_INTERVAL_MAX in your application, and then the Connection Parameters module will request a connection interval between the min/max values. But ultimately, it’s the central device that decides the connection interval.

    You can try to change the PHY from the phone, or request 2M PHY some time later from your application. Some phones does not seem to accept a PHY change before service discovery is done.

    Here is some code you can use to request a PHY change from your application:

    APP_TIMER_DEF(m_phy_update_delay_timer_id);                           /**< PHY update timer. */
    
    
    static void phy_update_delay_timeout_handler(void * p_context)
    {
        UNUSED_PARAMETER(p_context);
    
        NRF_LOG_DEBUG("PHY update request.");
    
        ble_gap_phys_t const phys =
        {
            .rx_phys = BLE_GAP_PHY_2MBPS,
            .tx_phys = BLE_GAP_PHY_2MBPS,
        };
    
        if(m_conn_handle != BLE_CONN_HANDLE_INVALID)
        {
            uint32_t err_code = sd_ble_gap_phy_update(m_conn_handle, &phys);
            APP_ERROR_CHECK(err_code);
        }
    
       
    }
    
    
    in timers_init(), add
    
        err_code = app_timer_create(&m_phy_update_delay_timer_id,
                                    APP_TIMER_MODE_SINGLE_SHOT,
                                    phy_update_delay_timeout_handler);
        APP_ERROR_CHECK(err_code);
    
    
    
    in ble_evt_handler() , under case for BLE_GAP_EVT_CONNECTED
    
                err_code = app_timer_start(m_phy_update_delay_timer_id, APP_TIMER_TICKS(7000), NULL);
                APP_ERROR_CHECK(err_code);

Related