nRF5340 function bt_nus_send() taking 40ms to execute, how to speed up?

I am looking to modify the sample code for peripheral UART and central UART, so that the central one takes data received from peripheral via BLE, and transmits said data out to some external processor via UART. External component must receive 10-byte packets with at most 1ms delay between end of one packet and start of another packet.

I am currently using 2 nRF5340-DKs to accomplish this. One of them is flashed with firmware from a direct copy of the central sample code (see nrf\samples\bluetooth\central_uart). The other has modified peripheral code (see nrf\samples\bluetooth\peripheral_uart), with the following changes:

  • main.c, defined array of hardcoded data - const uint8_t data[] (with size of roughly 16,000)
  • main.c, modified function ble_write_thread() to look like:

void ble_write_thread(void)
{
	/* Don't go any further until BLE is initialized */
	k_sem_take(&ble_init_ok, K_FOREVER);

	const uint16_t len2 = 10;
	uint16_t ndx = 0;
    int send_err;
    
	for (;;) {
		// send 1 packet
        dk_set_led(DK_LED3, 0);
		if ( (send_err = bt_nus_send(NULL, data + ndx, len2)) ) {
			LOG_WRN("Failed to send data over BLE connection");
            printk("BLE, FAILED TO SEND (ERROR=%d)\n", send_err);
		}
		// prepare for next time
		else {
            dk_set_led(DK_LED3, 1);
			if (ndx % (len2 * 100) == 0) {
				printk("BLE, DATA PROGRESS (LASTBYTE=0x%02x)\n", data[ndx + len2 - 1]);
			}
			ndx += len2;
			if (ndx >= sizeof(data)) {
				printk("\n\nBLE, ALL DATA SENT; RESTARTING\n\n");
				ndx = 0;
				break;
			}
		}
		// wait 1ms before sending next pkt
		k_sleep(K_MSEC(1));
	}
}

K_THREAD_DEFINE(ble_write_thread_id, STACKSIZE, ble_write_thread, NULL, NULL,
		NULL, PRIORITY, 0, 0);

I set up a logic analyzer to read the data on the central device's UART lines, and am getting the data with no loss. But there is a 45ms delay between the end of one packet and the start of another. I noticed a similar delay on the peripheral device (used the logic analyzer on the GPIO pin for LED3, and added dk_set_led() calls to use LED's off-time to measure it).

Any ideas, thoughts, suggestions on what I can do to reduce the delay (down to at most 1ms) and speed up the BLE communication? Thanks in advance.

------------------------------------------------------------------------------------------

Development Setup (for both peripheral and central devices):

  • Board: nRF5340-DK
  • Development Environment: VS Code
  • SDK: nRF Connect 2.5.0
  • OS: Windows 10
Parents Reply Children
  • We are using the nRF's in a medical application; as such, we need the device to be operating essentially in real-time. That's about as much info as I can provide at this time.

    I will need to investigate further on whether the multi-packet, 7.5ms latency setup is acceptable. Our 1ms delay restriction is only the external component/processor end's input, so we do have some flexibility with the wireless communication. Would you be able to point me to some examples that show how the connection interval can be changed please? I've checked a couple examples so far and haven't found anything yet. I think the interval change in the LLPM example also relates to HCI which seems specific to LLPM and not the typical BLE functions.

    I took a look at the LLPM example, but after reading up on the README, I found the SoftDevice Controller info stating that "Low Latency Packet mode is not supported on the nRF53 Series". So then is achieving low latency on these nRF53's impossible then? From my limited understanding, SoftDevice is a library; would it technically be possible to write "our own library" (custom lower-level code) to make it happen?

    --------

    EDIT1: Additional question -do you anticipate support for LLPM on the nRF53 in the future?

    EDIT2: More info on the application - this portion of BLE in the project is anticipated to be only for the nRF devices specifically. As we don't need to handle other devices, going for proprietary is definitely an option.

  • Hi Afok, 

    Regarding the question about changing the connection interval, I would suggest to go through our Academy course here: https://academy.nordicsemi.com/courses/bluetooth-low-energy-fundamentals/lessons/lesson-3-bluetooth-le-connections/topic/connection-process/

    At chapter 3 we cover the connection parameter update. 

    afok-esmart said:
    I took a look at the LLPM example, but after reading up on the README, I found the SoftDevice Controller info stating that "Low Latency Packet mode is not supported on the nRF53 Series". So then is achieving low latency on these nRF53's impossible then? From my limited understanding, SoftDevice is a library; would it technically be possible to write "our own library" (custom lower-level code) to make it happen?

    You are right. I forgot that the support for LLPM with NRF53 was removed. We have removed the support for it a few year back due to performance issue. You can take a look here:  RE: LLPM on two NRF5340

    We hope to get the feature into our next generation chip the nRF54. 

    You can take a look at our propriety protocol such as ESB for your application. It's more flexible with regard to the low latency communication. You can do ESB and BLE concurrently. 

  • Thanks for the connection parameter link and nRF53 LLPM status.

    I took a look at ESB and it seems promising for what we need, but we would need to examine the power consumption. My team originally chose nRF53 because of its low power when using BLE, and we would like to prioritize low consumption in our application as well. I know the datasheet lists it out for BLE, but is there a document/website highlighting power consumption metrics for using ESB?

  • Hi Afok, 

    There isn't a document that calculate the power consumption for ESB. You would need to look into the numbers in the product specification. The current consumption numbers are for radio activity in general, not just for BLE. 

    It can be difficult to calculate the power consumption by just looking at the number when the radio is transmitting (TX). You would need to calculate the ramp-up process the time it take to do transmission vs the time it's sleeping. My suggestion is to either to write some code and measure the current consumption directly. Or base on the online profiler made for BLE and do some calculation adjusting for your application. 

    Please be aware that when you do low latency with ESB, most likely the PRX (the one that receive) will have to stay in active RX all the time this will draw quite high current (for example 2.7mA for the radio). 
    On the TX side if you continuously transmitting at 1ms interval, you may also need to keep the HFCLK running all the time as the ramping up time for the HFCLK may take half a millisecond. 

    It's hard to achieve very low power consumption when doing very low latency. They don't come together. 

  • Thank you for the ESB info and suggestions! I will look into those some more to better evaluate ESB for our purposes.

    Given my team's timeline, we are also considering using the nRF54. Do you have any updates on when and/or how we could get our hands on nRF54 eval. boards (at least 2 of them)?

    -------

    EDIT1: I also went ahead with just trying the ESB demo code (nRF Connect 2.5.0, path nrf\samples\esb). This time I tried nRF52 DK's instead of nRF53's, since that's what I had on hand at the time. But I tried manipulating the TX code's k_sleep() call to lower the delay, and the lowest I could get it without significant "failed events" is around 10ms. I'll keep investigating the code to see how I can optimize it more, but what would you recommend I do to lower that more?

Related