Hello,
I'm working on an application which advertises a proprietary command-response service and I would like to optimize the power consumption. According to the online power profiler I should get as low as 36uA, but currently I am only able to achieve about 260uA.
Is 260uA already the limit? Is there a way to set the application-core to a deeper sleep and wake up at bluetooth-events? Do I need to disable something additional in the device tree?
I was not able to find a sample achieving lower power consumption, is there any?
I'm using Nordic SDK 2.4 with zephyr on an nRF5340dk with the following sources.
# prj.conf CONFIG_NCS_SAMPLES_DEFAULTS=y CONFIG_BT=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_DEVICE_NAME="NPP" CONFIG_PM=y
// nrf5340dk_nrf5340_cpuapp_ns.overlay
&uart0 {
status = "disabled";
};
&i2c1 {
status = "disabled";
};
&spi4 {
status = "disabled";
};
&adc {
status = "disabled";
};
&pwm0 {
status = "disabled";
};
&nfct {
status = "disabled";
};
&usbd {
status = "disabled";
};
&usbreg {
status = "disabled";
};
// main.c
#include <zephyr/kernel.h>
#include <zephyr/bluetooth/bluetooth.h>
#include <zephyr/bluetooth/hci.h>
#include <zephyr/bluetooth/conn.h>
#include <zephyr/bluetooth/uuid.h>
#include <zephyr/bluetooth/gatt.h>
#include <stdint.h>
#include <errno.h>
static void bt_connected(struct bt_conn *conn, uint8_t err);
static void bt_disconnected(struct bt_conn *conn, uint8_t err);
static void response_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value);
static ssize_t new_data(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset, uint8_t flags);
const static char notify_msg[] = "notification";
const static char response_msg[] = "response";
static int notify_enabled = 0;
static int connected = 0;
const static struct bt_gatt_attr *response_attr = NULL;
static struct bt_conn_cb bt_conn_cb = {
.connected = bt_connected,
.disconnected = bt_disconnected,
};
#define MY_BT_UUID_VAL BT_UUID_128_ENCODE(0xDAE90050, 0x384C, 0x037A, 0x10B8, 0x21CD1C007486)
#define MY_BT_UUID_COMMAND_VAL BT_UUID_128_ENCODE(0xDAE90051, 0x384C, 0x037A, 0x10B8, 0x21CD1C007486)
#define MY_BT_UUID_RESPONSE_VAL BT_UUID_128_ENCODE(0xDAE90052, 0x384C, 0x037A, 0x10B8, 0x21CD1C007486)
#define MY_BT_UUID BT_UUID_DECLARE_128(MY_BT_UUID_VAL)
#define MY_BT_UUID_COMMAND BT_UUID_DECLARE_128(MY_BT_UUID_COMMAND_VAL)
#define MY_BT_UUID_RESPONSE BT_UUID_DECLARE_128(MY_BT_UUID_RESPONSE_VAL)
BT_GATT_SERVICE_DEFINE(svc,
BT_GATT_PRIMARY_SERVICE(MY_BT_UUID),
BT_GATT_CHARACTERISTIC(MY_BT_UUID_COMMAND, BT_GATT_CHRC_WRITE,
BT_GATT_PERM_WRITE, NULL, new_data, NULL),
BT_GATT_CHARACTERISTIC(MY_BT_UUID_RESPONSE, BT_GATT_CHRC_NOTIFY,
BT_GATT_PERM_NONE, NULL, NULL, NULL),
BT_GATT_CCC(response_ccc_cfg_changed, BT_GATT_PERM_READ | BT_GATT_PERM_WRITE),
);
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, (BT_LE_AD_GENERAL | BT_LE_AD_NO_BREDR)),
BT_DATA(BT_DATA_NAME_COMPLETE, CONFIG_BT_DEVICE_NAME, sizeof(CONFIG_BT_DEVICE_NAME)),
};
static const struct bt_data sd[] = {
BT_DATA_BYTES(BT_DATA_UUID128_ALL, MY_BT_UUID_VAL),
};
#define ADV_PARAM BT_LE_ADV_PARAM(BT_LE_ADV_OPT_CONNECTABLE, BT_GAP_ADV_SLOW_INT_MIN, BT_GAP_ADV_SLOW_INT_MAX, NULL)
int main(void)
{
response_attr = bt_gatt_find_by_uuid(svc.attrs, svc.attr_count, MY_BT_UUID_RESPONSE);
bt_enable(NULL);
bt_conn_cb_register(&bt_conn_cb);
bt_le_adv_start((ADV_PARAM), ad, (ARRAY_SIZE(ad)), sd, (ARRAY_SIZE(sd)));
return 0;
}
static void bt_connected(struct bt_conn *conn, uint8_t err) {
connected++;
return;
}
static void bt_disconnected(struct bt_conn *conn, uint8_t err) {
connected--;
return;
}
static void response_ccc_cfg_changed(const struct bt_gatt_attr *attr, uint16_t value) {
if (value == BT_GATT_CCC_NOTIFY) {
bt_gatt_notify(NULL, response_attr, notify_msg, sizeof(notify_msg));
notify_enabled++;
} else {
notify_enabled--;
}
return;
}
static ssize_t new_data(struct bt_conn *conn, const struct bt_gatt_attr *attr,
const void *buf, uint16_t len, uint16_t offset, uint8_t flags) {
if (notify_enabled) {
bt_gatt_notify(NULL, response_attr, response_msg, sizeof(response_msg));
}
return len;
}
The behavior of the application works fine.
Thank you in advance!
Best regards,
Sandro
