Increase BLE throughput GATT HR service

Hello everyone,

I am developing an application, with the nRF52840 chip (actually BMD-380) , that streams via BLE data read by an SPI sensor (ADS1293) to an Ubuntu machine @ 250 Hz.

For testing purposes, I am sending only one byte with the "bt_hrs_notify" function when the data ready callback is triggered (250Hz verified with a logic analyzer) :

#include <zephyr.h>
#include <device.h>

#include "ads1293.h"
#include "ble_utils.h"


K_SEM_DEFINE(ADS_sem, 0, 1);	


void data_ready_cb(const struct device *dev, struct gpio_callback *cb,
		    uint32_t pins)
{
  k_sem_give(&ADS_sem);
}

void main(void)
{
	init_ble();

    init_ads1293(); // Init SPI drivers and GPIO ISR that triggers 'data_ready_cb'
    
	int8_t dummy_byte = 10;

	while (1)
	{
		k_sem_take(&threadADS_sem, K_FOREVER);
		bt_hrs_notify(dummy_byte);
	}
}

the other relevant .c file for BLE (taken from the zephyr peripheral HR example):

#include "ble_utils.h"

static const struct bt_data ad[] = {
	BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
	BT_DATA_BYTES(BT_DATA_UUID16_ALL,
		      BT_UUID_16_ENCODE(BT_UUID_HRS_VAL),
		      BT_UUID_16_ENCODE(BT_UUID_BAS_VAL),
		      BT_UUID_16_ENCODE(BT_UUID_DIS_VAL))
};

static void connected(struct bt_conn *conn, uint8_t err)
{
	if (err) {
		printk("Connection failed (err 0x%02x)\n", err);
	} else {
		printk("Connected\n");
	}
}

static void disconnected(struct bt_conn *conn, uint8_t reason)
{
	printk("Disconnected (reason 0x%02x)\n", reason);
}

BT_CONN_CB_DEFINE(conn_callbacks) = {
	.connected = connected,
	.disconnected = disconnected,
};

static void bt_ready(void)
{
	int err;

	printk("Bluetooth initialized\n");

	err = bt_le_adv_start(BT_LE_ADV_CONN_NAME, ad, ARRAY_SIZE(ad), NULL, 0);
	if (err) {
		printk("Advertising failed to start (err %d)\n", err);
		return;
	}

	printk("Advertising successfully started\n");
}

static void auth_cancel(struct bt_conn *conn)
{
	char addr[BT_ADDR_LE_STR_LEN];

	bt_addr_le_to_str(bt_conn_get_dst(conn), addr, sizeof(addr));

	printk("Pairing cancelled: %s\n", addr);
}

static struct bt_conn_auth_cb auth_cb_display = {
	.cancel = auth_cancel,
};


void init_ble(void)
{
	int err;

	err = bt_enable(NULL);
	if (err) {
		printk("Bluetooth init failed (err %d)\n", err);
		return;
	}

	bt_ready();

	bt_conn_auth_cb_register(&auth_cb_display);
}

prj.conf:

CONFIG_STDOUT_CONSOLE=n
CONFIG_SERIAL=n
CONFIG_SPI=y
CONFIG_SENSOR=y


CONFIG_BT=y
CONFIG_BT_DEBUG_LOG=y
CONFIG_BT_SMP=y
CONFIG_BT_PERIPHERAL=y
CONFIG_BT_DIS=y
CONFIG_BT_DIS_PNP=n
CONFIG_BT_BAS=y
CONFIG_BT_HRS=y
CONFIG_BT_DEVICE_NAME="Test BLE"
CONFIG_BT_DEVICE_APPEARANCE=833

with this basic configurations I obtain a throughput of just about 60Hz.

If I get rid of the timing given by the ISR, and so sending continuously data in the infinite while loop, this can reach up to 1500Hz, but I obviously need the timing given by the sensor.

Is there something I am missing? Do you have any idea on how to improve the communication?

Thank you very much for your time!

Related