一、项目介绍
MAX32655FTHR 基于 Analog Devices MAX32655 微控制器(Arm Cortex-M4F 核心,集成 BLE 5.0 射频模块),适合验证低功耗多传感器数据采集与无线上报场景。开发板结合板载 I2C2 总线(P0_30/P0_31)与用户可编程 LED,并基于 WSF(Wireless Software Framework)蓝牙协议栈的 GATT Server 与 WSF Timer 机制,可用于实现多路传感器周期性采样、本地 OLED 实时显示与蓝牙 Notify 推送的一体化环境监测终端。
在实时性方面,WSF 提供的 wsfTimer_t 定时器、AttsHandleValueNtf 通知接口以及 AttsCccEnabled 订阅状态查询机制,可以在保证 BLE 连接稳定性的前提下完成多路传感器数据的周期采集与推送;同时引入 LVGL 图形库驱动 SSD1306 OLED,通过独立于 BLE 连接状态的定时器保证屏幕持续高频刷新。结合三颗环境传感器,MAX32655FTHR 非常适合构建"多传感器融合采集 + 双端(上位机/小程序)BLE 接收 + 阈值声光报警"的完整应用原型。
硬件平台
本次使用 Analog Devices MAX32655FTHR 开发板,是一款面向物联网应用的高性能蓝牙低功耗开发平台。该开发板搭载了基于 ARM Cortex-M4 内核的 MAX32655 微控制器,具备丰富的外设资源,包括多个 I2C 接口、GPIO 端口等,非常适合用于多传感器蓝牙低功耗监测站的开发。开发板集成了蓝牙射频模块、调试接口与用户可编程 LED,便于快速搭建无线环境监测节点。
软件平台
在软件方面,本项目采用 VSCode + ADI CodeFusion Studio插件作为开发环境;WSF(Wireless Software Framework)蓝牙协议栈作为底层运行环境,配合 LVGL 图形库与 SSD1306 I2C HAL 驱动 OLED 显示。通过将传感器读取、GATT 服务与显示渲染整合到统一的 WSF 事件循环中,实现了 BLE 从机广播、多特征 Notify 推送以及本地可视化显示的协同工作。
ADI CodeFusion Studio 开发调试画面:

主控设备:Analog Devices MAX32655FTHR 开发板
- 搭载 MAX32655 MCU(ARM Cortex-M4F)
- 集成蓝牙 5.0 低功耗射频模块
- 板载用户可编程 LED 指示灯,用于报警联动
- 支持自定义多服务 GATT Profile

传感器模块
- SHT30 模块(温湿度)

- RPR-0521RS 光照接近传感器模块

- STEVAL-MKI192V1(LPS22HH)气压传感器模块

- SSD1306 OLED 显示模块(I2C,128×64)
项目目标:
- 多传感器融合采集:单一 I2C2 总线同时挂载 SHT30、RPR0521RS、LPS22HH 三颗传感器与 OLED,一次定时器触发内完成全部读取与刷新。
- 采样周期可配置:通过宏
FIT_SENSOR_SAMPLE_PERIOD_SEC在 1~60 秒范围内任意配置,编译期越界检查防止误配置。 - OLED 高刷新率显示:独立于 BLE 连接状态的 LVGL 定时器以 20ms 周期驱动,实测刷新率约 50Hz,远超 5Hz 设计指标。
- 双端 BLE 接收:Python 上位机(bleak)与微信小程序均可同时连接设备,稳定接收温度/湿度/气压/光照/接近五路 Notify。
- 声光报警联动:小程序端持续监测温度是否跨越设定阈值,一旦跨越,1 秒内触发手机震动提醒并联动 LED 开关,且仅在跨越瞬间触发一次,杜绝持续超阈值时的重复报警。
二、任务分析与实现思路
本次我选做的任务是“赛道二:智能感知”其中的题目一:多传感器环境监测站。
题目要求可以拆为5个关键点:
- 采集温度、湿度、气压、光照等环境数据,这需要我们准备好相应的传感器模块,并编写驱动,建立正常的数据读取功能;
- 采样周期1秒至1分钟可配置,这既是对功能,也是对程序结构的要求,要存在一个变量或预定义常量,可以通过它来决定数据采集周期;
- 在OLED屏实时显示(刷新率5Hz以上),显示方面的要求,需要准备并驱动OLED显示屏;
- 并通过BLE发送至手机或上位机,存在上位机与通信要求,且使用BLE进行通信;
- 当监测数据超过设定阈值时,1秒内触发声光报警提示,对于提示的发生没有具体的要求,我们既可以在下位机使用LED、屏幕、蜂鸣器等发出声光报警,也可以在上位机实现此功能。
针对题目要求,我设计了如图的系统实现:

