Achieving Shorter BLE Connection Intervals for Channel Sounding on nRF54L15DK

Dear Nordic Specialist,

I am currently testing the minimum connection interval at which BLE Channel Sounding can operate reliably. Specifically, I would like to achieve a connection interval of 50ms or less on my nRF54L15DK. According to Nordic’s official documentation, connection intervals of 50ms or shorter are mentioned as tested and supported.

LE Channel Sounding

However, when using the Nordic Connect SDK Sample: Bluetooth: Channel Sounding Initiator with Ranging Requestor, I have found it very difficult to achieve such a fast connection interval. In practice, the connection interval cannot be set lower than 250ms; otherwise, I encounter "overwritten" callbacks.

From my tests, the minimum stable interval without overwritten errors is 300ms (interval = 6). This is sufficient for data storage to flash in the sample application.

At this point, I would like to know if there is any set of feasible configuration parameters that would allow for a 50ms, or at least faster than 250ms, connection interval.

Additionally, I have noticed that in the latest commits on GitHub, the connection interval also appears to be limited to no less than 200–250ms (interval = 4 or 5).

bluetooth: samples: increase procedure interval in RAS RREQ sample · nrfconnect/sdk-nrf@2f8cf5c

I have also tried reducing the number of enabled channels and decreasing the number of mode-0 steps, which only slightly reduces the length of each subevent. With the channel map repetition already set to 1, these changes have minimal effect—the subevent length still remains around 20ms.

Would it be necessary to disable certain features in order to achieve shorter intervals? Reduce the number of channels or num of mode-0 steps only reduce 100us per step  

Thank you very much for your attention and support. I look forward to your guidance.

Best regards,
Cheng

