目录
概述
本文主要介绍基于nRF Connect SDK实现Beacon功能,笔者基于vs-code开发环境详细介绍了项目模块配置,设备树配置,UUID的实现,以及Beacon扫描和解析功能等内容。
1. Beacon 功能概述
蓝牙 Beacon 是一种单向广播设备,通过特定数据格式持续发送信号,用于位置服务、资产追踪等场景。nRF Connect SDK 支持以下主流 Beacon 协议:
- iBeacon(Apple 协议)
- Eddystone(Google 协议)
- 自定义 Beacon
2. 快速实现 iBeacon
2.1 配置 prj.conf
CONFIG_BT=y
CONFIG_BT_BROADCASTER=y # 启用广播角色
CONFIG_BT_EXT_ADV=y # 启用扩展广播
CONFIG_BT_DEVICE_NAME="iBeacon" # 设备名称(可选)
2.2 代码实现
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
// iBeacon 数据格式定义
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
BT_DATA_BYTES(BT_DATA_MANUFACTURER_DATA,
0x4C, 0x00, // Apple Company ID (0x004C)
0x02, 0x15, // iBeacon 类型标识
// Proximity UUID (16字节)
0xE2, 0xC5, 0x6D, 0xB5, 0xDF, 0xFB, 0x48, 0xD2,
0xB0, 0x60, 0xD0, 0xF5, 0xA7, 0x10, 0x96, 0xE0,
0x00, 0x01, // Major (0x0001)
0x00, 0x02, // Minor (0x0002)
0xC5, // Tx Power (-59 dBm)
),
};
void main(void) {
// 初始化蓝牙
bt_enable(NULL);
// 启动广播
struct bt_le_adv_param *adv_param = BT_LE_ADV_PARAM(
BT_LE_ADV_OPT_USE_IDENTITY | BT_LE_ADV_OPT_EXT_ADV,
BT_GAP_ADV_SLOW_INT_MIN,
BT_GAP_ADV_SLOW_INT_MAX,
NULL
);
bt_le_adv_start(adv_param, ad, ARRAY_SIZE(ad), NULL, 0);
}
3. 实现 Eddystone-UID
3.1 Eddystone 数据格式
// Eddystone-UID 广播数据示例
static const struct bt_data ad[] = {
BT_DATA_BYTES(BT_DATA_FLAGS, BT_LE_AD_NO_BREDR),
BT_DATA_BYTES(BT_DATA_SVC_DATA16,
0xAA, 0xFE, // Eddystone Service UUID (0xFEAA)
0x00, // Frame Type: UID (0x00)
0xED, // Tx Power (-19 dBm)
// Namespace ID (10字节)
0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF, 0x01, 0x23,
// Instance ID (6字节)
0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
),
};
3.2 配置说明
# prj.conf
CONFIG_BT_CTLR_ADV_EXT=y # 必需扩展广播支持
CONFIG_BT_CTLR_ADV_DATA_LEN_MAX=31 # 扩展广播数据长度
4. Beacon 扫描与解析
4.1 配置 Central 角色
CONFIG_BT_OBSERVER=y # 启用扫描功能
CONFIG_BT_SCAN=y
CONFIG_BT_SCAN_FILTER_ENABLE=y # 启用扫描过滤
4.2 解析 iBeacon 数据
static void scan_cb(const bt_addr_le_t *addr, int8_t rssi,
uint8_t type, struct net_buf_simple *ad) {
// 检查 Manufacturer Data
struct bt_data data;
while (bt_data_parse(ad, &data)) {
if (data.type == BT_DATA_MANUFACTURER_DATA && data.data_len >= 25) {
const uint8_t *ptr = data.data;
if (sys_get_le16(ptr) == 0x004C && ptr[2] == 0x02 && ptr[3] == 0x15) {
printk("iBeacon detected: UUID=%s, RSSI=%d\n",
uuid_str(ptr + 4), rssi);
}
}
}
}
// 启动扫描
struct bt_le_scan_param scan_param = BT_LE_SCAN_PARAM(
BT_LE_SCAN_TYPE_PASSIVE, BT_LE_SCAN_OPT_FILTER_DUPLICATES,
BT_GAP_SCAN_FAST_INTERVAL, BT_GAP_SCAN_FAST_WINDOW
);
bt_le_scan_start(&scan_param, scan_cb);
5. Beacon 参数优化
5.1 调整广播间隔
# 设置慢速广播间隔(节省功耗)
CONFIG_BT_GAP_ADV_SLOW_INT_MIN=1600 // 1s (1600*0.625ms)
CONFIG_BT_GAP_ADV_SLOW_INT_MAX=1600
5.2 校准发射功率
// 设置 Tx Power (单位: dBm)
bt_le_adv_param_set_tx_power(BT_HCI_LE_TX_POWER_MAX_ENHANCED);
6. 常见问题
Q:Beacon 未被手机检测到?
- 排查步骤:
- 确认广播数据长度 ≤ 31 字节(非扩展广播)。
- 检查 Manufacturer Data 格式是否符合标准(iBeacon/Eddystone)。
- 使用 nRF Connect for iOS/Android 验证广播数据。
Q:扫描时频繁丢包?
- 优化方法:
- 缩短扫描窗口:
CONFIG_BT_GAP_SCAN_FAST_WINDOW=16
(10ms)。 - 减少广播间隔:
CONFIG_BT_GAP_ADV_FAST_INT_MIN=32
(20ms)。
- 缩短扫描窗口:
7. 参考资源
- nRF Beacon 示例代码:
ncs/nrf/samples/bluetooth/beacon
- Eddystone 协议规范:
Google Eddystone Documentation - iBeacon 开发指南:
Apple iBeacon Guide
通过上述配置与代码,您可快速实现 Beacon 广播与扫描功能,并优化其性能以满足实际应用需求