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 ?

Parents Reply
  • 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)

Children
  • 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 ?

  • 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 ?

    You can test the throughput using the ble_app_att_mtu_throughput example in the SDK. Remember to increase the data_length to 251. Connect with the phone using nRF Connect for mobile, and enable the notification in the app to start the test. What ATT_MTU and data length you get negotiated with the phone should be printed by the example, and at the end of the test the throughput result is printed.

  • I tried the example now, here is my take on it:

    1. between 2 boards with data_length 251 I get throughput of 1043 Kbps (kilo bit per second). That is about 125 kilo bytes per second - almost twice as fast as I need.

    2. When I write "run" with only one board after setting it as tester and attempting to connect to it using nRF Connect. I do see it in the scanned devices, but when I connect to it I see the services I have in *my* code (previously flashed hex). Ie, I dont see any services from the ble_app_att_mtu_throughput code (if there are any). So I have no idea how to test throughput between ble_app_att_mtu_throughput and nRF Connect.

  • Or said:
    I do see it in the scanned devices, but when I connect to it I see the services I have in *my* code

     The phone has cached the old services. Try to delete the bond on the phone, and connect again. It should then do a new service discovery when it connects.

Related