Parents
  • Hi Cheng,

    The sample in the SDK use a connection interval of 50 ms out of the box (40 * 1.25 ms), but based on the question I wonder if you are referring to the channel sounding parameters? Can you share your code/config and clarify what you are after?

    PS: You can log the connection iterval upon connection by adding this in connected_cb() to see the connection interval being used:

    	struct bt_conn_info info = {0};
    	err = bt_conn_get_info(conn, &info);
    	if (err) {
    		LOG_ERR("Failed to get connection info %d", err);
    		return;
    	}
    
    	LOG_INF("Conn. interval is %u units", info.le.interval);
    

    (The samples do not do connection parameter update, but if that was used you could add a le_param_updated and check there as well).

    Additionally, I have noticed that in the latest commits on GitHub, the connection interval also appears to be limited to no less than 200–250ms (interval = 4 or 5).

    This is about the channel sounding procedure interval, and not the connection interval (is is also done for nRF54H20 which has additional latencies due inter core communication). You can see 3.4.2.2 Timing in the BluetoothRegistered Channel Sounding Technical Overview for the link between connection interval, procedure interval and event intervals. Note that the subevent length should be shorter than the connection interval.

    Br,

    Einar

  • Hi Einar,

    Thank you very much for your response. After checking the link you provided, I realized that I did indeed mix up the connection interval and the event interval for channel sounding. You are correct, and what I actually wanted to inquire about are the configuration parameters for Channel Sounding (CS).

    With the code snippet you shared, I can confirm that the current connection interval is indeed 50ms (40 * 1.25ms).


    [00:00:08.026,829] [0m<inf> app_main: sem_connected count after conncb: 0[0m
    [00:00:08.030,611] [0m<inf> app_main: Now connected, scanning stopped[0m
    [00:00:08.034,224] [0m<inf> app_main: Conn. interval is 40 units[0m

    [00:00:09.073,686] [0m<inf> app_main: Security changed: D1:15:C6:44:A1:9C (random) level 2[0m

    I now understand that each distance estimation is based on the data from a single subevent. If I want to increase the frequency of distance estimations, which parameters should I start adjusting? My understanding is that if I want to obtain one ranging result every 50ms, the CS subevent should be executed every 50ms. Similarly, if I want a new distance estimation every 100ms, the CS subevent should occur every 100ms.

    Therefore, I have checked the bt_le_cs_set_procedure_parameters_param. My current configuration executes one procedure every 300ms because my procedure interval is set to 6 ACL connection intervals (50ms * 6 = 300ms). However, since there is no parameter to specify the number of events or subevents per procedure, I can only indirectly increase the subevent execution frequency by shortening the procedure interval.

    static const struct bt_le_cs_set_procedure_parameters_param procedure_params = {
        .config_id = CS_CONFIG_ID,
        .max_procedure_len = 500,
        .min_procedure_interval = 1,
        .max_procedure_interval = 6,
        .max_procedure_count = 0,
        .min_subevent_len = 10000,
        .max_subevent_len = 50000, // unit is us
        .tone_antenna_config_selection = BT_LE_CS_TONE_ANTENNA_CONFIGURATION_A1_B1,
        .phy = BT_LE_CS_PROCEDURE_PHY_2M,
        .tx_power_delta = 0x80,
        .preferred_peer_antenna = BT_LE_CS_PROCEDURE_PREFERRED_PEER_ANTENNA_1,
        .snr_control_initiator = BT_LE_CS_SNR_CONTROL_NOT_USED,
        .snr_control_reflector = BT_LE_CS_SNR_CONTROL_NOT_USED,
    };

    I have also minimized the subevent data size. I have disabled RTT and enabled only PBR (mode-2), and the channel map repeats only once. Currently, the length of a subevent is 21334 us, which is indeed less than one ACL connection interval.

    static struct bt_le_cs_create_config_params config_params = {
        .id = CS_CONFIG_ID,
        .main_mode_type = BT_CONN_LE_CS_MAIN_MODE_2,
        .sub_mode_type = BT_CONN_LE_CS_SUB_MODE_UNUSED,
        .min_main_mode_steps = 1,
        .max_main_mode_steps = 1,
        .main_mode_repetition = 0,
        .mode_0_steps = NUM_MODE_0_STEPS,
        .role = BT_CONN_LE_CS_ROLE_INITIATOR,
        .rtt_type = BT_CONN_LE_CS_RTT_TYPE_AA_ONLY,
        .cs_sync_phy = BT_CONN_LE_CS_SYNC_1M_PHY,
        .channel_map_repetition = 1,
        .channel_selection_type = BT_CONN_LE_CS_CHSEL_TYPE_3B,
        .ch3c_shape = BT_CONN_LE_CS_CH3C_SHAPE_HAT,
        .ch3c_jump = 2,
    };

    Perhaps increasing the number of subevents within each procedure could help? However, I could not find a way to configure this. Only bt_le_cs_test_param seems to have a max_num_subevents parameter, which might be related, but I am not sure. From the output below, I noticed that the event interval is set to 2, which seems to be auto-generated. Also, if each procedure contains only one subevent, this parameter does not seem to have any practical effect.

    [00:00:17.374,443] <inf> app_main: CS procedures enabled:
     - config ID: 0
     - antenna configuration index: 0
     - TX power: 8 dbm
     - subevent length: 21334 us
     - subevents per event: 1
     - subevent interval: 0
     - event interval: 2
     - procedure interval: 6
     - procedure count: 0
     - maximum procedure length: 500
    

    Finally, based on my understanding, are there any other factors that could affect the update rate for CS distance estimation (for example, the latency you mentioned)? In the current sample code, each procedure contains only one event, and each event contains only one subevent. So, the approach of shortening the procedure interval to increase the update rate for distance estimation should be feasible. However, when I set the interval to less than 6, it becomes difficult to obtain valid data, and I often encounter issues such as "overwritten" or "Error when getting ranging data with ranging counter".

    I am a bit confused—since the subevent lasts only 20ms, even if the procedure interval is set to 2 (100ms), there should still be 100-20=80ms available for processing the acquired data, which seems like plenty of time.

    Thank you again for your guidance and support.

    Best,
    Cheng


  • Hi Cheng,

    I have checked internally, and it seems it is not realistically possible to get faster channel sonding results (shorter interval between estimates) than what is done in the example (though note that in nRF Connect SDK 3.1 that was just released, Real-time ranging data" makes the GATT transfer part faster. It is bottlenecked by several things:

    • Scheduling parameters like connection interval + procedure interval will affect how frequently CS data is produced by the devices. See 4.5.18.1. Channel Sounding procedures and subevents.
    • Data needs to be sent over GATT, which takes some connection events. CS data is often large so this can take considerable airtime. Shorter CI doesn't necessarily help with this as the ACL is allowed to extend its event to exchange more data. See Connection timing with Connection Event Length Extension in the SoftDevice Controller specification.
    • The signal processing in the cs_de.c module also takes some CPU time.

    As connection interval was discussed initially, note that if you want to reduce the connection interval, that is possible. The subevent length needs to be reduced, which should split the CS procedures up across multiple ACL events. You do not get more or faster measurements this way but you get a shorter connection interval (if that's needed for other reasons)

    Br,

    Einar

  • Hi Einar,

    Thank you very much for the information you provided—it completely answered my question. I have realized that I overlooked the fact that the data measured by the reflector needs time to be transmitted back to the initiator, and this portion of time is not included within the CS subevent itself. It seems that, at present, the update rate for distance estimation is constrained by various factors.

    If this is the case, it appears that reducing the number of enabled channels could help decrease both the subevent duration and the amount of data that needs to be transmitted afterwards. I have tried this before, but I noticed that the SDK requires at least 15 channels to be enabled. If possible, I would like to know whether this limitation is mandated by the Bluetooth 6.0 specification, or if it is a restriction imposed by the SDK to prevent misconfiguration. This is an additional question, and I would appreciate your clarification if you have the opportunity.

    Thank you again for your kind assistance.

    Best,
    Cheng

  • Hi Cheng,

    The limitation of 15 channels come from the Bluetooth specification. You can for instance see this statement in BLUETOOTH CORE SPECIFICATION Version 6.0 | Vol 4, Part E
    Page 2830:

    If the Channel_Classification parameter enables channels that are reserved for future
    use or enables fewer than 15 channels, then the Controller shall return the error code
    Invalid HCI Command Parameters (0x12).

    Br,

    Einar

  • Thanks again for your help! I truly appreciate it!

Reply Children
No Data
Related