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

Low transfer rate between nRF52840-DK (BLE) and nRF Connect (android app)

Hi,

I'm trying to transfer data between an nRF52840-DK and an Android phone which has nRF Connect installed on it and I can only reach about 40kbps (that is kilo bytes per second) where I need about 68kbps.

Here is what I do:

1. on the Android phone (Android 8, Samsung Galaxy 10) I open "nRF Connect" and connect to my custom device. Then I request connection priority high and set preferred PHY to LE 2M for both TX and RX.
I get success for switching PHY TX & RX to LE 2M. and connection is updated to interval: 15ms, latency: 0, timeout: 20000ms.
Then I turn on notifications to my custom characteristic.

2. on the nRF52840-DK I have PDM driver running that collects data into a buffer of type: int16_t pdm_buffer[254]; // biggest buffer that doesnt return an error
When the PDM driver handler is called with p_evt->buffer_released != NULL I send this buffer as a notification over a custom service + characteristics I created that handles the size of this buffer + 1 byte at the beginning for a running packet index (to see if I lose packets).

Overall PDM produces 16kHz * 2 (2 microphones) * 2 (16 bit) = 64000 bytes per second of data which I try to pass to the nRF Connect app in packets of size 254*2 + 1 = 509 bytes (254 samples + 1 index byte at the beginning).

Now, my problem is that I lose about 1/3 of the packets somehow (I can tell by looking at the first byte of the packets I do get in the nRF Connect log) which means a transfer rate of about 40kbps.

My question is - how can I increase the transfer rate ? how can I make it reliable ?

  • my configuration is:

    #define NRF_SDH_BLE_GATT_MAX_MTU_SIZE 1024 // had to adjust RAM start and length for this
    #define NRF_SDH_BLE_GAP_EVENT_LENGTH 352 // was 247, changed to 351, cant see any effect
    #define MIN_CONN_INTERVAL MSEC_TO_UNITS(7.5, UNIT_1_25_MS)
    #define MAX_CONN_INTERVAL MSEC_TO_UNITS(8, UNIT_1_25_MS)

    This is the MTU size I get (in the logs):
    <info> app: GATT ATT MTU on connection 0x0 changed to 517.

    I added the function and I call it, but the throughput stays the same.

    Has anyone ever got a higher transfer rate between an nRF52840-DK and an android device ? (higher than 40 kilo bytes per second)

  • Hi, 

    maybe you have the same case as this. In short - android device decreases priority of BLE in favor of WiFi link if there is no host activity for some time, solved by sending periodic host-initiated "keepalive" packets.

  • I believe we have seen at least around 1200 kbps on Android.

    Note that when the connection event starts, the SoftDevice will empty it's internal buffer as fast as possible by sending the packets to the other device. When the SoftDevice does not have any more packets to send, the connection event is ended, and you will need to wait until the next connection event starts before the SoftDevice sends packets to the peer device(android phone in this case) again.

    If possible, I recommend setting the ATT MTU size to 247(NRF_SDH_BLE_GATT_MAX_MTU_SIZE), as this will avoid fragmentation of the ATT packet into several on-air data packets.

    You could try to manually increase the TX buffer, and see if it have any effect:

        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.gatts_conn_cfg.hvn_tx_queue_size = 50;
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_cfg, ram_start);
        APP_ERROR_CHECK(err_code);

    (should be added to ble_stack_init() in main.c )

    A sniffer trace could also be useful in analyzing what is happening on-air.

  • 1. Changed NRF_SDH_BLE_GATT_MAX_MTU_SIZE to 247 and added the code you suggested between the call to nrf_sdh_ble_default_cfg_set() and the call to nrf_sdh_ble_enable().
    2. Updated the .ld file according to the required RAM start location and length that was written in the log.
    3. Connected to the DK with nRF connect and changed PHY to LE 2M (TX & RX) + requested connection priority to HIGH.

    4. Enabled notification (that makes the DK start sending packets) ... and I lose packets still.

    Is it possible for you to post a project code of yours that actually send at rate of 1200 kbps between the DK and the android device ?

  • I lose packets right away, not "after some time".

    .. and I get this problem when I connect to the DK with nRF Connect.

Related