一、终端节点功能设计

1. 功能说明

终端节点设计的是基于鸿蒙操作系统的 TCP 服务器程序,用于监测空气质量并提供远程控制功能。与之前的光照监测程序相比,这个程序使用 E53_SF1 模块(烟雾 / 气体传感器),主要功能包括:

空气质量监测:通过 MQ2 传感器检测有害气体浓度

自动报警:当气体浓度超过阈值时触发蜂鸣器报警

网络通信

  • 连接 WiFi 网络

  • 建立 TCP 服务器监听客户端连接

  • 实现自定义消息协议进行数据交换

远程控制:支持三种命令类型:

  • 上传数据:返回气体浓度数据

  • 控制命令:手动控制蜂鸣器

  • 设置命令:调整气体浓度阈值和控制模式

2. 软硬件环境

板卡详细开发说明:OpenHarmony轻量系统--BearPi-Nano开发板网络程序测试

终端节点采用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 服务器主任务,实现网络连接与数据交互

核心流程

  1. 初始化 E53_SF1 传感器并校准

  2. 连接 WiFi 网络

  3. 创建 TCP 套接字,绑定端口 8888 并监听连接

  4. 循环接受客户端连接,处理数据交互

关键函数调用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)

功能:处理客户端命令并返回响应

核心流程

  1. 接收客户端消息并解析Message结构体

  2. 验证消息帧头和校验和(通过parse_message

  3. 根据消息类型(msg_type)执行不同操作:

    • 0x01(上传数据):返回气体浓度的高低字节

    • 0x02(控制命令):手动控制蜂鸣器

    • 0x03(设置命令):更新气体浓度阈值gas_max

  4. 封装响应消息并发送

关键变量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(构造响应)

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/85547.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/85547.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/85547.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Plotly图表全面使用指南 -- Displaying Figures in Python

文中内容仅限技术学习与代码实践参考,市场存在不确定性,技术分析需谨慎验证,不构成任何投资建议。 在 Python 中显示图形 使用 Plotly 的 Python 图形库显示图形。 显示图形 Plotly的Python图形库plotly.py提供了多种显示图形的选项和方法…

getx用法详细解析以及注意事项

源码地址 在 Flutter 中,Get 是来自 get 包的一个轻量级、功能强大的状态管理与路由框架,常用于: 状态管理路由管理依赖注入(DI)Snackbar / Dialog / BottomSheet 管理本地化(多语言) 下面是 …

深度学习:人工神经网络基础概念

本文目录: 一、什么是神经网络二、如何构建神经网络三、神经网络内部状态值和激活值 一、什么是神经网络 人工神经网络(Artificial Neural Network, 简写为ANN)也简称为神经网络(NN),是一种模仿…

Unity2D 街机风太空射击游戏 学习记录 #12环射道具的引入

概述 这是一款基于Unity引擎开发的2D街机风太空射击游戏,笔者并不是游戏开发人,作者是siki学院的凉鞋老师。 笔者只是学习项目,记录学习,同时也想帮助他人更好的学习这个项目 作者会记录学习这一期用到的知识,和一些…

网站如何启用HTTPS访问?本地内网部署的https网站怎么在外网打开?

在互联网的世界里,数据安全已经成为了每个网站和用户都不得不面对的问题。近期,网络信息泄露事件频发,让越来越多的网站开始重视起用户数据的安全性,因此启用HTTPS访问成为了一个热门话题。作为一名网络安全专家,我希望…

计算机网络-----详解网络原理TCP/IP(上)

文章目录 📕1. UDP协议✏️1.1 UDP的特点✏️1.2 基于UDP的应用层协议 📕2. TCP协议✏️2.1 TCP协议段格式✏️2.2 TCP协议特点之确认应答✏️2.3 TCP协议特点之超时重传✏️2.4 TCP协议特点之连接管理✏️2.5 TCP协议特点之滑动窗口✏️2.6 TCP协议特点…

Lora训练

一种大模型高效训练方式&#xff08;PEFT&#xff09; 目标&#xff1a; 训练有限的ΔW&#xff08;权重更新矩阵&#xff09; ΔW为低秩矩阵→ΔWAB&#xff08;其中A的大小为dr, B的大小为rk&#xff0c;且r<<min(d,k)&#xff09;→ 原本要更新的dk参数量大幅度缩减…

蓝牙 5.0 新特性全解析:传输距离与速度提升的底层逻辑(面试宝典版)

蓝牙技术自 1994 年诞生以来,已经经历了多次重大升级。作为当前主流的无线通信标准之一,蓝牙 5.0 在 2016 年发布后,凭借其显著的性能提升成为了物联网(IoT)、智能家居、可穿戴设备等领域的核心技术。本文将深入解析蓝牙 5.0 在传输距离和速度上的底层技术逻辑,并结合面试…

Minio使用https自签证书

自签证书参考&#xff1a;window和ubuntu自签证书_windows 自签证书-CSDN博客 // certFilePath: 直接放在 resources 目录下 或者可以自定实现读取逻辑 // 读取的是 .crt 证书文件public static OkHttpClient createTrustingOkHttpClient(String certFilePath) throws Excep…

汽车前纵梁焊接总成与冲压件的高效自动化三维检测方案

汽车主体结构件上存在很多安装位&#xff0c;为保证汽车装配时的准确性&#xff0c;主体结构件需要进行全方位的尺寸和孔位置精度检测&#xff0c;以确保装配线的主体结构件质量合格。 前纵梁焊接总成是车身框架的核心承载部件&#xff0c;焊接总成由多片钣金冲压件焊接组成&a…

F接口基础.go

前言&#xff1a;接口是一组方法的集合&#xff0c;它定义了一个类型应该具备哪些行为&#xff0c;但不关心具体怎么实现这些行为。一个类型只要实现了接口中定义的所有方法&#xff0c;那么它就实现了这个接口。这种实现是隐式的&#xff0c;不需要显式声明。 目录 接口的定…

cartographer官方指导文件说明---第3章 cartographer前端算法流程介绍

cartographer官方指导文件说明 第3章 cartographer前端算法流程介绍 3.1 Scan Match扫描匹配 扫描匹配&#xff08;Scan Matching&#xff09;是 Cartographer 中实现局部SLAM的核心技术&#xff0c;它通过优化算法将当前激光扫描数据对齐到子图地图中。下面从计算过程、数学…

汽车整车厂如何用数字孪生系统打造“透明车间”

随着工业4.0时代的发展&#xff0c;数字孪生技术已成为现代制造业的重要利器。特别是在汽车整车厂&#xff0c;通过数字孪生系统的应用&#xff0c;能够有效打造一个“透明车间”&#xff0c;实现生产过程的全面可视化与实时监控&#xff0c;提高生产效率&#xff0c;降低成本&…

openKylin适配RISC-V高性能服务器芯片,携手睿思芯科共拓智算新蓝海

3月31日&#xff0c;睿思芯科&#xff08;深圳&#xff09;技术有限公司&#xff08;简称“睿思芯科”&#xff09;2025春季新品发布会在深圳前海国际会议中心盛大举行&#xff0c;作为RISC-V领域的年度盛事&#xff0c;此次发布会吸引了众多业内目光。此次发布会上&#xff0c…

【已解决】lxml.etree.ParserError: Document is empty

本专栏解决日常生活工作中非快速找到解决方案的问题。 问题背景 在爬取某网站时&#xff0c;使用开源框架报错&#xff1a;lxml.etree.ParserError: Document is empty 解决方案 1、多个搜索引擎中查找&#xff0c;建议都是对lxml的python源码进行修改&#xff0c;不好用。…

mac电脑调试iphone真机safari网页

mac电脑调试iphone真机safari网页 start 本文主要是记录一下如何调试苹果手机上的safari的网页 方法 1.苹果手机打开 web检查器 操作步骤&#xff1a; 打开设置搜索safari最底部“高级”开启“网页检查器” 2.mac电脑打开safari 操作步骤&#xff1a; 先用数据线连接手机和…

opencv依据图像类型读取图像像素点

Mat数据类型和通道对应的type()&#xff1a; 库类型C1C2C3C4CV_8U081624CV_8S191725CV_16U2101826CV_16S3111927CV_32S4122028CV_32F5132129CV_64F6142230 通过c程序查看类型并读取图像像素点&#xff1a; switch (im->type()){case 0:std::cout << "at (&quo…

软件架构的发展历程——从早期的单体架构到如今的云原生与智能架构

软件架构的发展历程是技术演进与业务需求相互驱动的结果&#xff0c;从早期的单体架构到如今的云原生与智能架构&#xff0c;每一步都在突破系统的可扩展性、灵活性和效率边界。以下是其核心发展脉络及未来趋势的全景解析&#xff1a; 一、发展历程&#xff1a;从单体到智能的…

Oracle 基础语句大全:从数据定义到复杂查询

一、DDL&#xff08;数据定义语言&#xff09;&#xff1a;定义数据库结构 1. 创建表&#xff08;CREATE TABLE&#xff09; -- 语法格式 CREATE TABLE [schema.]table_name (column1 datatype [CONSTRAINT constraint1],column2 datatype [DEFAULT default_value],-- 表级约…

【学习笔记】锁+死锁+gdb调试死锁

【学习笔记】锁死锁gdb调试死锁 一、互斥锁&#xff08;std::mutex&#xff09; 最基本的锁类型&#xff0c;提供排他性访问&#xff0c;同一时间仅允许一个线程持有锁。 #include <iostream> #include <mutex> #include <thread>std::mutex mtx; // 全局…