在qt中使用ZH-44043d采集器

news/2026/1/8 1:17:53/文章来源:https://www.cnblogs.com/Luy62/p/19447934

在qt中使用ZH-44043d采集器

在 Qt 中实现 RS485 通讯(与 ZH-44043D-14NI 采集器交互),核心是利用 Qt 的QSerialPort模块实现串口数据收发,并整合之前的 Modbus CRC16 算法完成指令封装与响应解析。下面是完整的实现步骤、代码示例和注意事项。
一、前期准备

  1. Qt 环境配置(关键)
    Qt 中操作串口需要依赖SerialPort模块,必须在项目的.pro文件中添加以下配置,否则无法编译通过:

QT += core gui serialport # 若为控制台项目,可去掉gui

其他原有配置(如SOURCES、HEADERS等)保持不变

  1. 硬件准备
    RS485 硬件:USB 转 485 模块(如 CH340/PL2303+485 转换芯片),或开发板自带 485 接口
    接线:模块D+对应采集器D+,模块D-对应采集器D-,确保供电与接地稳定
    串口参数:与采集器一致(115200 波特率、8 数据位、1 停止位、无校验、无流控)

二、核心实现步骤(Qt Widgets 示例)
步骤 1:包含必要头文件

include

include

include

include

include

include

// 提前声明CRC相关辅助函数(复用之前的C++算法)
uint8_t reverseByte(uint8_t byte);
uint16_t reverseWord(uint16_t word);
uint16_t calculateModbusCRC16(const uint8_t* data, uint16_t length);
void splitCRCToBytes(uint16_t crc, uint8_t& lowByte, uint8_t& highByte);

步骤 2:定义类成员变量(串口对象 + CRC 辅助函数)
在窗口类(如MainWindow)中定义私有成员变量,用于管理串口和数据:
class MainWindow : public QWidget
{
Q_OBJECT

public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();

private slots:
// 串口接收数据槽函数(响应readyRead()信号)
void onSerialPortReadyRead();
// 发送Modbus指令的槽函数(可绑定按钮点击)
void sendRead3rdCurrentCmd();

private:
QSerialPort *m_serialPort; // 串口对象指针
};

// 实现CRC辅助函数(与之前的C++算法完全一致,适配Qt)
uint8_t reverseByte(uint8_t byte) {
uint8_t reversed = 0;
for (int i = 0; i < 8; ++i) {
reversed |= ((byte >> i) & 0x01) << (7 - i);
}
return reversed;
}

uint16_t reverseWord(uint16_t word) {
uint16_t reversed = 0;
for (int i = 0; i < 16; ++i) {
reversed |= ((word >> i) & 0x0001) << (15 - i);
}
return reversed;
}

uint16_t calculateModbusCRC16(const uint8_t* data, uint16_t length) {
const uint16_t POLY = 0x8005;
uint16_t crc = 0xFFFF;

if (length == 0) return crc;for (uint16_t i = 0; i < length; ++i) {uint8_t reversedByte = reverseByte(data[i]);crc ^= (static_cast<uint16_t>(reversedByte) << 8);for (int bit = 0; bit < 8; ++bit) {if (crc & 0x8000) {crc = (crc << 1) ^ POLY;} else {crc <<= 1;}}
}crc = reverseWord(crc);
crc ^= 0x0000;
return crc;

}

void splitCRCToBytes(uint16_t crc, uint8_t& lowByte, uint8_t& highByte) {
lowByte = crc & 0xFF;
highByte = (crc >> 8) & 0xFF;
}

