一、终端节点功能设计
1. 功能说明
终端节点设计的是基于鸿蒙操作系统的 TCP 服务器程序,用于监测空气质量并提供远程控制功能。与之前的光照监测程序相比,这个程序使用 E53_SF1 模块(烟雾 / 气体传感器),主要功能包括:
空气质量监测:通过 MQ2 传感器检测有害气体浓度
自动报警:当气体浓度超过阈值时触发蜂鸣器报警
网络通信:
连接 WiFi 网络
建立 TCP 服务器监听客户端连接
实现自定义消息协议进行数据交换
远程控制:支持三种命令类型:
上传数据:返回气体浓度数据
控制命令:手动控制蜂鸣器
设置命令:调整气体浓度阈值和控制模式
2. 软硬件环境
终端节点采用BearPi-HM_Nano开发板
BearPi-HM_Nano开发板是一块专门为HarmonyOS设计的HarmonyOS开发板,板载高度集成的2.4GHz WLAN SoC芯片Hi3861,并板载NFC电路及标准的E53接口,标准的E53接口可扩展智能加湿器、智能台灯、智能安防、智能烟感等案例。
节点项目代码在鸿蒙的lite-os系统源码的sample目录下,完整路径如下:
~/lite-os-dev/bearpi-hm_nano/applications/BearPi/BearPi-HM_Nano/sample/D4_iot_tcp_server_sf1
代码工程目录如下,build.gn是编译配置文件,tcp_server_demo.c是主功能程序,E53_SF1.c程序实现节点数据采集功能,wifi_connect.c程序实现wifi网络通信基础功能。
3. 程序运行
程序下载到节点板卡后,通过type-c数据线接电脑,电脑接到板卡对应的串口终端,可看到调试运行信息。
节点串口显示节点分配到的IP地址:
飞腾派网络通信程序通过上述IP地址连接到终端节点:
节点串口显示接收到飞腾派的通信协议数据:
二、程序流程分析与设计
终端节点通过 "传感器数据采集→网络协议交互→自动 / 手动控制" 的闭环逻辑,实现了基于 TCP 协议的远程气体监测与报警系统。传感器数据通过自定义消息协议传输,支持远程设置报警阈值和手动控制报警装置,适用于智能家居或工业环境监测场景。
1. 系统初始化阶段
程序启动
系统通过
APP_FEATURE_INIT
宏自动调用TCPServerDemo
函数
TCPServerDemo
创建并启动TCPServerTask
线程
传感器初始化
调用Init_E53_SF1()初始化 E53_SF1 传感器模块
等待 1 秒(usleep(1000000))后进行传感器校准(MQ2_PPM_Calibration())
初始化全局变量:gas_max(气体浓度阈值,默认 100)、auto_control(自动控制标志,默认开启)
网络初始化
连接 WiFi 网络(SSID: "xxxx",密码: "xxxx")
创建 TCP 套接字,绑定到 8888 端口并开始监听
2. 主循环阶段
等待客户端连接
调用
accept
函数阻塞等待客户端连接连接建立后,获取客户端 IP 地址并打印日志
数据采集与命令处理循环
循环执行
e53_Task()
采集气体浓度数据调用
cmd_proc()
处理客户端发送的命令处理完成后休眠 1 秒,继续下一轮循环
连接管理
若
cmd_proc()
返回非 1 值(如连接断开或错误),退出内层循环关闭客户端套接字,返回外层循环等待新连接
3. 传感器数据采集与自动控制
数据采集
e53_Task()
调用Get_MQ2_PPM()
获取当前气体浓度打印气体浓度值到控制台
自动控制逻辑
当
auto_control
为 1 时,进入自动控制模式比较当前气体浓度与阈值
gas_max
若超过阈值,调用
Beep_StatusSet(ON)
开启蜂鸣器报警若低于阈值,关闭蜂鸣器
4. 命令处理流程
消息接收与解析
接收客户端发送的消息并复制到
Message
结构体调用
parse_message()
验证消息有效性:
检查帧头是否为
0xAA, 0x55
计算并验证校验和
根据消息类型执行不同操作
上传数据命令 (0x01):
将当前气体浓度转换为高低字节
封装响应消息(节点 ID: 0x02)
控制命令 (0x02):
设置
auto_control
为 0(关闭自动控制)根据命令参数手动控制蜂鸣器开关
设置命令 (0x03):
设置
auto_control
为 1(开启自动控制)更新气体浓度阈值
gas_max
发送响应
调用
pack_message()
封装响应消息打印响应消息内容(调试用)
通过
sock_fd
发送响应到客户端
5. 异常处理
连接断开处理
在
cmd_proc()
中,若recv()
返回值小于等于 0,判定为连接断开退出内层循环,关闭套接字,等待新连接
消息解析错误
若
parse_message()
返回非 0 值,打印错误信息并忽略该消息继续下一轮循环,等待新消息
三、程序功能分析与设计
1. 初始化与系统任务函数
TCPServerDemo()
功能:创建并启动 TCP 服务器任务线程
实现:
配置线程属性(名称、栈大小 10240 字节、优先级)
使用
osThreadNew
创建TCPServerTask
线程调用时机:通过
APP_FEATURE_INIT
宏在系统启动时自动初始化
TCPServerTask()
功能:TCP 服务器主任务,实现网络连接与数据交互
核心流程:
初始化 E53_SF1 传感器并校准
连接 WiFi 网络
创建 TCP 套接字,绑定端口 8888 并监听连接
循环接受客户端连接,处理数据交互
关键函数调用:
Init_E53_SF1()
、MQ2_PPM_Calibration()
、WifiConnect()
、cmd_proc()
2. 传感器数据采集与控制函数
e53_Task()
功能:读取气体传感器数据并实现自动报警控制
核心逻辑:
调用
Get_MQ2_PPM()
获取气体浓度(单位:PPM)若处于自动控制模式(
auto_control=1
),当浓度超过阈值gas_max
时触发蜂鸣器报警输出:打印气体浓度值到控制台
Init_E53_SF1()
功能:初始化 E53_SF1 传感器模块
调用时机:在
TCPServerTask
中服务器启动时执行
MQ2_PPM_Calibration()
功能:校准 MQ2 气体传感器
使用场景:传感器开机后需等待 1 秒(通过
usleep(1000000)
实现)再校准,确保数据准确性
Beep_StatusSet(Status status)
功能:控制蜂鸣器开关状态
参数:
ON
(开启)或OFF
(关闭)调用场景:自动报警或手动控制时执行
3. 网络通信与命令处理函数
cmd_proc(int new_fd)
功能:处理客户端命令并返回响应
核心流程:
接收客户端消息并解析
Message
结构体验证消息帧头和校验和(通过
parse_message
)根据消息类型(
msg_type
)执行不同操作:
0x01
(上传数据):返回气体浓度的高低字节
0x02
(控制命令):手动控制蜂鸣器
0x03
(设置命令):更新气体浓度阈值gas_max
封装响应消息并发送
关键变量:
recvbuf
(接收缓冲区)、response
(响应消息结构体)
WifiConnect(char *ssid, char *psk)
功能:连接指定 WiFi 网络
参数:WiFi 名称(
ssid
)和密码(psk
)调用时机:服务器启动时在
TCPServerTask
中执行
4. 消息协议处理函数
Message结构体
功能:定义通信消息格式
字段说明:
frame_header[2]
:帧头(固定为0xAA, 0x55
)
msg_type
:消息类型(上传 / 控制 / 设置)
node_id
:设备节点 ID(本程序中为0x02
)
data_len
:数据长度
data[10]
:数据内容
checksum
:校验和(通过异或运算生成)
calculate_checksum(Message *msg)
功能:计算消息校验和
实现:对消息所有字段(除校验和本身)进行异或运算
作用:确保消息传输的完整性
parse_message(Message *msg)
功能:解析并验证消息合法性
验证逻辑:
检查帧头是否为
0xAA, 0x55
计算校验和并与消息中的
checksum
对比返回值:
0
(成功)、-1
(帧头错误)、-2
(校验和错误)
pack_message(Message *msg, ...)
功能:封装响应消息
参数:消息类型、节点 ID、数据长度及内容
实现:填充消息结构体并计算校验和
调用场景:服务器向客户端返回响应时使用
print_message(Message *msg)
功能:调试时打印消息内容
输出:消息类型、节点 ID、数据长度及数据内容
5. 辅助工具函数
Get_MQ2_PPM()
功能:获取 MQ2 传感器的气体浓度值(单位:PPM)
返回值:浮点型浓度值
closesocket(int sockfd)
功能:关闭套接字连接
调用场景:客户端断开连接时释放资源
6. 函数调用关系总结
启动流程:
APP_FEATURE_INIT → TCPServerDemo → TCPServerTask
↳ Init_E53_SF1 + MQ2_PPM_Calibration(传感器初始化)
↳ WifiConnect(网络连接)
通信循环:
TCPServerTask → accept(等待客户端连接)
↳ e53_Task(定时采集传感器数据)
↳ cmd_proc(处理客户端命令)
↳ pack_message + send(返回响应)
协议处理:
cmd_proc → parse_message(解析请求)
↳ calculate_checksum(校验消息合法性)
↳ pack_message(构造响应)