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
  • Hi Afok, 


    You can crank it up even more by using use_fast_ramp_up in the ESB configuration.

    This will select the fast ramping up mode of the radio, allowing it to have shorter latency. The only drawback is that it will make it not compatible with old device running normal ESB. So if you have control over both ends of the communication, you can use this mode. 

  • I did experiment with "use_fast_ramp_up" as well (most likely would use it for my project if I got it working, as I do indeed have control over both ends of comms). It did lower the time between packets to 0.25-0.3ms, but only if my PTX "tx_payload" had length 6 bytes or less.

    It would stop working if the payload had more bytes (none of the LEDs on PRX would ever toggle). I still need to check if PTX is even sending them to begin with, and also see if PRX has anything else that makes it unable to serve the radio fast enough. Do you have any thoughts about what else I can try looking into?

  • Hi Afok, 
    I haven't tested myself but have you made sure you use the same configuration on both sides PTX and PRX. 
    Also you may want to send packet with noack. You would need to set selective_auto_ack = true to noack to take effect.

    There is a TX complete call back on the PTX that you can add to check if the packet is sent.

  • (OP replying here) It's been a while and the forum discussion has sort of steered towards ESB rather than BLE, so I thought I would suggest an answer to help answer my original question.

    As Hung Bui reported, delays that are:

    • > 7.5ms can be achieved by lowering connection interval (but I never tried it personally)
    • > 2-3ms can be achieved by using BLE LLPM
      • The '2-3ms' is a rough range; unfortunately I don't have the exact numbers on-hand
    • > (sub) 1ms can be achieved by using ESB (not BLE)
Related