步骤 3:初始化串口(构造函数中)
配置串口参数并打开串口,关联readyRead()信号(有数据接收时触发槽函数):
MainWindow::MainWindow(QWidget *parent)
: QWidget(parent)
{
// 1. 初始化串口对象
m_serialPort = new QSerialPort(this);

// 2. 选择串口端口(需根据你的USB转485模块修改,如"COM3"、"/dev/ttyUSB0")
QString portName = "COM3";  // Windows示例,Linux请改为"/dev/ttyUSB0"
m_serialPort->setPortName(portName);// 3. 配置串口参数(匹配ZH-44043D-14NI)
m_serialPort->setBaudRate(QSerialPort::Baud115200);  // 115200波特率
m_serialPort->setDataBits(QSerialPort::Data8);       // 8数据位
m_serialPort->setStopBits(QSerialPort::OneStop);     // 1停止位
m_serialPort->setParity(QSerialPort::NoParity);      // 无校验
m_serialPort->setFlowControl(QSerialPort::NoFlowControl);  // 无流控// 4. 打开串口(只读/只写/读写,这里选读写)
if (m_serialPort->open(QSerialPort::ReadWrite)) {qDebug() << "串口打开成功:" << portName;// 5. 关联串口接收信号与槽函数connect(m_serialPort, &QSerialPort::readyRead, this, &MainWindow::onSerialPortReadyRead);
} else {qDebug() << "串口打开失败:" << m_serialPort->errorString();
}// 测试:发送读取第3路电流指令(可绑定按钮点击,这里直接调用演示)
sendRead3rdCurrentCmd();

}

MainWindow::~MainWindow()
{
// 关闭并释放串口
if (m_serialPort->isOpen()) {
m_serialPort->close();
}
delete m_serialPort;
}

步骤 4:封装并发送 Modbus 指令
实现发送读取第 3 路电流的指令,自动计算 CRC 并拼接完整帧:
void MainWindow::sendRead3rdCurrentCmd()
{
if (!m_serialPort->isOpen()) {
qDebug() << "串口未打开,无法发送指令";
return;
}

// 1. 准备指令前6字节(不含CRC):01 03 00 06 00 01
uint8_t cmdPrefix[] = {0x01, 0x03, 0x00, 0x06, 0x00, 0x01};
int prefixLen = sizeof(cmdPrefix);// 2. 计算Modbus CRC16
uint16_t crcValue = calculateModbusCRC16(cmdPrefix, prefixLen);
uint8_t crcLow, crcHigh;
splitCRCToBytes(crcValue, crcLow, crcHigh);// 3. 拼接完整指令(前6字节+CRC低位+CRC高位)
QByteArray sendData;
for (int i = 0; i < prefixLen; ++i) {sendData.append(static_cast<char>(cmdPrefix[i]));
}
sendData.append(static_cast<char>(crcLow));   // CRC低位:0x64
sendData.append(static_cast<char>(crcHigh));  // CRC高位:0x0B// 4. 发送指令到串口
qint64 sendLen = m_serialPort->write(sendData);
if (sendLen == -1) {qDebug() << "指令发送失败:" << m_serialPort->errorString();
} else {qDebug() << "指令发送成功,发送内容(十六进制):" << sendData.toHex(' ').toUpper();
}

}

