I am using Zephyr to create a program that integrates BLE Mesh and NUS. My goal is to use a sensor_client to read data from a sensor_server, and then send the data, via peripheral_uart, to an external central_uart device after reading it. I referred to the official examples, including sensor_client, sensor_server, peripheral_uart, and ble_peripheral_lbs_coex, and developed the final program using NCS 2.9 on an nRF52833. My code shows below
main.c
/* * Copyright (c) 2020 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ /** @file * @brief Nordic mesh sensor observer sample */ #include <zephyr/bluetooth/bluetooth.h> #include <bluetooth/mesh/models.h> #include <bluetooth/mesh/dk_prov.h> #include <dk_buttons_and_leds.h> #include "model_handler.h" #include "nus_handler.h"//头文件 static void bt_ready(int err) { if (err) { printk("Bluetooth init failed (err %d)\n", err); return; } printk("Bluetooth initialized\n"); err = dk_leds_init(); if (err) { printk("Initializing LEDs failed (err %d)\n", err); return; } err = dk_buttons_init(NULL); if (err) { printk("Initializing buttons failed (err %d)\n", err); return; } err = bt_mesh_init(bt_mesh_dk_prov_init(), model_handler_init()); if (err) { printk("Initializing mesh failed (err %d)\n", err); return; } if (IS_ENABLED(CONFIG_SETTINGS)) { settings_load(); } /* This will be a no-op if settings_load() loaded provisioning info */ bt_mesh_prov_enable(BT_MESH_PROV_ADV | BT_MESH_PROV_GATT); printk("Mesh initialized\n"); /* 初始化 NUS handler */ err = nus_handler_init(); if (err) { printk("NUS handler initialization failed (err %d)\n", err); return; } printk("NUS handler initialized\n"); } int main(void) { int err; printk("Initializing...\n"); err = bt_enable(bt_ready); if (err) { printk("Bluetooth init failed (err %d)\n", err); } return 0; }
model_handler.c
/* * Copyright (c) 2020 Nordic Semiconductor ASA * * SPDX-License-Identifier: LicenseRef-Nordic-5-Clause */ #include <zephyr/bluetooth/bluetooth.h> #include <bluetooth/mesh/models.h> #include <dk_buttons_and_leds.h> #include "model_handler.h" #define GET_DATA_INTERVAL 10000 #define GET_DATA_INTERVAL_QUICK 3000 #define MOTION_TIMEOUT K_SECONDS(60) static bool is_occupied; static struct k_work_delayable motion_timeout_work; static void motion_timeout(struct k_work *work) { is_occupied = false; printk("Area is now vacant.\n"); } // static void sensor_cli_data_cb(struct bt_mesh_sensor_cli *cli, // struct bt_mesh_msg_ctx *ctx, // const struct bt_mesh_sensor_type *sensor, // const struct bt_mesh_sensor_value *value) // { // enum bt_mesh_sensor_value_status status; // if (sensor->id == bt_mesh_sensor_present_dev_op_temp.id) { // printk("Chip temperature: %s\n", bt_mesh_sensor_ch_str(value)); // } else if (sensor->id == bt_mesh_sensor_presence_detected.id) { // int64_t presence_detected = 0; // status = bt_mesh_sensor_value_to_micro(value, &presence_detected); // if (!bt_mesh_sensor_value_status_is_numeric(status)) { // printk("Warning: unexpected behaviour during conversion of presence " // "detected value (%d)\n", // status); // return; // } // if (!!presence_detected) { // printk("Presence detected\n"); // } else { // printk("No presence detected\n"); // } // } else if (sensor->id == // bt_mesh_sensor_time_since_presence_detected.id) { // int64_t time_since_presence_detected = 0; // status = bt_mesh_sensor_value_to_micro(value, &time_since_presence_detected); // if (status == BT_MESH_SENSOR_VALUE_UNKNOWN) { // printk("Unknown last presence detected\n"); // } else if (!time_since_presence_detected) { // printk("Presence detected, or under 1 second since presence detected\n"); // } else { // printk("%s second(s) since last presence detected\n", // bt_mesh_sensor_ch_str(value)); // } // } else if (sensor->id == bt_mesh_sensor_present_amb_light_level.id) { // printk("Ambient light level: %s\n", bt_mesh_sensor_ch_str(value)); // } else if (sensor->id == bt_mesh_sensor_motion_sensed.id) { // int64_t motion_sensed = 0; // status = bt_mesh_sensor_value_to_micro(value, &motion_sensed); // if (!bt_mesh_sensor_value_status_is_numeric(status)) { // printk("Warning: unexpected behaviour during conversion of motion sensed " // "value (%d)\n", // status); // return; // } // if (!!motion_sensed) { // is_occupied = true; // printk("Motion detected (%s %%). Area is occupied.\n", // bt_mesh_sensor_ch_str(value)); // k_work_cancel_delayable(&motion_timeout_work); // } else { // if (is_occupied) { // printk("No current motion detected. Area is still occupied.\n"); // k_work_reschedule(&motion_timeout_work, MOTION_TIMEOUT); // } else { // printk("No motion detected. Area is vacant.\n"); // } // } // } else if (sensor->id == bt_mesh_sensor_time_since_motion_sensed.id) { // int64_t time_since_motion_sensed = 0; // status = bt_mesh_sensor_value_to_micro(value, &time_since_motion_sensed); // if (status == BT_MESH_SENSOR_VALUE_UNKNOWN) { // printk("Unknown last motion sensed\n"); // } else if (!time_since_motion_sensed) { // printk("Motion sensed, or under 1 second since motion sensed\n"); // } else { // printk("%s second(s) since last motion sensed\n", // bt_mesh_sensor_ch_str(value)); // } // } else if (sensor->id == bt_mesh_sensor_people_count.id) { // printk("People count is %s\n", bt_mesh_sensor_ch_str(value)); // } // } static void sensor_cli_data_cb(struct bt_mesh_sensor_cli *cli, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_sensor_type *sensor, const struct bt_mesh_sensor_value *value) { if (sensor->id == bt_mesh_sensor_people_count.id) { // 打印 People Count 数据 printk("People count is %s\n", bt_mesh_sensor_ch_str(value)); } } static void sensor_cli_series_entry_cb( struct bt_mesh_sensor_cli *cli, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_sensor_type *sensor, uint8_t index, uint8_t count, const struct bt_mesh_sensor_series_entry *entry) { printk("Relative runtime in %s", bt_mesh_sensor_ch_str(&entry->value[1])); printk(" to %s degrees: ", bt_mesh_sensor_ch_str(&entry->value[2])); printk("%s percent\n", bt_mesh_sensor_ch_str(&entry->value[0])); } static void sensor_cli_setting_status_cb(struct bt_mesh_sensor_cli *cli, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_sensor_type *sensor, const struct bt_mesh_sensor_setting_status *setting) { printk("Sensor ID: 0x%04x, Setting ID: 0x%04x\n", sensor->id, setting->type->id); for (int chan = 0; chan < setting->type->channel_count; chan++) { printk("\tChannel %d value: %s\n", chan, bt_mesh_sensor_ch_str(&(setting->value[chan]))); } } static void sensor_cli_desc_cb(struct bt_mesh_sensor_cli *cli, struct bt_mesh_msg_ctx *ctx, const struct bt_mesh_sensor_info *sensor) { printk("Descriptor of sensor with ID 0x%04x:\n", sensor->id); printk("\ttolerance: { positive: %d negative: %d }\n", sensor->descriptor.tolerance.positive, sensor->descriptor.tolerance.negative); printk("\tsampling type: %d\n", sensor->descriptor.sampling_type); } static const struct bt_mesh_sensor_cli_handlers bt_mesh_sensor_cli_handlers = { .data = sensor_cli_data_cb, .series_entry = sensor_cli_series_entry_cb, .setting_status = sensor_cli_setting_status_cb, .sensor = sensor_cli_desc_cb, }; static struct bt_mesh_sensor_cli sensor_cli = BT_MESH_SENSOR_CLI_INIT(&bt_mesh_sensor_cli_handlers); static struct k_work_delayable get_data_work; // static void get_data(struct k_work *work) // { // if (!bt_mesh_is_provisioned()) { // k_work_schedule(&get_data_work, K_MSEC(GET_DATA_INTERVAL)); // return; // } // static uint32_t sensor_idx; // int err; // /* Only one message can be published at a time. Swap sensor after each timeout. */ // switch (sensor_idx++) { // case (0): { // err = bt_mesh_sensor_cli_get( // &sensor_cli, NULL, &bt_mesh_sensor_present_dev_op_temp, // NULL); // if (err) { // printk("Error getting chip temperature (%d)\n", err); // } // break; // } // case (1): { // err = bt_mesh_sensor_cli_series_entries_get( // &sensor_cli, NULL, // &bt_mesh_sensor_rel_runtime_in_a_dev_op_temp_range, NULL, NULL, // NULL, NULL); // if (err) { // printk("Error getting relative chip temperature data (%d)\n", err); // } // break; // } // case (2): { // err = bt_mesh_sensor_cli_get( // &sensor_cli, NULL, &bt_mesh_sensor_time_since_presence_detected, // NULL); // if (err) { // printk("Error getting time since presence detected (%d)\n", err); // } // break; // } // case (3): { // err = bt_mesh_sensor_cli_get( // &sensor_cli, NULL, &bt_mesh_sensor_present_amb_light_level, NULL); // if (err) { // printk("Error getting ambient light level (%d)\n", err); // } // break; // } // case (4): { // err = bt_mesh_sensor_cli_get(&sensor_cli, NULL, // &bt_mesh_sensor_time_since_motion_sensed, NULL); // if (err) { // printk("Error getting time since motion detected (%d)\n", err); // } // break; // } // case (5): { // err = bt_mesh_sensor_cli_get(&sensor_cli, NULL, &bt_mesh_sensor_people_count, NULL); // if (err) { // printk("Error getting people count (%d)\n", err); // } // break; // } // } // if (sensor_idx % 6) { // k_work_schedule(&get_data_work, K_MSEC(GET_DATA_INTERVAL_QUICK)); // } else { // k_work_schedule(&get_data_work, K_MSEC(GET_DATA_INTERVAL)); // sensor_idx = 0; // } // } static void get_data(struct k_work *work) { if (!bt_mesh_is_provisioned()) { k_work_schedule(&get_data_work, K_MSEC(GET_DATA_INTERVAL)); return; } int err; /* 只获取 people count 数据 */ err = bt_mesh_sensor_cli_get(&sensor_cli, NULL, &bt_mesh_sensor_people_count, NULL); if (err) { printk("Error getting people count (%d)\n", err); } else { printk("Requesting people count data...\n"); } /* 定时任务,保持轮询获取 people count */ k_work_schedule(&get_data_work, K_MSEC(GET_DATA_INTERVAL)); } static const int temp_ranges[][2] = { { 0, 100 }, { 10, 20 }, { 22, 30 }, { 40, 50 }, }; static const int presence_motion_threshold[] = { 0, 25, 50, 75, 100 }; static int setting_set_int(const struct bt_mesh_sensor_type *sensor_type, const struct bt_mesh_sensor_type *setting_type, const int *values) { struct bt_mesh_sensor_value sensor_vals[CONFIG_BT_MESH_SENSOR_CHANNELS_MAX]; int err; for (int i = 0; i < setting_type->channel_count; i++) { err = bt_mesh_sensor_value_from_micro(setting_type->channels[i].format, values[i] * 1000000LL, &sensor_vals[i]); if (err) { return err; } } return bt_mesh_sensor_cli_setting_set(&sensor_cli, NULL, sensor_type, setting_type, sensor_vals, NULL); } static void button_handler_cb(uint32_t pressed, uint32_t changed) { if (!bt_mesh_is_provisioned()) { return; } static uint32_t temp_idx; static uint32_t motion_threshold_idx; int err; if (pressed & changed & BIT(0)) { err = bt_mesh_sensor_cli_setting_get(&sensor_cli, NULL, &bt_mesh_sensor_present_dev_op_temp, &bt_mesh_sensor_dev_op_temp_range_spec, NULL); if (err) { printk("Error getting range setting (%d)\n", err); } } if (pressed & changed & BIT(1)) { err = setting_set_int(&bt_mesh_sensor_present_dev_op_temp, &bt_mesh_sensor_dev_op_temp_range_spec, temp_ranges[temp_idx++]); if (err) { printk("Error setting range setting (%d)\n", err); } temp_idx = temp_idx % ARRAY_SIZE(temp_ranges); } if (pressed & changed & BIT(2)) { err = bt_mesh_sensor_cli_desc_get(&sensor_cli, NULL, &bt_mesh_sensor_present_dev_op_temp, NULL); if (err) { printk("Error getting sensor descriptor (%d)\n", err); } } if (pressed & changed & BIT(3)) { err = setting_set_int(&bt_mesh_sensor_presence_detected, &bt_mesh_sensor_motion_threshold, &presence_motion_threshold[motion_threshold_idx++]); if (err) { printk("Error setting motion threshold setting (%d)\n", err); } motion_threshold_idx = motion_threshold_idx % ARRAY_SIZE(presence_motion_threshold); } } static struct button_handler button_handler = { .cb = button_handler_cb, }; /* Set up a repeating delayed work to blink the DK's LEDs when attention is * requested. */ static struct k_work_delayable attention_blink_work; static bool attention; static void attention_blink(struct k_work *work) { static int idx; const uint8_t pattern[] = { BIT(0) | BIT(1), BIT(1) | BIT(2), BIT(2) | BIT(3), BIT(3) | BIT(0), }; if (attention) { dk_set_leds(pattern[idx++ % ARRAY_SIZE(pattern)]); k_work_reschedule(&attention_blink_work, K_MSEC(30)); } else { dk_set_leds(DK_NO_LEDS_MSK); } } static void attention_on(const struct bt_mesh_model *mod) { attention = true; k_work_reschedule(&attention_blink_work, K_NO_WAIT); } static void attention_off(const struct bt_mesh_model *mod) { /* Will stop rescheduling blink timer */ attention = false; } static const struct bt_mesh_health_srv_cb health_srv_cb = { .attn_on = attention_on, .attn_off = attention_off, }; static struct bt_mesh_health_srv health_srv = { .cb = &health_srv_cb, }; BT_MESH_HEALTH_PUB_DEFINE(health_pub, 0); static struct bt_mesh_elem elements[] = { BT_MESH_ELEM(1, BT_MESH_MODEL_LIST(BT_MESH_MODEL_CFG_SRV, BT_MESH_MODEL_HEALTH_SRV(&health_srv, &health_pub), BT_MESH_MODEL_SENSOR_CLI(&sensor_cli)), BT_MESH_MODEL_NONE), }; static const struct bt_mesh_comp comp = { .cid = CONFIG_BT_COMPANY_ID, .elem = elements, .elem_count = ARRAY_SIZE(elements), }; const struct bt_mesh_comp *model_handler_init(void) { k_work_init_delayable(&attention_blink_work, attention_blink); k_work_init_delayable(&get_data_work, get_data); k_work_init_delayable(&motion_timeout_work, motion_timeout); dk_button_handler_add(&button_handler); k_work_schedule(&get_data_work, K_MSEC(GET_DATA_INTERVAL)); return ∁ }
nus_handler.c
#include "nus_handler.h" #include <zephyr/types.h> #include <zephyr/sys/printk.h> #include <zephyr/bluetooth/gatt.h> #include <zephyr/bluetooth/bluetooth.h> #include <zephyr/sys/byteorder.h> #include <zephyr/types.h> #include <stddef.h> #include <zephyr/sys/printk.h> #include <zephyr/sys/byteorder.h> #include <zephyr/kernel.h> #include <zephyr/drivers/gpio.h> #include <soc.h> #include <zephyr/bluetooth/bluetooth.h> #include <zephyr/bluetooth/hci.h> #include <zephyr/bluetooth/conn.h> #include <zephyr/bluetooth/uuid.h> #include <bluetooth/services/nus.h> #include <dk_buttons_and_leds.h> #define DEVICE_NAME CONFIG_BT_DEVICE_NAME #define DEVICE_NAME_LEN (sizeof(CONFIG_BT_DEVICE_NAME) - 1) static struct bt_conn *current_conn; static struct k_work_delayable send_work; static struct bt_le_ext_adv *nus_adv; // 独立的扩展广告实例 static const char cmd_str[] = "123456789"; static uint8_t nus_conn_id = BT_ID_DEFAULT; /* Advertising配置 */ 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, DEVICE_NAME, DEVICE_NAME_LEN), }; static const struct bt_data sd[] = { BT_DATA_BYTES(BT_DATA_UUID128_ALL, BT_UUID_NUS_VAL), }; /* 蓝牙连接回调函数 */ static void connected(struct bt_conn *conn, uint8_t err) { if (err) { printk("Connection failed (err 0x%02x)\n", err); return; } printk("Connected\n"); current_conn = bt_conn_ref(conn); // 保存连接引用 } static void disconnected(struct bt_conn *conn, uint8_t reason) { printk("Disconnected (reason 0x%02x)\n", reason); if (current_conn) { bt_conn_unref(current_conn); // 释放连接引用 current_conn = NULL; } } /* 定义连接回调结构 */ BT_CONN_CB_DEFINE(conn_callbacks) = { .connected = connected, .disconnected = disconnected, }; /* 数据发送工作处理 */ static void send_work_handler(struct k_work *work) { if (current_conn) { int err = bt_nus_send(current_conn, cmd_str, sizeof(cmd_str) - 1); if (err == -ENOMEM) { printk("Failed to send NUS data: Out of memory (err %d)\n", err); } else if (err) { printk("Failed to send NUS data (err %d)\n", err); } else { printk("Sent: %s\n", cmd_str); } } else { printk("No active connection, skipping send\n"); } // 定时调度下一次发送任务 k_work_schedule(&send_work, K_SECONDS(5)); } /* NUS回调函数 */ static void bt_receive_cb(struct bt_conn *conn, const uint8_t *const data, uint16_t len) { printk("Received data: %.*s\n", len, data); } /* NUS回调结构 */ static struct bt_nus_cb nus_cb = { .received = bt_receive_cb, }; /* 初始化扩展广告 */ static int init_extended_advertising(void) { int err; size_t id_count = 0xFF; struct bt_le_adv_param adv_params = *BT_LE_ADV_CONN; /* 检查当前标识符数量 */ (void)bt_id_get(NULL, &id_count); if (id_count < CONFIG_BT_ID_MAX) { int id = bt_id_create(NULL, NULL); if (id < 0) { printk("Unable to create a new identity for NUS (err %d). Using the default one.\n", id); nus_conn_id = BT_ID_DEFAULT; } else { nus_conn_id = id; printk("Created a new identity for NUS: %d\n", nus_conn_id); } } else { nus_conn_id = BT_ID_DEFAULT; printk("Recovered identity for NUS: %d\n", nus_conn_id); } // struct bt_le_adv_param adv_params = { // // .options = BT_LE_ADV_OPT_EXT_ADV | BT_LE_ADV_OPT_CONNECTABLE, // 启用扩展广告并支持连接 // // .interval_min = BT_GAP_ADV_FAST_INT_MIN_2, // // .interval_max = BT_GAP_ADV_FAST_INT_MAX_2, // // .peer = NULL, // 无特定目标设备 // // .sid = 0, // 广播实例ID // .id = nus_conn_id, // }; adv_params.id = nus_conn_id; /* 创建扩展广告实例 */ err = bt_le_ext_adv_create(&adv_params, NULL, &nus_adv); if (err) { printk("Failed to create extended advertising instance (err %d)\n", err); return err; } /* 设置广告和扫描响应数据 */ err = bt_le_ext_adv_set_data(nus_adv, ad, ARRAY_SIZE(ad), sd, ARRAY_SIZE(sd)); if (err) { printk("Failed to set extended advertising data (err %d)\n", err); return err; } printk("Extended advertising instance created\n"); return 0; } /* 启动扩展广告 */ static int start_extended_advertising(void) { int err; err = bt_le_ext_adv_start(nus_adv, BT_LE_EXT_ADV_START_DEFAULT); if (err) { printk("Failed to start extended advertising (err %d)\n", err); return err; } printk("Extended advertising started\n"); return 0; } /* 初始化NUS服务的入口函数 */ int nus_handler_init(void) { int err; /* 初始化NUS服务 */ err = bt_nus_init(&nus_cb); if (err) { printk("Failed to initialize NUS (err %d)\n", err); return err; } printk("NUS service initialized\n"); /* 初始化扩展广告 */ err = init_extended_advertising(); if (err) { return err; } /* 启动扩展广告 */ err = start_extended_advertising(); if (err) { return err; } /* 初始化定时发送任务 */ k_work_init_delayable(&send_work, send_work_handler); k_work_schedule(&send_work, K_SECONDS(5)); // 每 5 秒发送一次数据 printk("NUS Handler initialized\n"); return 0; }
project config
# # Copyright (c) 2020 Nordic Semiconductor ASA # # SPDX-License-Identifier: LicenseRef-Nordic-5-Clause # CONFIG_NCS_SAMPLES_DEFAULTS=y # Deferred logging helps improve LPN power consumption # when friendship is established. CONFIG_LOG_MODE_DEFERRED=y # General configuration CONFIG_NCS_APPLICATION_BOOT_BANNER_STRING="Mesh Sensor Observer" #CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=2048 在后面加了个大的 CONFIG_FLASH=y CONFIG_FLASH_MAP=y # Flash shell module uses 8k of RAM for testing buffers, disable to save RAM CONFIG_FLASH_SHELL=n CONFIG_NVS=y CONFIG_NVS_LOOKUP_CACHE=y CONFIG_SETTINGS=y CONFIG_SETTINGS_NVS_NAME_CACHE=y CONFIG_HWINFO=y CONFIG_DK_LIBRARY=y CONFIG_PM_SINGLE_IMAGE=y CONFIG_PM_PARTITION_SIZE_SETTINGS_STORAGE=0x8000 CONFIG_SOC_FLASH_NRF_PARTIAL_ERASE=y CONFIG_CBPRINTF_FP_SUPPORT=y # Bluetooth configuration CONFIG_BT=y CONFIG_BT_DEVICE_NAME="Mesh Sensor Observer" CONFIG_BT_L2CAP_TX_BUF_COUNT=8 CONFIG_BT_OBSERVER=y CONFIG_BT_PERIPHERAL=y CONFIG_BT_SETTINGS=y # Disable unused Bluetooth features CONFIG_BT_CTLR_LE_ENC=n CONFIG_BT_PHY_UPDATE=n CONFIG_BT_CTLR_CHAN_SEL_2=n CONFIG_BT_CTLR_MIN_USED_CHAN=n CONFIG_BT_CTLR_PRIVACY=n # Bluetooth Mesh configuration CONFIG_BT_MESH=y CONFIG_BT_MESH_RELAY=y CONFIG_BT_MESH_FRIEND=y CONFIG_BT_MESH_TX_SEG_MAX=24 CONFIG_BT_MESH_RX_SEG_MAX=16 CONFIG_BT_MESH_PB_GATT=y CONFIG_BT_MESH_GATT_PROXY=y CONFIG_BT_MESH_PROXY_USE_DEVICE_NAME=y CONFIG_BT_MESH_DK_PROV=y CONFIG_BT_MESH_SUBNET_COUNT=2 CONFIG_BT_MESH_APP_KEY_COUNT=3 CONFIG_BT_MESH_MODEL_KEY_COUNT=3 CONFIG_BT_MESH_CRPL=32 CONFIG_BT_MESH_MSG_CACHE_SIZE=64 CONFIG_BT_MESH_SHELL=y # Bluetooth Mesh models CONFIG_BT_MESH_SENSOR_CLI=y CONFIG_LOG_BACKEND_RTT=n #我加的我加的 CONFIG_BT_NUS=y # CONFIG_FLASH_PAGE_LAYOUT=y CONFIG_BT_EXT_ADV_MAX_ADV_SET=6 # CONFIG_BT_BUF_ACL_RX_SIZE=27 # CONFIG_BT_BUF_ACL_TX_SIZE=27 # CONFIG_BT_BUF_ACL_TX_COUNT=10 # CONFIG_BT_BUF_EVT_RX_COUNT=10 # CONFIG_BT_BUF_EVT_DISCARDABLE_SIZE=58 # CONFIG_HEAP_MEM_POOL_SIZE=4096 # CONFIG_MAIN_STACK_SIZE=2048 # CONFIG_SYSTEM_WORKQUEUE_STACK_SIZE=4096 CONFIG_BT_ID_MAX=2 CONFIG_BT_MAX_CONN=3
However, I encountered an issue: despite maintaining the logic and structure of the ble_peripheral_lbs_coex code entirely, I am unable to initialize advertising, and I frequently receive errors such as 'no BUFFER', 'no context', and 'No more contexts.'
*** Booting Mesh Sensor Observer v2.9.0-99e1dd02b3a7 *** *** Using nRF Connect SDK v2.9.0-7787b2649840 *** *** Using Zephyr OS v3.7.99-1f8f3dc29142 *** Initializing... [00:00:00.008,209] <inf> fs_nvs: 8 Sectors of 4096 bytes [00:00:00.008,209] <inf> fs_nvs: alloc wra: 0, fe8 [00:00:00.008,239] <inf> fs_nvs: data wra: 0, 0 [00:00:00.008,575] <inf> bt_sdc_hci_driver: SoftDevice Controller build revision: 2d 79 a1 c8 6a 40 b7 3c f6 74 f9 0b 22 d3 c4 80 |-y..j@.< .t.."... 74 72 82 ba |tr.. [00:00:00.012,512] <inf> bt_hci_core: HW Platform: Nordic Semiconductor (0x0002) [00:00:00.012,542] <inf> bt_hci_core: HW Variant: nRF52x (0x0002) [00:00:00.012,603] <inf> bt_hci_core: Firmware: Standard Bluetooth controller (0x00) Version 45.41337 Build 3074452168 [00:00:00.012,939] <inf> bt_hci_core: No ID address. App must call settings_load() Bluetooth initialized [00:00:00.271,362] <inf> bt_hci_core: Identity: CC:E6:9E:65:8E:2C (random) [00:00:00.271,392] <inf> bt_hci_core: HCI: version 6.0 (0x0e) revision 0x106b, manufacturer 0x0059 [00:00:00.271,423] <inf> bt_hci_core: LMP: version 6.0 (0x0e) subver 0x106b [00:00:00.277,465] <inf> bt_mesh_provisionee: Device UUID: 0bc7df6f-43c0-4ca9-b438-2090bc3fc356 Mesh initialized NUS service initialized Recovered identity for NUS: 0 Failed to create extended advertising instance (err -12) NUS handler initialization failed (err -12)
Could you let me know if my approach is correct? Is it possible to integrate NUS with BLE Mesh? Alternatively, is there another way to achieve similar functionality? I have not found relevant examples online and look forward to your response : )