鸿蒙汽车仪表盘项目-软硬件通信

187 阅读7分钟

一,硬件端 - ESP32

定义MQTT通信的核心参数,包括代理服务器地址、客户端ID、认证信息及默认主题,用于建立设备与MQTT服务器的安全连接并指定数据交互的通道。这些配置为后续的发布/订阅功能提供了基础参数支持,确保设备能够正确接入物联网平台并进行双向通信。代码如下所示。

image.png

实现与MQTT代理服务器的连接和初始化,使用 Paho MQTT 客户端库进行通信。

mqtt_connect() 函数负责建立网络连接并配置MQTT客户端参数。

NetworkInit(&n) 初始化底层网络栈。

NetworkConnect(&n, MQTT_BROKER, MQTT_PORT) 连接到指定的MQTT服务器。

MQTTClientInit() 初始化MQTT客户端,分配发送和接收缓冲区(各4KB)。

MQTTConnect() 发送CONNECT报文,携带客户端ID、用户名和密码,并设置心跳间隔。如果连接成功,打印Connected to MQTT broker!;失败则返回错误码。代码如下所示。

image.png

实现消息发布功能,通过定义mqtt_publish() 函数来实现向指定主题发布JSON格式的消息。消息结构包含QoS级别(QOS0,最多一次)、负载数据和长度。MQTTPublish() 将消息发送到代理服务器,若失败则打印错误日志。代码如下所示。

image.png

实现消息订阅与回调处理功能,通过定义mqtt_receive_once() 实现了同步订阅并接收单条MQTT消息的功能。调用 MQTTSubscribe() 订阅主题,并注册回调函数 _once_mqtt_cb。在超时时间内循环检查标志位 g_sub_flag,若收到消息则退出等待。通过 MQTTUnsubscribe() 取消订阅。回调函数中会将消息内容拷贝到全局缓冲区 g_sub_msg,并解析JSON提取关键字段。最后返回动态分配的字符串,避免内存泄漏。代码如下所示。

image.png

定义extract_json_value() 函数实现JSON数据的解析,从MQTT消息中提取指定键值。先定位键名后的冒号。跳过空格和引号,记录值的起始位置。找到值结束符,计算长度并动态分配内存存储结果。返回堆内存指针,调用者需 free() 防止泄漏。代码如下所示。

image.png

最后定义测试函数并集成。mqtt_test() 是集成测试入口,验证连接和发布功能。调用 mqtt_connect() 建立连接,成功后发布在线状态消息。可在此函数中添加订阅逻辑,实现双向通信(如接收控制指令)。代码如下所示。

image.png

对编写好的代码添加到虚拟机的目录下进行编译。

image.png

image.png

编译后把这里面的bin文件保存在Windows环境下。启动并配置烧录工具,选择固件,对应于刚刚从虚拟机保存到本地的bin里面的文件,连接开发板进行烧录程序。

image.png

 

二,软件端-北向应用

在该部分,创建了一个MQTT客户端类 MQTTClient,采用单例模式确保全局唯一实例。通过静态方法 getInstance() 获取唯一实例,避免重复创建连接。构造函数接收配置参数(如URL、客户端ID、认证信息等),并初始化MQTT客户端。在 init() 方法中依次创建客户端、连接服务器、订阅主题并设置消息监听。代码如下所示。

image.png

定义了connectMqtt() 方法负责与MQTT服务器建立安全连接,支持超时设置和自动重连。通过connectTimeout来设置连接超时时间(默认30秒)。automaticReconnect表示启用断线自动重连。通过 sslOptions 配置服务端证书认证,确保通信安全。使用Promise处理连接结果,成功或失败时打印日志。代码如下所示。

image.png

定义subscribe() 和 messageArrived() 方法实现主题订阅和消息接收功能。通过 MqttSubscribeOptions 指定主题和服务质量(QoS)。通过messageArrived() 监听订阅主题的消息,接收成功后通过鸿蒙的 emitter 模块将消息内容发送到事件总线,供其他模块消费。如果出现错误,会捕获订阅或接收过程中的错误并打印日志。代码如下所示。

image.png

image.png

定义了pushMessage() 和 destroy() 方法分别实现消息发布和客户端资源清理。其中支持动态指定主题和QoS,默认使用初始化参数。发布结果通过Promise处理,打印成功或失败日志。并调用 destroy() 销毁MQTT客户端实例,并取消事件监听,防止内存泄漏。代码如下所示。

image.png

定义好了这个类后,便在首页中通过MQTTClient.getInstance() 创建了一个MQTT客户端实例,并配置了连接参数(服务器地址、客户端ID、认证信息等)。并且在 MQTTClient 类的 init() 方法中,会自动调用 connectMqtt() 和 subscribe(),完成与服务器的连接和主题订阅。代码如下所示。

image.png

在 Index 页面的 onPageShow() 生命周期中,注册了 EVENTID=1001 的事件监听器,用于接收MQTT消息。接收到的消息为JSON字符串(如 {"turnSignal":"left"} 或 {"temperature":"26"}),通过 JSON.parse 解析后,根据字段更新组件的状态变量。代码如下所示。

image.png

解析后的MQTT数据会直接驱动UI组件的状态变化,实现动态渲染。当收到 硬件传递过来的数据(如{"turnSignal":"left"})时,设置 leftTurnOn = true,触发UI更新。将数据传递给父组件实现数据同步。部分代码如下所示。

image.png

三,软硬件通信

硬件端通过MQTT协议向MQTT服务器发布传感器数据(如温度、转向灯状态),软件端(鸿蒙应用)通过MQTTClient类订阅相同主题接收数据。鸿蒙应用使用emitter事件总线将接收到的JSON格式数据解析后更新UI组件的状态变量,从而实时渲染对应的界面元素(如转向灯图标、温度显示)。同时,用户通过UI按钮触发的操作(如切换驾驶模式)也可以通过MQTT反向发送指令到硬件端,实现双向通信。整个流程基于MQTT的发布/订阅模式,通过云端中转实现跨平台的软硬件数据交互。

打开开发板串口进行运行,运行后可以通过串口调试工具SSCOM显示初始化日志,包括WiFi连接成功、MQTT代理服务器连接成功,以及传感器数据采集。这些数据是通过MQTT协议发布到云端服务器。

image.png

  也可以通过MQTT的软件来进行信息的查看,通过订阅相同的主题,接收硬件发送的JSON格式数据,并解析后更新UI界面。整个通信过程基于MQTT的发布/订阅模式,通过云端中转数据,完成硬件传感器与软件界面的实时同步。

image.png

image.png

四,总结

本次项目让我对鸿蒙物联网系统的开发有了更深入的理解。通过实践掌握了OpenHarmony环境搭建、南北向通信设计等关键技术点。在硬件端,我学会了如何使用ESP32开发板通过GPIO和ADC与传感器交互,并通过MQTT协议实现数据上传。在软件端,理解了鸿蒙应用的UI设计与状态管理机制,特别是通过事件总线实现MQTT消息的解析与界面动态更新。整个项目中,我深刻体会到JSON数据格式在物联网通信中的重要性,以及如何通过发布/订阅模式实现软硬件解耦。同时,在调试过程中遇到的问题让我认识到代码健壮性的关键作用,比如内存管理、异常处理和网络重连机制。此外,团队协作开发的经验也让我明白文档规范和接口定义的重要性。