步骤 5:接收并解析串口响应
实现onSerialPortReadyRead()槽函数,读取采集器返回的数据并解析:
void MainWindow::onSerialPortReadyRead()
{
// 1. 读取串口缓冲区所有数据
QByteArray recvData = m_serialPort->readAll();
if (recvData.isEmpty()) {
return;
}

// 2. 打印接收结果(十六进制格式,方便调试)
qDebug() << "收到响应(十六进制):" << recvData.toHex(' ').toUpper();// 3. 合法性校验(响应帧应为7字节:01 03 02 XX XX CRC1 CRC2)
if (recvData.length() != 7) {qDebug() << "响应帧长度异常,预期7字节,实际" << recvData.length() << "字节";return;
}// 4. 逐字节拆解响应(对应你的接收数据:01 03 02 00 00 B8 44)
uint8_t devAddr = static_cast<uint8_t>(recvData.at(0));       // 第1字节:设备地址(01)
uint8_t funcCode = static_cast<uint8_t>(recvData.at(1));      // 第2字节:功能码(03)
uint8_t dataLen = static_cast<uint8_t>(recvData.at(2));       // 第3字节:数据区长度(02)
uint8_t dataLow = static_cast<uint8_t>(recvData.at(3));       // 第4字节:数据低位(00)
uint8_t dataHigh = static_cast<uint8_t>(recvData.at(4));      // 第5字节:数据高位(00)
uint8_t recvCrcLow = static_cast<uint8_t>(recvData.at(5));    // 第6字节:响应CRC低位(B8)
uint8_t recvCrcHigh = static_cast<uint8_t>(recvData.at(6));   // 第7字节:响应CRC高位(44)// 5. 验证功能码(无错误,错误功能码为0x83)
if (funcCode != 0x03) {qDebug() << "采集器返回错误,功能码:" << QString::number(funcCode, 16).toUpper();return;
}// 6. 验证数据区长度(预期2字节,对应1个16位寄存器)
if (dataLen != 0x02) {qDebug() << "数据区长度异常,预期2字节,实际" << static_cast<int>(dataLen) << "字节";return;
}// 7. 计算响应数据的CRC(验证传输是否无误)
uint8_t crcCheckData[] = {devAddr, funcCode, dataLen, dataLow, dataHigh};
uint16_t crcCheckValue = calculateModbusCRC16(crcCheckData, sizeof(crcCheckData));
uint8_t checkCrcLow, checkCrcHigh;
splitCRCToBytes(crcCheckValue, checkCrcLow, checkCrcHigh);if (checkCrcLow != recvCrcLow || checkCrcHigh != recvCrcHigh) {qDebug() << "响应CRC校验失败,预期:" << QString::number(checkCrcLow, 16).toUpper()<< " " << QString::number(checkCrcHigh, 16).toUpper();return;
}// 8. 解析第3路电流值(核心计算)
uint16_t currentData = (static_cast<uint16_t>(dataHigh) << 8) | dataLow;  // 拼接16位数据(00 00 → 0)
float actualCurrent = static_cast<float>(currentData) / 10000.0f;         // 基础计算:DATA/10000// 补充:乘以你的采集器电流量程(如5A、10A,需根据实际配置修改)
float currentRange = 5.0f;  // 示例:5A量程,根据你的设备修改
actualCurrent *= currentRange;// 9. 输出最终结果
qDebug() << "第3路电流解析结果:";
qDebug() << "  寄存器原始值(十六进制):" << QString::number(currentData, 16).toUpper();
qDebug() << "  实际电流值(A):" << actualCurrent;

}

三、关键注意事项

  1. 串口端口选择
    Windows:在设备管理器中查看 USB 转 485 模块对应的 COM 口(如 COM3、COM4)
    Linux:查看/dev/ttyUSB或/dev/ttyACM,需赋予串口权限(sudo chmod 777 /dev/ttyUSB0)
    可通过QSerialPortInfo::availablePorts()枚举所有可用串口,方便用户选择。
  2. RS485 硬件适配
    Qt 仅负责软件串口数据收发,RS485 的差分信号转换由硬件完成(USB 转 485 模块)
    多设备组网时,需在总线两端添加 120Ω 终端电阻,避免信号反射
    通讯线使用屏蔽双绞线,远离强电磁干扰源(如变频器、电机)。
  3. 数据粘包处理
    若串口接收数据不完整或粘包,可添加延时读取(QTimer::singleShot)或帧尾判断(基于 Modbus 帧长度规则)
    示例中假设单次接收完整 7 字节响应,实际项目中可缓存接收数据,待数据长度达标后再解析。
  4. CRC 算法兼容性
    示例中复用了之前的 C++ CRC 算法,完全适配 Qt 的QByteArray数据格式,无需修改核心逻辑
    若需优化性能,可将 CRC 算法改为 Qt 风格(使用QVector替代原生数组),但功能完全一致。

总结
在 Qt 中使用 RS485 与 ZH-44043D-14NI 通讯的核心要点:
配置.pro文件引入serialport模块,是串口操作的前提;
用QSerialPort配置与采集器一致的串口参数,关联readyRead()信号接收数据;
复用 Modbus CRC16 算法完成指令封装与响应校验,确保通讯可靠性;
按照 Modbus-RTU 帧结构解析响应数据,结合采集器的参数计算规则得到实际测量值。

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

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

相关文章

AVIF格式Photoshop插件完整使用指南:快速实现高效图像压缩与HDR处理

