原本计划进行功耗测试,看到有网友已经做了相关测试,并且需要使用额外的板子才能使用 power 工具,遂作罢。
在之前的文章中提到, QSG169:《蓝牙 SDK v3.x 快速入门指南》中关于蓝牙协议栈,介绍了三种工作模式。本人对其中的 NCP 模式比较感兴趣,这次就来研究一下。
NCP 全称为:network Co-Processor(NCP) Mode,官方对其介绍如下:
Network Co-Processor (NCP) mode, where the Bluetooth stack runs in an EFR32 and the application runs on a separate host MCU. For this use case, the Bluetooth stack can be configured into NCP mode where the API is exposed over a serial inter- face such as UART.
其功能结构框图如下:
如上图,蓝牙 SOC 只负责协议栈相关的处理。我们的应用程序运行在单独的设备上,可以是其它 MCU 或者 PC 上位机。可以通过名为 BGAPI 的软件接口,使用 UART 硬件接口进行蓝牙协议栈的配置。
在第二篇文章【Silicon Labs BG22-EK4108A 蓝牙开发评测】二:开发环境初体验 中,我们简单体验了一下 NCP 模式,当时使用官方提供的图形化工具 -- Bluetooth NCP Commander 进行蓝牙协议栈的配置。
继续研究,发现官方提供了一个名为 PyBGAPI 的 python 库。对 PyBGAPI 的介绍如下:
This package provides a Python interface for the BGAPI binary protocol. It reads the BGAPI definition file and dynamically generates a parser for it.
这意味着我们可以通过 python 语言来很方便地进行蓝牙协议栈的配置。接下来就以我们上一篇中介绍的官方例程 Bluetooth-Soc Blinky 为参考,通过 python 控制运行于 NCP 模式下的 EFR32BG22 SOC 来实现 Blinky 例程功能。
关于 PyBGAPI 库的使用,可以参考官方给出的例程。这里在 empty 例程的基础上添加代码,实现我们需要的功能。 修改蓝牙名字等这些简单操作就不一一介绍了,这里讲一下关于蓝牙服务的添加及控制数据的处理。
首先是添加蓝牙 Blinky 服务,服务 UUID 可以在官方 Blinky 例程中找到。然后是添加 Button 和 LED 两个特征,特征 UUID 同样参考官方例程。注意这里的 Button 特征属性为 Read 和 Notify,LED 特征属性为 Write 和 Read。 在 gattdb_init 方法中增加如下代码:
# Blinky service
_, service = self.lib.bt.gattdb.add_service(
session,
self.lib.bt.gattdb.SERVICE_TYPE_PRIMARY_SERVICE,
self.lib.bt.gattdb.SERVICE_PROPERTY_FLAGS_ADVERTISED_SERVICE,
b"x24x12xb5xcbxd4x60x80x0cx15xc3x9bxa9xacx5ax8axde"
)
# Report button
_, self.gattdb_report_button = self.lib.bt.gattdb.add_uuid128_characteristic(
session,
service,
self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_READ |
self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_NOTIFY,
0,
0,
b"x9cxd2x70x2ax65x6dx53x9axd0x60xc3x41xa4x85xa8x61",
self.lib.bt.gattdb.VALUE_TYPE_FIXED_LENGTH_VALUE,
1,
b"x00"
)
self.lib.bt.gattdb.start_service(session, service)
# LED Contorl
_, self.gattdb_led_control = self.lib.bt.gattdb.add_uuid128_characteristic(
session,
service,
self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_READ |
self.lib.bt.gattdb.CHARACTERISTIC_PROPERTIES_CHARACTERISTIC_WRITE,
0,
0,
b"x7ax08x6ax73x6cxbexd8x46x97xc2x88x40x10x65x02x5b",
self.lib.bt.gattdb.VALUE_TYPE_FIXED_LENGTH_VALUE,
1,
b"x00"
)
self.lib.bt.gattdb.start_service(session, service)
这里仅介绍 LED 控制状态的处理。在 event_handler 方法中添加如下代码:
elif evt == "bt_evt_gatt_server_attribute_value":
if evt.att_opcode == self.lib.bt.gatt.ATT_OPCODE_WRITE_REQUEST:
led_status_update(evt.value)
当 LED 特征执行写入请求操作时,就会调用 led_status_update 方法,进行 LED 状态的更新操作。这里仅通过打印日志反应 LED 状态,代码如下:
def led_status_update(value):
if value== b'x00':
print("led off.")
elif value == b'x01':
print("led on.")
else:
print("Invalid value.")
原计划是基于 python 开发一个桌面端的图形上位机,结合 EFR Connect 进行更直观的功能演示。奈何 iOS 端的 EFR Connect 最近更新后似乎有 bug,在 Demo 页面搜索不到对应的设备,记得上一个版本是可以的。于是乎一切从简,就做一个简单的演示吧。
注:开发板需要提前烧录好 NCP 固件。
EFR32BG22 的这个 NCP 模式给应用开发提供了更多的选择,同时可玩性也大大提高。比如我们可以将开发板作为一个蓝牙鼠标接收器。由于提供了 python 库,因此开发也变得很简单,可轻松实现跨平台。
本帖最后由 jj1989 于 2022-2-9 09:04 编辑