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

Expectable data rates with NUS in multilink application

Hello,

we developed an application with a nRF52840DK as central and a custom board with a nRF52832 chip as peripheral. The peripheral sends data via NUS with a data rate of 40.8 kBit/s to the central. The code on the central is based on the ble_app_uart_c example and the code on the peripheral is based on the ble_app_uart example. This works fine.

Now we have to expand this application. We want to use one central with as much peripherals as possible. So we want to achieve the architecture which is shown in the following picture (e.g. with 3 peripherals):

To achieve this, we already found this multilink example code for our central (https://github.com/NordicPlayground/nrf52-ble-app-uart-c-multilink). It works well with the nRF52840DK as central and multiple Development-Boards based on nRF52832 chips as peripherals. Each peripheral can send data via NUS to the central at low data rates (e.g. 0.5 kBit/s).

We want to achieve a 40,8 kBit/s data rate between every peripheral and the central.

So here are our questions:

1. Is it possible to achieve this data rate between each peripheral and the central?

2. What are the correct connection parameters to achieve this? (The exact time when the NUS pakets are sent or received is not really important, each NUS paket is timestamped anyways)

3. Do you have any suggestions or tips, how to evaluate the maximum amount of peripherals properly?

Thank you very much in advance.

Parents
  • Hi,

     

    1. Is it possible to achieve this data rate between each peripheral and the central?

     Yes, 40 kbit/s should be fully possible to achieve.

    2. What are the correct connection parameters to achieve this?

     Well, you could probably achieve this with many different connection parameter sets(combinations of different MTU's sizes, Connection intervals, LL payload sizes, etc). But, one of the most important thing for achieving optimal performance in a multi-link setup like this is that all connections have intervals that have a common factor, as explained in the SDS Chapter Suggested intervals and windows. That means for e.g. a link with 3 peripherals like this, the connection interval should not be lower than NRF_SDH_BLE_GAP_EVENT_LENGTH * 3. In the SDK, most examples uses NRF_SDH_BLE_GAP_EVENT_LENGTH=6 (in 1.25ms units), so if you don't change that parameter, you should use a connection interval that is minimum 22.5ms.

    3. Do you have any suggestions or tips, how to evaluate the maximum amount of peripherals properly?

     We have a Throughput Example in the SDK, https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/ble_sdk_app_att_mtu.html, ,it's only written for testing a 1-to-1 connection, but it could be a good starting point for evaluation in a multi-link setup as well. We also have some numbers in the SDS Chapter Bluetooth Low Energy data throughput you can have a look at.

Reply
  • Hi,

     

    1. Is it possible to achieve this data rate between each peripheral and the central?

     Yes, 40 kbit/s should be fully possible to achieve.

    2. What are the correct connection parameters to achieve this?

     Well, you could probably achieve this with many different connection parameter sets(combinations of different MTU's sizes, Connection intervals, LL payload sizes, etc). But, one of the most important thing for achieving optimal performance in a multi-link setup like this is that all connections have intervals that have a common factor, as explained in the SDS Chapter Suggested intervals and windows. That means for e.g. a link with 3 peripherals like this, the connection interval should not be lower than NRF_SDH_BLE_GAP_EVENT_LENGTH * 3. In the SDK, most examples uses NRF_SDH_BLE_GAP_EVENT_LENGTH=6 (in 1.25ms units), so if you don't change that parameter, you should use a connection interval that is minimum 22.5ms.

    3. Do you have any suggestions or tips, how to evaluate the maximum amount of peripherals properly?

     We have a Throughput Example in the SDK, https://infocenter.nordicsemi.com/topic/sdk_nrf5_v17.0.2/ble_sdk_app_att_mtu.html, ,it's only written for testing a 1-to-1 connection, but it could be a good starting point for evaluation in a multi-link setup as well. We also have some numbers in the SDS Chapter Bluetooth Low Energy data throughput you can have a look at.

Children
  • Hello,

    thank you very much for your reply.

    I checked out the Throughput Example. Depending on the used parameters I can get up to 1300 kbps in a 1-to-1 connection. But when I use the ble_app_uart_c and ble_app_uart examples I can't even nearly reach this data rate.

    I modified the ble_app_uart example that it sends 204 Bytes every 40ms by calling ble_nus_data_send(). Connection Interval is also 40ms. It runs for a few seconds, then I get ERROR 19 [NRF_ERROR_RESOURCES] .

    So my question is:

    What do I have to change in the ble_app_uart example in order to reach a data-rate of >40 kbps without errors?

  • Did you change the value of NRF_SDH_BLE_GAP_EVENT_LENGTH ? If you had it at the default value of 6, then try to set it to 10.

  • Hello Sigurd,

    thank you very much for your reply.

    I changed the NRF_SDH_BLE_GAP_EVENT_LENGTH to 10 on central and peripheral. I also did the required changes regarding to the ram start.

    I have the following settings for the connection interval on central:

    // <o> NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL - Determines minimum connection interval in milliseconds. 
    #ifndef NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL
    #define NRF_BLE_SCAN_MIN_CONNECTION_INTERVAL 40
    #endif
    
    // <o> NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL - Determines maximum connection interval in milliseconds. 
    #ifndef NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL
    #define NRF_BLE_SCAN_MAX_CONNECTION_INTERVAL 40
    #endif
    On the peripheral I have the following parameters for the connection interval:

    #define MIN_CONN_INTERVAL               MSEC_TO_UNITS(40, UNIT_1_25_MS)
    #define MAX_CONN_INTERVAL               MSEC_TO_UNITS(40, UNIT_1_25_MS)  

    Which connection interval should I use, when I am calling the ble_nus_data_send() function every 40ms with 204 Bytes?

    At the moment I am still getting a NRF_ERROR_RECOURCES error after calling ble_nus_data_send() ~20 times. I start calling this function, when central and peripheral is connected and the MTU exchange has finished.

    Can you please provide me some further guidance how to achieve a stable 40kBit/s data-rate between central and peripheral?

    Thank you very much in advance.

    Best regards,

    Michael 

  • Michael01101 said:
    At the moment I am still getting a NRF_ERROR_RECOURCES error after calling ble_nus_data_send() ~20 times.

     How many peripherals is the central connected to when you see this issue?

    Is the central doing scanning at the same time? If yes, what is the scan window and scan interval? This might affect things.

    I assume that the peripheral, once connected, is no longer advertising.

    You could try set the hvn_tx_queue_size directly, and see if it improves anything, snippet:

    /**@brief Function for the SoftDevice initialization.
     *
     * @details This function initializes the SoftDevice and the BLE event interrupt.
     */
    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);
    
        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 = 10;
    
        err_code = sd_ble_cfg_set(BLE_CONN_CFG_GATTS, &ble_cfg, ram_start);
        if (err_code != NRF_SUCCESS)
        {
            NRF_LOG_ERROR("sd_ble_cfg_set() returned %s when attempting to set BLE_CONN_CFG_GATTS.",
                          nrf_strerror_get(err_code));
        }
    
    
    
        // 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);
    }

  • Hello,

    first of all, thank you very much for your quick reply.

    How many peripherals is the central connected to when you see this issue?

    Only 1. So the Central continues scanning.

    Is the central doing scanning at the same time?

    Yes.

    what is the scan window and scan interval?

    I use this parameters:

    #define NRF_BLE_SCAN_SCAN_INTERVAL 160
    #define NRF_BLE_SCAN_SCAN_WINDOW 80

    This are the default values of this multilink example. Do you recommend to adjust them?

    I assume that the peripheral, once connected, is no longer advertising.

    That is correct.

    You could try set the hvn_tx_queue_size directly

    I add this code snippet to my project. I set the hvn_tx_queue_size to 30 and made the required changes to the RAM parameters. (I have a lot of unused RAM)

    It looks like that the first data link between central and peripheral works now. But I need to do further testing to verify this (e.g. check if the hvn_tx_queue_size gets emptied fast enough). I will also try it with the other peripherals. I will let you know my results. But it looks promising at the moment. Thank you so much for this.

    Best regards,

    Michael

Related