AVIF格式Photoshop插件完整使用指南&#xff1a;快速实现高效图像压缩与HDR处理 【免费下载链接】avif-format An AV1 Image (AVIF) file format plug-in for Adobe Photoshop 项目地址: https://gitcode.com/gh_mirrors/avi/avif-format 还在为图像文件体积过大而影响工…

MPh革命性突破:Python驱动COMSOL实现智能化仿真工作流

MPh革命性突破&#xff1a;Python驱动COMSOL实现智能化仿真工作流 【免费下载链接】MPh Pythonic scripting interface for Comsol Multiphysics 项目地址: https://gitcode.com/gh_mirrors/mp/MPh 在工程仿真领域&#xff0c;传统手动操作模式正面临着前所未有的效率挑…

2026年青海政采云产品上传机构排行:政采云商品上传实力机构有哪些? - 工业品牌热点

TOP1 推荐:青海铃铛商务服务有限公司 推荐指数:★★★★★ 口碑评分:青海政采云产品上传领域标杆机构 专业能力:作为青海政采云服务赛道的深耕者,青海铃铛商务服务有限公司聚焦政采云产品上传全流程合规化与高效化…

主流支付宝消费券回收方式全解析 - 京顺回收

移动支付浪潮下,支付宝消费券闲置成了不少人的“甜蜜烦恼”。2025年,国内闲置消费券市场规模超500亿元,支付宝消费券占比超40%,这可不是个小数目!如何让这些“沉睡”的消费券“活”起来,实现权益最大化?别急,三…

3分钟搞定Figma中文界面:设计师必备的终极本地化方案

3分钟搞定Figma中文界面&#xff1a;设计师必备的终极本地化方案 【免费下载链接】figmaCN 中文 Figma 插件&#xff0c;设计师人工翻译校验 项目地址: https://gitcode.com/gh_mirrors/fi/figmaCN 还在为Figma的英文界面而烦恼吗&#xff1f;作为国内设计师&#xff0c…

DM数据库物理存储结构深度解析与理论实践

引言 DM&#xff08;达梦&#xff09;数据库作为国产数据库的标杆产品&#xff0c;其物理存储结构的设计直接决定了数据存储的安全性、可靠性和访问性能。物理存储结构是数据库底层数据组织的核心载体&#xff0c;包含配置文件、控制文件、数据文件、日志文件等多个关键组件&am…

Z-Image-Base模型性能瓶颈分析:哪些环节最耗资源?

Z-Image-Base 模型性能瓶颈深度剖析&#xff1a;哪些环节最耗资源&#xff1f; 在生成式 AI 快速渗透内容创作领域的今天&#xff0c;文生图模型已不再是实验室里的“黑科技”&#xff0c;而是设计师、艺术家甚至普通用户手中的生产力工具。然而&#xff0c;当我们试图在本地工…

让OneNote变身专业Markdown编辑器的完整指南

让OneNote变身专业Markdown编辑器的完整指南 【免费下载链接】NoteWidget Markdown add-in for Microsoft Office OneNote 项目地址: https://gitcode.com/gh_mirrors/no/NoteWidget 你是否曾经在OneNote中记录技术文档时感到力不从心&#xff1f;面对复杂的代码块、系统…

Z-Image-Edit自然语言编辑能力边界探索

Z-Image-Edit自然语言编辑能力边界探索 在电商运营的日常中&#xff0c;一张商品图可能需要反复修改十几次&#xff1a;换个背景、调下颜色、加个标语……传统流程里&#xff0c;这得靠设计师一遍遍打开 Photoshop。如今&#xff0c;只需一句“把模特身上的T恤换成蓝色&#xf…

2026年度圆锯机品牌商推荐供应商排行榜,节能型圆锯机供应商新测评精选 - mypinpai

