1. 项目介绍
本项目面向智能家居环境监测场景,使用 Arduino UNO R4 WiFi 作为主控与无线网关,通过 BLE 连接小米米家温湿度传感器 MJWSD06MMC,读取室内温度、湿度和传感器电池电压,并通过 WiFi 将数据上传至 OneNET 云平台,实现低成本、低布线复杂度的家庭环境远程监测。
本项目选择“智能家居 / 环境监测”作为设计方向。传统环境监测节点通常需要单独连接温湿度传感器模块,例如 DHT11、SHT30、AHT20 等;而米家温湿度传感器本身已经具备较好的外壳、显示、电池供电和低功耗 BLE 通信能力。因此本设计没有重复搭建温湿度采集硬件,而是将 Arduino UNO R4 WiFi 作为 BLE 到 WiFi 的桥接设备,把已有米家传感器的数据接入开放的物联网平台。
项目最终实现的功能包括:
- Arduino UNO R4 WiFi 连接家庭 WiFi 网络;
- 通过 BLE GATT 主动连接小米 MJWSD06MMC 温湿度传感器;
- 读取温度、湿度和电池电压数据;
- 通过 MQTT 接入 OneNET;
- 周期性上传
temp、humi、voltage三个物模型属性; - 使用 Arduino UNO R4 WiFi 板载 12x8 LED 点阵显示舒适度表情;
- 串口输出调试信息,便于观察 BLE 和 MQTT 连接状态。
2. 系统设计思路
系统整体由三部分组成:小米温湿度传感器、Arduino UNO R4 WiFi 网关、OneNET 云平台。
数据流如下:

Arduino UNO R4 WiFi 同时承担两个无线通信任务:一侧使用 ArduinoBLE 库作为 BLE Central,连接小米温湿度传感器;另一侧使用 WiFiS3 库连接路由器,并通过 OneNET SDK 将数据发布到云端。