在工程实现过程中有几个关键的技术点:
双定时器解耦设计:
fitSetup() 中启动两个完全独立的 WSF 定时器:fitSensorTimer 按 FIT_SENSOR_PERIOD_MS(由采样周期宏换算)周期触发传感器读取与 Notify 发送;fitLvglTimer 固定 20ms 周期驱动 lv_tick_inc 与 lv_task_handler。二者互不依赖,即使设备未与手机建立 BLE 连接,OLED 依然持续刷新,保证了"采样周期可调"与"显示刷新率恒定"两个指标互不冲突。
采样周期可配置机制:
FIT_SENSOR_SAMPLE_PERIOD_SEC 宏统一控制三颗传感器的读取频率、GATT 属性更新频率与 Notify 发送频率,取值范围通过 #if 预处理指令做编译期合法性检查,超出 [1, 60] 直接报错,避免烧录后才发现采样异常。
GATT 多服务 Notify 设计:
温度、湿度、气压、光照、接近五个数据分别建立独立 GATT 服务与特征,均带 CCC 描述符支持 Notify 订阅。fitSensorUpdate() 中统一通过 AttsCccEnabled() 判断客户端订阅状态,仅在已订阅时才调用 AttsHandleValueNtf() 推送,避免向未订阅通道无意义发送数据。
Notify 可靠性保障:
针对多路传感器同时高频推送导致 WSF 通知缓冲池耗尽的问题,通过调整 appUpdateCfg_t 连接间隔参数与 mainPoolDesc 缓冲池数量两方面协同优化,确保五路 Notify 在任意采样周期设置下都能稳定送达,不出现某一路特征值"卡住不更新"的情况。
阈值报警边沿触发机制:
小程序端维护 tempAboveThreshold 状态标记,每次收到温度 Notify 后计算当前是否超阈值,仅当状态发生翻转(isAbove !== 上次记录值)时才触发一次 wx.vibrateShort 震动与 LED 写入操作;持续停留在同一侧不会重复触发,满足"跨越阈值触发一次"的设计要求。
三、实现过程
3.1 开发环境搭建
基于 MAX32655FTHR SDK 搭建 WSF 协议栈工程,配置 mainPoolDesc 缓冲池描述符与 StackInitFit/FitStart 初始化流程,确保 GATT Server、DM 层与 ATT 层回调正确注册。
3.2 外设配置
I2C2 总线以 100kHz 频率初始化,依次挂载 SHT30(地址 0x45)、RPR0521RS(地址 0x38)、LPS22HH(地址 0x5C)与 SSD1306 OLED(地址 0x3C)。针对 MAX32655 GPIO 存在 VDDIO/VDDIOH 双电压域的问题,在 ssd1306_i2c_hal_init() 中显式调用 MXC_GPIO_SetVSSEL 切换到 3.3V 域,避免 OLED 因电平不匹配无法通信。
3.3 主要代码实现
软件流程:FitHandlerInit 完成传感器与 OLED 初始化 → fitSetup 启动双定时器 → fitProcMsg 分发采样与 LVGL 事件 → fitSensorUpdate 完成"读取-更新属性-条件通知-刷新显示"闭环。
3.3.1 采样周期宏与定时器换算
#define FIT_SENSOR_SAMPLE_PERIOD_SEC 1U
#if (FIT_SENSOR_SAMPLE_PERIOD_SEC < 1) || (FIT_SENSOR_SAMPLE_PERIOD_SEC > 60)
#error "FIT_SENSOR_SAMPLE_PERIOD_SEC must be within [1, 60] seconds"
#endif
#define FIT_SENSOR_PERIOD_MS (FIT_SENSOR_SAMPLE_PERIOD_SEC * 1000UL)
#define FIT_LVGL_PERIOD_MS 20
3.3.2 多传感器融合读取与条件通知
static void fitSensorUpdate(void)
{
fitSht30.read(&fitShtData);
fitRpr0521rs.read(&fitRprData);
fitLps22hh.read(&fitLpsData);
SvcEnvSetTemperature(fitShtData.temperature);
SvcEnvSetHumidity(fitShtData.humidity);
SvcEnvSetPressure(fitLpsData.pressure);
SvcEnvSetLight(fitRprData.als);
SvcEnvSetProximity(fitRprData.ps);
if (fitConnId != DM_CONN_ID_NONE) {
if (AttsCccEnabled(fitConnId, FIT_ENV_TEMP_CCC_IDX)) {
AttsHandleValueNtf(fitConnId, ENV_TEMP_HANDLE_DATA,
ENV_TEMP_SIZE_DATA_ATT, SvcEnvGetTempValue());
}
/* ... 其余四路同理 ... */
}
}
3.3.3 双定时器解耦刷新
case FIT_SENSOR_TIMER_IND:
fitSensorUpdate();
WsfTimerStartMs(&fitSensorTimer, FIT_SENSOR_PERIOD_MS);
break;
case FIT_LVGL_TIMER_IND:
lv_tick_inc(FIT_LVGL_PERIOD_MS);
lv_task_handler();
WsfTimerStartMs(&fitLvglTimer, FIT_LVGL_PERIOD_MS);
break;
3.3.4 阈值跨越判定(小程序端)
checkTempAlarm(value) {
const isAbove = value > this.data.tempThreshold
if (this.data.tempAboveThreshold === null) {
this.setData({ tempAboveThreshold: isAbove })
return
}
if (isAbove === this.data.tempAboveThreshold) return
this.setData({ tempAboveThreshold: isAbove })
if (isAbove) {
wx.vibrateShort({ type: 'heavy' })
this.setLedState(true)
} else {
this.setLedState(false)
}
}
四、实物验证
整体效果