为帮制造企业精准锁定适配产线需求的圆锯机合作伙伴,避免设备选型走弯路导致生产停滞、成本飙升,我们从设备核心精度(切割误差控制、长期稳定性)、智能适配能力(材料换型调试效率、数据联动性)、耗材成本可控性(…

扫路车专业厂家优质之选,程力专汽实力领航 - myqiye

在城市清洁和环卫作业领域,扫路车是不可或缺的重要装备。如何选购到一款好用、性价比高且靠谱的扫路车,成为众多采购者关注的焦点。今天,我们就来深入探讨扫路车专业厂家的相关信息,为大家的选购提供参考。 扫路车…

3分钟搞定Android Studio中文界面:新手必备的完整汉化指南

3分钟搞定Android Studio中文界面&#xff1a;新手必备的完整汉化指南 【免费下载链接】AndroidStudioChineseLanguagePack AndroidStudio中文插件(官方修改版本&#xff09; 项目地址: https://gitcode.com/gh_mirrors/an/AndroidStudioChineseLanguagePack 还在为Andr…

【JPCS出版 | EI检索】第五届能源利用与自动化国际学术会议(ICEUA 2026)

第五届能源利用与自动化国际学术会议(ICEUA 2026)计划于2026年1月30-2月1日在中国南京举行。【连续4届JPCS出版,EI稳定检索 | ICEUA 2025会后4个月EI检索】 第五届能源利用与自动化国际学术会议(ICEUA 2026) 2026…

2026年蝶阀市场新观察:哪些厂家表现亮眼?蝶阀/半球阀/三通球阀/气动调节阀/冶金阀门/调节阀,蝶阀工厂哪家强 - 品牌推荐师

行业趋势与市场格局:技术驱动下的蝶阀产业升级 随着工业4.0与绿色制造理念的深化,蝶阀市场正经历从传统机械控制向智能化、节能化转型的关键阶段。气动蝶阀作为核心产品,凭借快速响应、精准控制及适应高粉尘、高温等…

Coze AI Agent“智能体”工作流搭建全解析:一篇文章让你彻底明白!

一、前言 最近很多学生和朋友问我&#xff1a;如何用Coze搭建自己的AI智能体工作流程&#xff1f;想参加线上或者线下课学习。 今天花点时间跟大家讲讲如何使用Coze搭建自己的AI Agent&#xff01;接下来跟大家讲讲如何基于Coze搭建AI Agent(智能体)。 二、什么是Coze&#xf…

AI智能体应用架构全解析:从用户输入到生成回复,揭秘12个关键步骤与核心组件!

简介 本文详细解析了AI智能体应用架构的请求全流程&#xff0c;从用户输入问题到生成回复的12个关键步骤&#xff0c;包括API网关层、AI业务逻辑层、模型层、向量知识库层等核心组件的工作原理。通过流程图展示了AI智能体如何处理用户请求、进行向量化、知识检索、重排序以及工…

ZoteroTheme插件终极美化指南:深度定制文献管理界面

ZoteroTheme插件终极美化指南&#xff1a;深度定制文献管理界面 【免费下载链接】ZoteroTheme ZoteroTheme Plugin 项目地址: https://gitcode.com/gh_mirrors/zo/ZoteroTheme 厌倦了千篇一律的软件界面&#xff1f;想要打造专属的文献管理环境&#xff1f;ZoteroTheme插…

【程序员必看】VSCode后台智能体隔离技术:让编辑器提速300%

第一章&#xff1a;VSCode后台智能体隔离技术概述 VSCode 作为现代开发者的首选编辑器&#xff0c;其高性能与可扩展性得益于底层对后台任务的精细化管理。其中&#xff0c;后台智能体&#xff08;Background Agent&#xff09;隔离技术是保障主进程响应性与系统稳定性的核心机…

2026执业医师资格证考试资料推荐:高效冲刺攻略与高分资源盘点 - 品牌测评鉴赏家

2026执业医师资格证考试资料推荐:高效冲刺攻略与高分资源盘点一、医师资格证考试冲刺阶段核心难点解析 (一)考试特点与考生痛点 临床执业医师资格证考试为机考,含四大单元共600题,平均每题仅1分钟,时间紧张;近年…

2026年微信立减金回收回收平台大盘点 - 淘淘收小程序

数字权益的合理处置已成为当下必备的生活知识之一,各类支付场景中产生的立减金,若未及时运用便会面临失效风险。据统计,近六成的立减金因使用场景限制、有效期疏忽等原因闲置作废。了解立减金的科学处置方式,能有效…