This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

General questions on sending multiple packets in a connection interval (how to queue multiple packets)

Hi Nordic Magicians,

I have a couple of general questions when it comes to sending large amounts of data (FAST). Ultimately, I'm looking to transmit data with a throughput of about 1 Mb/s (each individual packet of data is 65 Bytes). System power isn't an issue and my central and peripheral devices will be within 1 meter of each other.

Based off a number of other posts it seems there are a couple of nobs I should play with:

  • Increase my ATT_MTU to at least 250 bytes (this way I can get 3 65 byte packets into a single bluetooth packet) 
  • Use a short connection interval (while this may increase overhead - I'll need to buffer data from my SPI in between bluetooth packets so using a small connection interval will let me be confident in the max number of SPI packets I need to be able to queue)
  • Enabling "connection event length extension" (does this make a difference if my min connection interval = max connection interval?)
  • Queueing multiple notifications to be sent during a single connection interval

Furthermore, it seems increasing tx power won't help because my devices will be close to each other.

If my notes up above are correct I have a follow up question regarding queueing notifications.

1) I need to increase my hvn_tx_queue_size, correct? I set it to 18 in the following code. There's nothing else I need to change, right? Some posts mention needing to change a memory start location in my linker script but others didn't.

static void ble_stack_init(void)
{
    ret_code_t err_code;

    err_code = nrf_sdh_enable_request();
    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 = 18;
    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);

}


2) I've built my application off of the peripheral ble_app_uart example code and use the ble_nus_data_send() function to send data. Digging into the function it seems it uses the appropriate function (sd_ble_gatts_hvx()) to add packets to the notification queue. This means I should be able to just call it multiple times and it should handle everything for me, correct? When sd_ble_gatts_hvx returns NRF_SUCCESS, does that mean the packet was successfully added to the queue, or successfully transferred over bluetooth?

Sorry if this was a lot of questions. I've gone back and bolded them to make it clearer what I'm trying to get help with hahah. Thank you so much for your help.

Kindest regards,

Ryan

Parents
  • Hello

    1 Mb/s throughput is a lot but should be possible. Looking at this page in the documentation it looks like you'll have to use 2M PHY, if you're not doing that already. I would also recommend referring to the throughput sample for pointers on how these things are set up if you haven't already looked at it.

    Then for your questions:

    Enabling "connection event length extension" (does this make a difference if my min connection interval = max connection interval?)

    I believe you might have some concepts confused here. The connection interval is how often a connection event occurs. The Connection event length is how much of the time between two such events are spent sending data, versus waiting for the next event. So the connection event length can be at most the same as the connection interval (which would mean you are sending data all the time).

    I need to increase my hvn_tx_queue_size, correct?
    When sd_ble_gatts_hvx returns NRF_SUCCESS, does that mean the packet was successfully added to the queue, or successfully transferred over bluetooth?

    According to the documentation:

    The number of Handle Value Notifications that can be queued is configured by ble_gatts_conn_cfg_t::hvn_tx_queue_size.

    NRF_SUCCESS: Successfully queued a notification or indication for transmission, and optionally updated the attribute value.

    There's nothing else I need to change, right?
    This means I should be able to just call it multiple times and it should handle everything for me, correct?

    I believe so, but have you tested if it works as expected?

    Have you checked what is received at the other end?

    Have you tested your current throughput?

    Best regards,

    Einar

  • Hi Einarh,


    Your guidance proved super invaluable!! Thank you for clarifying the difference between connection event length and the connection interval. I checked my throughput through using the att_mtu_throughput example (and using all the same settings that I had in my personal firmware) and it ended up being wayyyyyy less than I thought (only around 300kbps vs 1mbps).

    After finding more optimal bluetooth settings with the throughput example I was able to achieve the desired 1+ mbps throughput.

    In case anyone comes here with a similar problem, let me highlight the most important changes I made to my firmware.


    1) enable data length extension (so that multiple packets could be sent during a single connection)
    2) Increase my HVN queue size to 400 (so that the notification system would queue any notifications that couldn't be sent in time - this gives me a little leeway in case there are any flukes)
    3) Adjusting other ble stack settings to achieve a theoretical throughput of 1.2 Mbps (I figured these out by testing different parameters in the ble_app_mtu_throughput example)
    4) I began double buffering and adding a check in the CPU to retry sending the packet if ble_nus_data_send doesn't return 'success' when it's called the first time.

    Furthermore, in order to send multiple packets during a single connection, all you need to do is call ble_nus_data_send() multiple times. If you have an HVN queue large enough, all of your packets will get queued and sent without you having to worry.

    Again, Einarh, thanks for your guidance and clarification!

    Kindest regards,

    Ryan

Reply
  • Hi Einarh,


    Your guidance proved super invaluable!! Thank you for clarifying the difference between connection event length and the connection interval. I checked my throughput through using the att_mtu_throughput example (and using all the same settings that I had in my personal firmware) and it ended up being wayyyyyy less than I thought (only around 300kbps vs 1mbps).

    After finding more optimal bluetooth settings with the throughput example I was able to achieve the desired 1+ mbps throughput.

    In case anyone comes here with a similar problem, let me highlight the most important changes I made to my firmware.


    1) enable data length extension (so that multiple packets could be sent during a single connection)
    2) Increase my HVN queue size to 400 (so that the notification system would queue any notifications that couldn't be sent in time - this gives me a little leeway in case there are any flukes)
    3) Adjusting other ble stack settings to achieve a theoretical throughput of 1.2 Mbps (I figured these out by testing different parameters in the ble_app_mtu_throughput example)
    4) I began double buffering and adding a check in the CPU to retry sending the packet if ble_nus_data_send doesn't return 'success' when it's called the first time.

    Furthermore, in order to send multiple packets during a single connection, all you need to do is call ble_nus_data_send() multiple times. If you have an HVN queue large enough, all of your packets will get queued and sent without you having to worry.

    Again, Einarh, thanks for your guidance and clarification!

    Kindest regards,

    Ryan

Children
No Data
Related