拓冰建站拓冰建站
首页 / 资讯中心 / 正文

基于Hi3861与鸿蒙的工业物联网终端设计:井下环境监测实战

1. 项目缘起为什么是Hi3861与鸿蒙最近在做一个挺有意思的工业物联网项目客户的需求是在煤矿井下部署一套环境监测系统实时采集瓦斯浓度、温湿度、一氧化碳等关键数据并上传到地面监控中心。这个场景听起来简单但实际落地时选型和设计上的坑一个接一个。最核心的矛盾在于井下环境复杂对设备的功耗、体积、通信稳定性和成本都有近乎苛刻的要求同时还要考虑未来系统的可扩展性和维护便利性。传统的方案要么是用有线RS485/以太网布线成本高、灵活性差要么是用Zigbee/LoRa这类低功耗广域网但网关部署和网络管理又是麻烦事。我们团队评估了一圈最终把目光锁定在了WiFi方案上。你可能要问井下WiFi信号能行吗实际上现在很多现代化矿井都部署了工业级的本安型WiFi网络作为人员定位、通信和部分数据传输的基础设施信号覆盖已经不是大问题。关键在于我们需要一个能无缝接入现有WiFi网络且足够“轻量”的终端节点。这就是Hi3861进入我们视野的原因。它是一款基于RISC-V架构的WiFi SoC集成了完整的802.11b/g/n协议栈和丰富的接口GPIO, I2C, UART, ADC等最关键的是它原生支持鸿蒙OpenHarmony轻量系统。这意味着我们可以用一套统一的鸿蒙开发框架从设备端的嵌入式应用到手机/PC端的监控应用实现全栈开发极大地降低了开发和后期维护的复杂度。这个项目就是基于Hi3861 WiFi模组设计一个智能井下环境监测的终端节点并配套开发一个鸿蒙应用进行数据展示。2. Hi3861模组选型与核心能力拆解选型不能光看芯片型号得落实到具体的模组上。市面上基于Hi3861的模组不少我们最终选择了一款符合矿用本安要求的型号。这里重点不是推荐具体品牌而是分享选型时要关注的几个核心点这些点直接决定了后续开发的难易度和系统稳定性。2.1 硬件接口与供电设计Hi3861本身资源有限模组厂商的二次设计就至关重要。我们选的模组除了引出必要的UART、I2C和ADC接口用于连接传感器还内置了一个LDO稳压电路支持宽电压输入例如3.3V-5V。这对于井下设备非常重要因为供电线路长电压可能会有波动。模组本身的工作电流在WiFi活跃时峰值约200mA待机时能降到mA级以下配合合理的休眠策略用电池或本安电源供电是可行的。注意务必仔细阅读模组的数据手册确认其GPIO的驱动能力和电平标准。我们曾遇到过模组GPIO驱动电流不足无法直接驱动某些型号的传感器中间不得不加了一级三极管驱动电路增加了复杂度和故障点。2.2 内置的鸿蒙OpenHarmony LTS系统版本这是选择Hi3861模组的决定性因素。模组出厂时通常已经烧录了特定版本的OpenHarmony轻量系统固件。你需要确认这个版本比如是OpenHarmony 3.0 LTS还是3.2 LTS。不同版本的API和支持的组件可能有差异。我们的模组预装的是3.0 LTS这个版本对WiFi和Socket的网络支持已经比较稳定但像MQTT这样的高级网络组件需要自己移植或使用三方库。2.3 WiFi性能与天线设计井下环境金属设备多结构复杂对WiFi信号的衰减和反射很严重。因此模组的WiFi性能特别是接收灵敏度RX Sensitivity和天线设计是关键。我们选的模组采用了板载陶瓷天线并通过了相关射频认证。在实际部署前我们做了简单的穿透测试在模拟的金属巷道环境中模组与距离50米外的AP接入点仍能保持稳定的连接。当然实际矿井中需要专业的网络规划。3. 监测终端设计从传感器到数据帧终端设备的核心任务就三件事采集、处理、发送。下面我拆开来讲讲每个环节我们是怎么做的以及遇到的坑。3.1 传感器选型与驱动适配井下环境监测传感器的可靠性和精度是生命线。我们选用了催化燃烧式瓦斯传感器、电化学一氧化碳传感器和数字温湿度传感器。前两者输出通常是模拟量电流或电压后者通过I2C或UART数字接口通信。对于模拟量传感器Hi3861内置了12位ADC但精度和抗干扰能力需要仔细处理。我们在硬件上为每个模拟输入通道增加了RC滤波电路软件上则采用了中位值平均滤波算法。以下是ADC采样的一个核心代码片段#include ohos_init.h #include cmsis_os2.h #include hi_adc.h #define CHANNEL_NUM 0 // ADC通道号根据实际接线定义 #define NUM_SAMPLES 10 // 采样次数 static float ReadGasSensorValue(void) { unsigned int raw_value; float voltage; int samples[NUM_SAMPLES]; int i, j, temp; // 1. 多次采样 for (i 0; i NUM_SAMPLES; i) { hi_adc_read(CHANNEL_NUM, raw_value, HI_ADC_EQU_MODEL_1, HI_ADC_CUR_BAIS_DEFAULT, 0); // Hi3861 ADC参考电压通常为1.8V或3.3V需根据具体模组确定 // 假设参考电压Vref3.3V12位精度 voltage (raw_value * 3.3) / 4096.0; // 将电压值根据传感器数据手册转换为浓度值例如ppm // 此处简化处理实际需要校准曲线 samples[i] (int)(voltage * 1000); // 示例转换 osDelay(2); // 短暂延时避免采样过密 } // 2. 中位值平均滤波先排序去掉最大最小再平均 for (i 0; i NUM_SAMPLES - 1; i) { for (j 0; j NUM_SAMPLES - 1 - i; j) { if (samples[j] samples[j 1]) { temp samples[j]; samples[j] samples[j 1]; samples[j 1] temp; } } } int sum 0; for (i 1; i NUM_SAMPLES - 1; i) { // 去掉首尾最大最小值 sum samples[i]; } return sum / (NUM_SAMPLES - 2); }对于I2C温湿度传感器鸿蒙提供了//device/soc/hisilicon/hi3861v100/sdk_liteos/hardware/i2c的驱动接口但使用起来需要仔细配置时序。最大的坑在于有些传感器从机的应答速度慢需要调整I2C总线超时时间否则会一直返回失败。我们是在底层驱动里适当增大了超时阈值才解决的。3.2 数据协议设计与帧组装数据上传不能是乱流必须有固定的格式即协议。我们设计了一个简单的二进制协议兼顾了可读性和传输效率。一帧数据包括帧头、设备ID、数据体、校验和。#pragma pack(1) // 按1字节对齐避免结构体空洞 typedef struct { uint16_t header; // 帧头固定为0xAA55 uint8_t devId[6]; // 设备MAC地址作为ID uint32_t timestamp; // 时间戳 uint16_t gasConc; // 瓦斯浓度单位0.1%LEL int16_t temperature; // 温度单位0.1℃ uint16_t humidity; // 湿度单位0.1%RH uint16_t coConc; // CO浓度单位1ppm uint8_t battery; // 电池电量百分比 uint8_t rssi; // WiFi信号强度 uint16_t checksum; // CRC16校验和 } SensorDataFrame_t; #pragma pack()帧组装就是在内存中填充这个结构体。校验和我们用了CRC16-CCITT算法确保数据在传输过程中的完整性。这里有个细节结构体中的timestamp时间戳我们并没有使用Hi3861的RTC因为它没有独立的硬件RTC且断电会丢失而是在每次上电后通过NTP从服务器获取一次初始时间然后依靠系统tick来推算。虽然会有累积误差但对于非严格计时的环境监测可以接受。3.3 低功耗与任务调度策略井下设备很多地方无法方便取电低功耗设计是延长设备寿命的关键。Hi3861支持深度睡眠Deep Sleep但一旦进入深度睡眠WiFi连接会断开唤醒后需要重新关联网络耗时且耗能。我们的策略是采用“轻度休眠心跳上传”模式。我们创建了两个任务一个高优先级的数据采集处理任务一个低优先级的网络通信任务。系统大部分时间处于“空闲”状态由采集任务定时例如每10秒唤醒读取传感器数据并存入环形缓冲区。网络通信任务则以更长周期例如每60秒唤醒一次检查缓冲区是否有新数据如果有则组帧并通过WiFi发送。没有数据发送时WiFi模组会自动进入省电模式PS-Poll。这种设计在数据实时性和功耗之间取得了较好的平衡。4. 网络通信核心WiFi连接与MQTT封装这是项目中最具挑战性的部分之一。Hi3861的鸿蒙系统提供了基础的Socket API和WiFi连接管理API但直接使用Socket进行TCP通信并管理重连、心跳等逻辑非常繁琐。我们的目标是封装一个稳定、易用的MQTT客户端。4.1 WiFi连接与保活机制鸿蒙提供了//foundation/communication/wifi_lite组件用于WiFi操作。连接AP的基本流程是扫描 - 选择目标AP - 输入密码连接。但在工业环境网络可能不稳定必须要有自动重连机制。我们实现了一个WiFi管理状态机核心状态包括DISCONNECTED断开、SCANNING扫描、CONNECTING连接中、CONNECTED已连接、RECONNECTING重连中。在CONNECTED状态下我们会启动一个保活线程定期比如每30秒ping一下网关或者一个已知的服务器IP。如果连续多次ping失败则状态机自动跳转到RECONNECTING重新执行扫描和连接流程。实操心得不要一检测到断开就立刻重连最好加入一个随失败次数递增的延时例如1s, 2s, 4s, 8s...即“指数退避”算法。这能避免在AP短暂故障或信号瞬间不佳时设备频繁发起连接请求消耗电量并可能加重网络负担。4.2 MQTT客户端封装与选型OpenHarmony 3.0 LTS的标准库并没有提供MQTT客户端。我们有三个选择1. 自己基于Socket实现MQTT协议2. 移植一个开源的轻量级MQTT C库如Eclipse Paho MQTT C3. 使用厂商提供的SDK。自己实现协议栈工作量巨大且容易出bug首先排除。厂商SDK可能绑定特定云平台灵活性差。因此移植开源库是最佳选择。我们选择了Paho MQTT C的嵌入式版本MQTTClient-C它代码简洁依赖少非常适合Hi3861这种资源受限的设备。移植工作主要涉及以下几方面网络接口适配Paho库底层需要调用send()和recv()等Socket函数。我们需要实现一个Network结构体将其函数指针指向鸿蒙系统的Socket API。内存管理将库中动态内存分配malloc/free替换为鸿蒙的osMemoryAlloc/osMemoryFree或者直接使用静态内存池以提高确定性和避免内存碎片。定时器MQTT需要心跳保活库内部使用了定时器。我们需要实现一个基于鸿蒙osKernelGetTickCount的毫秒级定时器接口。日志输出将库中的printf调试信息重定向到鸿蒙的printf或自己的日志系统。封装后的MQTT客户端我们对外提供了几个简洁的接口// 初始化并连接MQTT服务器 int MQTT_ClientInit(const char* server_ip, int port, const char* client_id); // 订阅主题 int MQTT_Subscribe(const char* topic); // 发布消息 int MQTT_Publish(const char* topic, const char* payload, int qos); // 处理网络数据包和心跳需在主循环中定期调用 void MQTT_Yield(int timeout_ms); // 断开连接并释放资源 void MQTT_ClientDeinit(void);4.3 数据上传与服务器交互数据上传的Topic我们设计为/mine/env/{devId}/upload其中{devId}替换为设备的MAC地址。消息体就是前面组装的二进制帧但为了兼容性我们将其进行了Base64编码后再作为MQTT Payload发送。服务器Broker端订阅此Topic收到后解码、校验、解析并存入数据库。同时设备也订阅了一个命令Topic/mine/env/{devId}/cmd。服务器可以通过此Topic下发指令例如修改采集上传周期、请求实时数据、远程重启等。这实现了对设备的反向控制。5. 鸿蒙应用开发数据可视化与监控设备端的数据需要有一个直观的展示界面。我们利用鸿蒙的分布式能力和统一的开发框架开发了一个运行在手机或平板上的鸿蒙应用。这里主要分享几个关键点的实现。5.1 应用与设备的发现与绑定理想状态下鸿蒙设备之间可以通过软总线自动发现。但在我们的场景中井下监测终端数量多且网络环境复杂通过软总线直接发现并不稳定。我们采用了“云端中介”的模式设备上电连接MQTT后向一个特定的注册Topic如/mine/env/register发布自己的设备信息ID、名称、位置编码等。鸿蒙应用启动后同样连接MQTT服务器订阅注册Topic和所有设备的数据上传Topic可以使用通配符/mine/env//upload。应用收到注册消息后将设备添加到本地设备列表。用户可以在列表中选择需要重点监控的设备实现“逻辑绑定”。应用收到绑定设备的数据后进行解析和展示。5.2 数据解析与实时图表绘制应用端收到Base64编码的二进制数据后先解码再按照同样的结构体定义进行解析。这里要注意字节序Endian问题我们统一使用了小端序Little-Endian。对于数据展示我们使用了鸿蒙的Chart组件来绘制历史曲线图。由于鸿蒙应用开发框架ArkUI的Chart组件功能还在不断完善中我们遇到了一些性能问题。当需要同时展示多个传感器、且数据点较多例如一天的数据时直接渲染会导致UI卡顿。解决方案是进行数据采样和分页加载实时视图只显示最近1小时的数据并且每收到一条新数据就更新图表。历史视图当用户查看更长时间范围如一天时我们不将所有原始数据点都交给Chart组件而是在后端先进行降采样。例如对于一天86400秒的数据我们将其划分为1440个区间每分钟一个点取每个区间内的最大值、最小值、平均值三个点用“蜡烛图”的形式展示既能反映趋势又能看到波动范围同时数据量从86400个点减少到4320个点渲染压力大大降低。5.3 告警功能与分布式通知当解析到的瓦斯浓度、一氧化碳浓度超过安全阈值时应用需要立即告警。我们实现了两级告警应用内告警在应用界面顶部用红色横幅显示告警信息并播放告警音。分布式通知利用鸿蒙的分布式能力将关键告警信息同步到用户的其他鸿蒙设备上例如智能手表。即使手机应用不在前台用户也能通过手表震动及时感知。这里用到了鸿蒙的ohos.distributedNotificationManager模块。关键代码如下以JS/ETS为例import distributedNotificationManager from ohos.distributedNotificationManager; import common from ohos.app.ability.common; // 发布一个分布式通知 async function publishAlarmNotification(context: common.Context, alarmMsg: string) { let request: distributedNotificationManager.NotificationRequest { content: { contentType: distributedNotificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, normal: { title: 井下环境告警, text: alarmMsg, // ... 其他通知参数 } }, // ... 其他请求参数 }; try { await distributedNotificationManager.publish(request); console.info(Alarm notification published successfully.); } catch (err) { console.error(Failed to publish alarm notification. Code: ${err.code}, message: ${err.message}); } }6. 系统集成测试与井下部署要点实验室跑通只是第一步真正的考验在井下。我们总结了几个部署前后的关键测试点和注意事项。6.1 模拟环境压力测试在实验室我们搭建了一个简单的测试环境用金属柜模拟井下巷道将设备放入AP放在柜外。测试内容包括长时间稳定性测试让设备连续运行72小时以上观察是否有死机、内存泄漏、数据丢失等情况。我们通过日志发现运行约20小时后MQTT客户端偶尔会因网络抖动而进入一个错误状态无法恢复。最后发现是网络断连处理逻辑中没有正确重置某个内部状态标志修复后问题解决。网络异常测试手动开关AP模拟网络中断。检查设备重连机制是否有效重连后数据是否能续传我们设计了简单的本地缓存最多存50条数据网络恢复后优先发送缓存数据。多设备干扰测试同时让10台设备接入同一个AP频繁上报数据测试AP的带机量和网络拥堵情况下的数据丢包率。结果发现当所有设备同时以1秒为周期发送数据时丢包率显著上升。这促使我们将上报周期调整为错峰随机例如基准60秒加上一个-5到5秒的随机偏移有效降低了网络峰值压力。6.2 井下部署安装规范井下安装绝非简单地把设备挂墙上必须遵守安全规范。设备选型与认证所有下井的设备包括Hi3861模组、传感器、电源、外壳都必须具备“矿用产品安全标志证书”MA标志和“防爆合格证”。我们选用的整套设备是经过认证的本安型设备。安装位置瓦斯传感器应安装在巷道顶板下方距顶板不大于300mm距侧壁不小于200mm因为瓦斯比空气轻。一氧化碳和温湿度传感器的安装高度则根据其密度和监测需求而定。供电与布线电源必须来自矿井安全供电系统。信号线、电源线必须穿管保护接头处使用防爆接线盒。天线处理WiFi天线位置应尽量避开大型金属设备遮挡朝向AP方向。如果使用外置天线天线本身也需是防爆型。6.3 运维与远程诊断设备部署后运维同样重要。我们为设备端增加了几个远程诊断功能心跳与状态上报除了传感器数据设备定期如每10次数据上报一次发布状态信息到/mine/env/{devId}/status包含电池电压、信号强度RSSI、内部温度、运行时长、错误码等。远程日志级别调整通过命令Topic可以动态调整设备端的日志输出级别如DEBUG, INFO, ERROR。当某个设备出现问题时可以将日志级别调高获取更详细的运行信息辅助排查。固件远程升级OTA我们预留了OTA接口。服务器可以通过MQTT下发新固件的下载地址和校验码设备在空闲时下载、校验并写入备份分区下次重启时切换分区启动。这是保证系统长期可维护性的关键功能但第一次实现时要极其小心必须做好版本回滚和断电保护机制避免变“砖”。这个基于Hi3861和鸿蒙的智能井下监测系统从芯片选型到协议设计再到应用开发是一套完整的软硬件结合解决方案。它最大的优势不在于用了多高端的技术而在于用一套统一的、开源的鸿蒙生态将嵌入式端、通信端和应用端串联起来降低了长期的技术维护成本和人员学习成本。在实际项目中稳定性和可靠性永远是第一位的任何花哨的功能都必须为这两点让路。
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门