BLE Transmission Blocking/Delay between nrf periphearl_uart and Raspberry Pi4

We are developing a BLE interface between Raspberry Pi4 and the nrf52833dk. The requirements are we need to send 40bytes every 4 msec.  The Raspberry Pi4 is the client and the nrf52833dk is the peripheral.  The issue we are having is something is blocking the transmission at 4msec.  We are using a modified nrf peripheral uart example.   The attached graph is an I/O pin toggling when we send data from the nrf52833dk.  You see the transmission every 4msec then a long delay.  Any ideas/suggestions on if this is a result of buffering on the Nordic side due to latency issues on the Raspberry Pi4. Also, included is the config file.  We tried just sending 20 bytes and have the same issue.

void main(void)
{
	int blink_status = 0;
	
        uint8_t i=0;

	configure_gpio();
    gpio_init();
	setup_bt();

	while (1) {
		dk_set_led(RUN_STATUS_LED, (++blink_status) % 2);
		//k_sleep(K_MSEC(RUN_LED_BLINK_INTERVAL));
		k_sleep(K_MSEC(4));
		nrf_gpio_pin_toggle(31);
                //if (SendData == true) {
                     /* Don't go any further until BLE is initialized */
                     //k_sem_take(&ble_init_ok, K_FOREVER);
                     //TODO verify bt is init and connected

                      for(i=0;i<40;i++){

                        send_data[i]=i+65;

                      }
                      nrf_gpio_pin_set(30);
                      if (bt_nus_send(NULL, send_data, 40)) {
					LOG_WRN("Failed to send data over BLE connection");
                      }
                      nrf_gpio_pin_clear(30);

					// LOG_INF("Data Sent");
					//k_free(send_data);
					// k_sleep(K_MSEC(100));
               //   SendData = false;
               // }
	}
}

 Copyright (c) 2018 Nordic Semiconductor
#
# SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
#

# Enable the UART driver
#CONFIG_UART_ASYNC_API=y
#CONFIG_NRFX_UARTE0=y
CONFIG_SERIAL=y

CONFIG_GPIO=y

# Make sure printk is printing to the UART console
CONFIG_CONSOLE=y
CONFIG_UART_CONSOLE=y

CONFIG_HEAP_MEM_POOL_SIZE=2048

CONFIG_BT=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DEVICE_NAME="NG-Proto"
CONFIG_BT_DEVICE_APPEARANCE=833
CONFIG_BT_MAX_CONN=1
CONFIG_BT_MAX_PAIRED=1


# Enable the NUS service
CONFIG_BT_NUS=y

# Enable bonding
CONFIG_BT_SETTINGS=y
CONFIG_FLASH=y
CONFIG_FLASH_PAGE_LAYOUT=y
CONFIG_FLASH_MAP=y
CONFIG_NVS=y
CONFIG_SETTINGS=y

# Enable DK LED and Buttons library
CONFIG_DK_LIBRARY=y

# This example requires more workqueue stack
CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048

# Config logger
CONFIG_LOG=y
CONFIG_USE_SEGGER_RTT=y
CONFIG_LOG_BACKEND_RTT=y
CONFIG_LOG_BACKEND_UART=n

CONFIG_ASSERT=y


  • Hi,

    bt_nus_send() is in principle non-blocking, but will block if the work queue is full (see this thread). And that will likely be the case here.

    What is the connection parameters used in this Bluetooth connection? And packet length etc? The minimum connection interval that can be used is 7.5 ms, so you will have to buffer up or send multiple packets per connection event, which would only be possible when several are queued (as one packet will need to have the more data bit set in the header in order to send another packet in the same connection event).

    So, I would first of all make sure to select a sensible connection interval and a connection events that allow multiple packets per event (scaled to the amount of data you need and the connection interval you use). Secondly, queue up data with calls to bt_nus_send() so that the data is ready, instead of what you have not which is in practice a minimum delay of 4 ms.-

  • Einar, Thank you for your response! I included the config file with the parameters in the initial post.  Also, the number of byte is 40. I have tried the min conn interval at 7.5 msec (6) and still have issues. I'll check the work queue thread.

    Scott

  • Hi Scott,

    I don't see that much useful from the config file to be hones. To know what is used in the link it would be good with a sniffer trace (the parameters that are actually used are decided by the central, based on what is supported by both peers and potential requests from the peripheral. It would also be very good to know if the 40 bytes are sent in a packet with DLE or if it is fragmented in two, tough that is probably not relevant right now as you see the same with 20 ms.

    But again, you will see this being bursty as you try to send more than 4 ms, and as you also have a delay of 4 ms like this you will not queue up packets as fast as you could in other cases, preventing efficient "catch up" by sending potentially many packets in one event if needed. So it would make sense to revise you approach.

Related