4.1 传感器采集
读取所有传感器模块信息,通过串口打印数据。其中温度T来自SHT30、温度T2来自LPS22HH传感器,数值基本接近。


4.2 上位机 BLE 连接测试
Python 上位机与微信小程序分别单独连接、及先后连接测试中,五路 Notify(温度/湿度/气压/光照/接近)均能持续稳定接收,此前发现的"接近传感器 Notify 数轮后停止"问题经连接间隔与缓冲池调优后未再复现。
Python上位机日志

微信小程序画面

4.3 声光报警测试
手动加热传感器使温度跨越设定阈值,1 秒内手机发出声音提示并点亮板载 LED;温度持续维持在阈值以上时不再重复震动;温度回落跨越阈值后 LED 自动熄灭,且回落/上升过程均只触发一次动作,验证了边沿触发逻辑的正确性。

五、总结
本项目基于ADI CodeFusion Studio开发,将多传感器 I2C 融合采集、WSF BLE GATT 多服务 Notify、LVGL OLED 高频渲染与小程序端阈值边沿报警等多个技术点有机整合,形成了一个采样周期可灵活配置、显示刷新流畅、蓝牙推送可靠、报警响应及时的环境监测站原型。项目过程中重点解决了 BLE 通知缓冲池在多路高频推送下的资源争用问题,并通过双定时器解耦保证了显示与通信两条链路互不干扰。后续可在此基础上为气压、光照增加独立阈值报警通道,并将报警状态通过专用 GATT 特征回传给上位机,实现设备端与云端的双向报警确认。