任务介绍
本项目实现了Funpack第4-1期活动Qorvo板卡的任务二,基于Qorvo DWM3001CDK开发板实现了蓝牙低功耗(BLE)环境监测系统,通过微信小程序实时获取温湿度数据并控制蜂鸣器告警。系统采用Nordic nRF52833的蓝牙5.0协议栈,构建了完整的物联网监测解决方案。
硬件平台
首先介绍本次用到的开发板:DWM3001CDK,它是射频方案商Qorvo推出的一块基于Nordic nRF52833微控制器的UWB开发板,它主要面向的是UWB定位应用的开发,但由于使用了nRF52833这一片低功耗蓝牙SoC,所以也同时支持蓝牙、NFC等常用功能。开发板分为底板和核心邮票板,底板引出了大量引脚,并集成了常用的外设,如按键、LED、串口、NFC、USB接口和调试器接口。在软件方面,Nordic官方和第三方平台已经适配好了Arduino、nRF5 SDK、NCS等多种开发框架,上手开发会很方便。本次我会使用这块开发板的低功耗蓝牙,做一个基于BLE的温湿度监测系统。
主控设备:Qorvo DWM3001CDK开发板
- 搭载Nordic nRF52833低功耗蓝牙SoC
- 集成NFC Type 2标签功能
- 板载4个可编程LED指示灯
- 支持多线程实时操作系统(Zephyr RTOS)
传感执行器扩展板
- 板载AHT20高精度温湿度传感器
- 无源蜂鸣器驱动电路
- 128x64 SSD1306 OLED显示屏
监测终端
- 微信小程序(支持BLE客户端)
- 蓝牙协议规范:GATT
- 数据传输速率:2Kbps(环境数据通道)
- 控制指令:1字节开关量
任务分析与实现
本系统实现了基于BLE协议的物联网环境监测方案,主要功能包括:
三通道数据交互:
- 环境数据采集
- 温度测量范围:-40℃~85℃ (±0.3℃)
- 湿度测量范围:0-100%RH (±2%)
- 采样频率:4Hz(BLE传输降频至2Hz)
- BLE数据传输
- 温度服务UUID:ADAF0000(Adafruit标准服务)
- 湿度服务UUID:ADAF0700(Adafruit扩展服务)
- 数据格式:IEEE754单精度浮点
- 设备控制通道
- 蜂鸣器控制服务UUID:00001523(Nordic LBS服务)
- 控制协议:1字节指令(0x00关/0x01开)
- PWM参数:1KHz方波,50%占空比
方案框图:
代码详解
下位机核心逻辑
下位机整体软件流程图:
一、硬件初始化与传感器配置
系统上电后首先完成外设初始化序列,关键流程如下:
- 采用
digitalWrite
直接控制LED状态指示灯,确保设备状态可视化 - PWM时钟分频设为16,产生1MHz基频满足蜂鸣器驱动需求,之后设置计数器实现1KHz波形输出
- I2C总线增加传感器检测重试机制,避免启动失败导致系统瘫痪
void setup() {
// 配置双色状态指示灯
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_RED_BOT, OUTPUT);
digitalWrite(LED_GREEN, HIGH); // 初始状态:绿灯亮表示待机
// 初始化PWM蜂鸣器驱动
HwPWM0.addPin(BUZZER_PIN);
HwPWM0.begin();
HwPWM0.setResolution(15); // 15位分辨率提供精细控制
HwPWM0.setClockDiv(PWM_PRESCALER_PRESCALER_DIV_16);
// 启动AHT20温湿度传感器
Wire.begin();
while(!aht20.begin()) { // 阻塞式检测确保传感器就绪
Serial.println("AHT20初始化失败,请检查连接");
delay(1000);
}
}
二、BLE服务
// Adafruit标准环境服务(温度)
BLEAdafruitTemperature bleTemp;
// Adafruit扩展湿度服务
BLEAdafruitHumid bleHumid;
// Nordic按钮服务(复用为蜂鸣器控制)
BLEService lbs(LBS_UUID_SERVICE);
BLECharacteristic lsbLED(LBS_UUID_CHR_LED);
服务配置策略:
- 温度服务:使用预定义UUID
ADAF0100
,兼容主流BLE客户端 - 湿度服务:采用扩展UUID
ADAF0700
,保持服务独立性 - 控制服务:复用Nordic LBS规范,利用现有特征值实现快速开发
三、温湿度采集
关键特性
- 主循环以4Hz频率更新传感器数据,保证响应实时性
- BLE特征值回调直接访问全局变量,避免重复采样
- 内存拷贝使用
memcpy
而非逐字节赋值,提升传输效率
void loop() {
// 高速采样(250ms)
currentTemperature = aht20.getTemperature();
currentHumidity = aht20.getHumidity();
// BLE回调直接读取全局变量
uint16_t tempMeasureCallback(uint8_t* buf, uint16_t bufsize) {
memcpy(buf, ¤tTemperature, 4); // 小端格式传输
return sizeof(float);
}
}
四、蜂鸣器设备控制逻辑
1、关键特性
- PWM值500对应1KHz方波信号,驱动无源蜂鸣器
- 附加1个红色LED作为视觉反馈,增强人机交互体验
- 回调函数中避免耗时操作,确保蓝牙栈响应及时性
2、监听write回调
上位机作为central设备,控制下位机的Peripheral设备,需要向相应的Character写入数据,我们需要设置write回调来根据写入数据控制蜂鸣器和LED。
void led_write_callback(...) {
if (data[0]) {
HwPWM0.writePin(BUZZER_PIN, 500); // 500/1000=50%占空比
digitalWrite(LED_RED_BOT, LOW); // 红色指示灯同步状态
} else {
HwPWM0.writePin(BUZZER_PIN, 0); // 关闭PWM输出
digitalWrite(LED_RED_BOT, HIGH);
}
}
微信小程序核心逻辑
微信小程序整体软件流程图:
一、服务发现策略
关键技术点
- 使用UUID模式匹配而非精确比较,提高协议兼容性
- 分离环境服务和控制服务的处理逻辑,降低耦合度
const SERVICE_UUID = {
TEMPERATURE: 'ADAF0100-C332-...',
CONTROL: '00001523-1212-...'
};
wx.getBLEDeviceServices({
success: res => {
res.services.forEach(service => {
if (service.uuid.includes('ADAF01')) this.handleEnvService(service)
if (service.uuid.includes('1523')) this.handleControlService(service)
})
}
})
二、数据流处理
采用事件驱动架构实现高效数据解析。
wx.onBLECharacteristicValueChange(res => {
const dv = new DataView(res.value);
const value = dv.getFloat32(0, true); // 小端格式解析
if (res.characteristicId === tempChar) {
this.setData({
temperature: value.toFixed(1) // 保留1位小数
});
}
})
优化措施
- 使用DataView替代TypedArray,精确控制字节序
- 数值格式化在客户端完成,减轻下位机计算负担
- 单精度浮点转换避免JavaScript精度丢失问题
效果展示
上位机:微信小程序
下位机
遇到的难题与解决办法
问题:nRF52833的Arduino环境编程报错,Error: No J-Link device found
在使用Arduino对nRF52833编程时,发现烧写程序时,报错OpenOCD找不到Jlink,但是在任务管理器中可以看到JLink设备。
解法
经过网上搜索,发现原因是 OpenOCD 对 JLink 的驱动兼容问题,我们需要把 JLink 原来的驱动更换为 WinUSB 驱动才可以被 OpenOCD 识别。
驱动管理软件的下载地址:https://visualgdb.com/UsbDriverTool/
活动感想
通过本项目实践,深入掌握了BLE GATT协议栈开发、微信小程序蓝牙API集成等关键技术。Qorvo DWM3001CDK优秀的射频性能确保了稳定的无线连接,Nordic成熟的SDK极大简化了外设驱动开发。在开发过程中,体会到物联网系统需要硬件、固件、移动端的紧密配合,每个环节的参数优化都能显著提升整体性能。
本项目可扩展为智能农业监测系统,通过增加气压、光照强度等传感器,配合云平台实现大范围环境监控。期待未来能基于该平台开发更多创新应用,推动物联网技术在实际场景中的落地。
特别地,感谢交流群里的大佬 qqice ,大佬为本次活动的开发板 DWM3001CDK 完善了Arduino适配,并记录提醒了nRF52833在使用Arduino框架开发过程中要特别注意的踩坑点,无形中帮我节省了很多时间,十分感谢!
感谢硬禾学堂和得捷电子联合举办的Funpack活动,祝硬禾的活动越办越好!