实际抓到的广播包可以识别到设备地址和产品信息,例如设备名 MJWSD06MMC、MAC 地址 A4:C1:38:23:28:FA,但普通广播帧中没有携带明文温湿度 Object Data。因此最终改用 GATT 连接方式读取数据。
通过 BLE 调试工具和程序扫描确认,该传感器的温湿度数据位于以下 characteristic:
Service:
ebe0ccb0-7a0a-4b0c-8a1a-6ff2997da3a6
Characteristic:
ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6
该 characteristic 读取到的数据长度为 5 字节,格式如下:
byte[0..1] 温度,小端 int16,单位 0.01 摄氏度
byte[2] 湿度,uint8,单位 %
byte[3..4] 电池电压,小端 uint16,单位 mV
例如实测原始数据:
F4 0B 46 03 0C解析后为:
温度 = 0x0BF4 / 100 = 30.60 ℃
湿度 = 0x46 = 70 %
电压 = 0x0C03 = 3075 mV
3. 硬件与软件组成
硬件部分:
- Arduino UNO R4 WiFi;
- 小米米家温湿度传感器 MJWSD06MMC;
- WiFi 路由器;
- USB 数据线,用于供电、下载程序和串口调试。
软件与平台:
- Arduino IDE;
- ArduinoBLE 库;
- WiFiS3 库;
- Arduino_LED_Matrix 库;
- OneNET SDK;
- OneNET 物联网平台。
OneNET 端配置了三个物模型属性:
temp 温度
humi 湿度
voltage 电池电压
程序中对应上传:
OnenetSDK::send("temp", currentData.temp);
OnenetSDK::send("humi", currentData.humi);
OnenetSDK::send("voltage", currentData.voltage);
4. 程序实现
程序初始化阶段先连接 WiFi,然后初始化 OneNET SDK,最后启动 BLE 功能。BLE 连接成功后,程序查找指定 characteristic,并定时读取传感器数据。
为了让系统具备本地反馈能力,程序还使用 Arduino UNO R4 WiFi 板载 12x8 LED 点阵显示环境舒适度。每次成功读取温湿度后,程序根据当前温度和湿度判断人体舒适度,并刷新点阵表情。
舒适度判断规则如下:
20 ℃ <= 温度 <= 28 ℃ 且 40 % <= 湿度 <= 70 %:舒适
温度 > 28 ℃:偏热
温度 < 20 ℃:偏冷
湿度 < 40 %:偏干
湿度 > 70 %:偏湿
温度和湿度同时超出舒适范围:综合不适
点阵显示逻辑如下:
ComfortState state = getComfortState(currentData.temp, currentData.humi);
switch (state) {
case COMFORT_GOOD:
matrix.renderBitmap(faceGood, 8, 12);
break;
case COMFORT_HOT:
matrix.renderBitmap(faceHot, 8, 12);
break;
case COMFORT_COLD:
matrix.renderBitmap(faceCold, 8, 12);
break;
case COMFORT_DRY:
matrix.renderBitmap(faceDry, 8, 12);
break;
case COMFORT_HUMID:
matrix.renderBitmap(faceHumid, 8, 12);
break;
default:
matrix.renderBitmap(faceBad, 8, 12);
break;
}
关键的 BLE 数据解析代码如下:
int16_t tempRaw = data[0] | (data[1] << 8);
uint8_t humiRaw = data[2];
uint16_t voltageRaw = data[3] | (data[4] << 8);
currentData.temp = tempRaw / 100.0;
currentData.humi = humiRaw;
currentData.voltage = voltageRaw;
currentData.valid = true;
这段代码首先按照小端格式组合温度和电压数据。温度原始值单位为 0.01 ℃,因此需要除以 100;湿度本身是整数百分比;电池电压单位为 mV,可直接上传。
BLE 连接部分使用设备 MAC 地址进行过滤,避免误连接其他 BLE 设备:
const char *XIAOMI_ADDR = "a4:c1:38:23:28:fa";
const char *XIAOMI_DATA_CHAR_UUID =
"ebe0ccc1-7a0a-4b0c-8a1a-6ff2997da3a6";
当扫描到目标设备后,程序停止扫描并连接设备,随后执行 GATT 属性发现:
if (!dev.discoverAttributes()) {
Serial.println("Xiaomi discover attributes failed");
dev.disconnect();
return;
}
OneNET 上传部分采用定时发送方式,避免过于频繁地进行 MQTT 发布:
if (currentData.valid && now - lastUploadMs >= UPLOAD_INTERVAL_MS) {
lastUploadMs = now;
uploadToOnenet();
}
这样可以让 BLE 读取和 MQTT 上传保持相对独立,提高整体稳定性。
5. 实现结果
项目运行后,串口可以看到 WiFi、MQTT、BLE 和传感器数据的完整状态。一次成功运行的输出如下:
Connected to AP
MQTT Connected!
Subscribed: $sys/1V5P4PRH27/cool_car/thing/property/post/reply
Scanning Xiaomi sensor...
Xiaomi sensor found, connecting...
Xiaomi connected
Temp: 30.40 C, Humi: 70 %, Voltage: 3064 mV
说明系统已经完成以下链路:

实测数据稳定,温度、湿度、电池电压都能被正确解析。由于数据来自小米原厂传感器,硬件本身具备电池供电、低功耗和本地显示能力,Arduino 端无需额外布置温湿度传感器,整体结构更加简洁。

天气比较热,显示表情不开心。
云平台成功读取数据
6. 项目总结
本项目完成了一个基于 Arduino UNO R4 WiFi 的智能家居环境监测网关。项目的重点不在于单个温湿度传感器的采集,而在于将已有 BLE 智能设备接入开放云平台,实现不同生态之间的数据打通。
通过本次设计,可以看到 Arduino UNO R4 WiFi 同时具备 WiFi 和 BLE 能力,适合承担轻量级物联网网关角色。BLE 侧可以连接低功耗传感器,WiFi 侧可以接入 OneNET、MQTT 服务器或其他云平台。对于家庭环境监测、冰箱温湿度监测、仓储环境记录、桌面环境看板等应用,都可以在此基础上继续扩展。