blhost 补充烧录并跑通 peripheral_ht 例子
Zephyr 官方有相当多的 BLE 蓝牙例程,我们可以直接用 samples/bluetooth/peripheral_ht 作为起点,初始化我们的项目,本想用 west build -b frdm_mcxw71 && west flash 快速看一下效果,结果发现烧写完成后,板子直接报错了.

经过考证,是因为 MCXW71 其实是一个多核心的系统,主核心是 Cortex-M33 而负责无线处理也有一个单独的 Cortex-M3 核心(NBU / 窄带单元),主核心上操作的蓝牙实际上是通过 HCI 接口与 NBU 核心进行协作的,而不是直接读写无线控制器实现的. 我们这里只是烧录了主核心的固件,无线处理的核心需要进入 ISP 模式才能够烧录,我们需要下载 blhost 工具.


然后可以看到 Zephyr 的模块下有一个给 MCXW71 设计的 SB3 固件,我们下载下来后通过
blhost -p /dev/ttyACM0 -- receive-sb-file mcxw71_nbu_ble_hosted.sb3
就可以烧录 NBU 固件了.


我们再重新上一下电就可以正常启动了.

用 BLE Toolbox 可以看到对应的数据.

SHT30 传感器
既然基本的通信我们有了,下面我们就开始着手让 Zephyr 接入 SHT30 传感器吧,既然是模拟信号的传感器,只要先找可以用的 ADC 引出就可以了. 板子的用户手册说 UNO 接口一部分的 J4 上有三个 ADC 口,然后查芯片的参考手册发现在 ADC 内部对应不同的通道,B5 是 CH1B,A6 是 CH2A,B6 是 CH2B


然后折腾了很长时间写好的设备树,这样就可以比较方便的用 Zephyr 推荐的方式读取这两个通道的值了.

C 代码里,初始化主要用到了设备树 API 相关 adc_channel_setup_dt 之类的 API

读取的话就需要设置 adc_sequence 用来指示输出的缓冲区,这里读出来的是电压值模拟量.

模拟量需要经过一个线性映射从而转换成实际有意义的传感数据,可以看 SHT30 的手册实现转换函数.


下面是踩坑阶段写的小例子,可以直接输出温度和相对湿度数据.

BLE 实现
这里例子实现的是标准 HTS 即体温计,实际上 Bluetooth 委员会有一个标准的环境监测 profile 叫做 ESS,里面可以塞气压、温度、湿度这样的数据.
这是原版 HTS 的服务结构

我们只需要改成两个 characteristic 然后每个后面附带一个 CCCD 用于订阅通知即可.

基本的逻辑是不变的,甚至 BLE 的数据处理部分还更简单,因为原先 HTS 的浮点数需要符合 IEEE-11073 的要求,需要一定的处理变换,而 ESS 的数据其实就是 0.01 精度的 16 位定点数.

用 BLE Toolbox 看一下,确实同步更新了.

接入网页 app
BLE 设备调通之后,下一步就是做一个前端 app 来读取数据. 我写了一个单页的 HTML 应用,通过 Web Bluetooth API 连接设备,把温度和湿度实时显示出来.

连接逻辑其实不复杂:先扫描名称前缀为 `EEPW` 的设备,连上之后获取环境监测服务(UUID `0x181A`),再分别拿到温度和湿度两个 characteristic 并开启 notify. 数据过来之后更新 DOM 上的数值,同时推入 Chart.js 的图表里,形成历史趋势曲线. 整个过程就是标准的 Web Bluetooth 流程,没什么特别花哨的地方,但作为演示工具够用了.


总结
这次活动让我更加熟悉 Zephyr 特别是 ADC 的配置和使用技巧,完整的代码可以在这里查看 https://codeberg.org/scgummy/eepw-e14-thermo
我要赚赏金
