从0到1,我们一起调试温控仪表

2023-10-17 19:33
文章标签 调试 一起 温控仪

本文主要是介绍从0到1,我们一起调试温控仪表,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好,我是程序员小哈。
最近拿到客户买的一个温控仪表,让我编个软件,读取一下这个仪表的实时温度数据,今天我们就从0到1,看看小哈哥是怎么来实现这个功能的。

基本功能

拿到一个新的模块,首先我们要看的就是它的官方资料,本模块自带一个使用说明书,我们先对其整体进行一个大致的了解吧。

型号定义

首先我们看一下这个模块使用说明的手册中,它的型号定义由以下9部分组成:
image.png
具体的型号在模块的外壳上有具体标识:
image.png
两者对应一下,我们可以得出:
AI-标识仪表的型号,由此可以得出此模块的型号是AI-756P
SIZE,标识仪表面板的尺寸规格,A 对应的面板规格为96x96mm;
MIO,表示仪表辅助输入(MIO)安装的模块规格:可安装I4、K3、V等模块,N表示没有安装;
OUTP,仪表主输出安装的模块规格;
ALM,仪表报警安装的规格说明;
AUX,仪表辅助输出安装的模块规格;
COM,仪表通讯安装的模块规格;
POWER,仪表供电电源,此处没标,表示使用的100~240VAC电源;
⑨ 表示仪表扩充的分度表规格,如果没有,则不写。

接线方法

image.png
因为我们最终目标是读取仪表的实时温度,所以我们要了解一下如何与仪表进行数据通讯。
首先我们使用USB转485线与上图COMM口的③④位置相连,A对A,B对B。
① ② 位置接220V电源供电。
⑱⑲⑳位置接一个PT100用于测试使用。

通信协议

这个仪表支持两种通信协议,一个是自己公司的通讯协议AIBUS,一个是兼容的Modbus协议。

自定义AIBUS通信协议

发送指令

: 地址代号+52H(82)+要读的参数代号+00+00+校验码
: 地址代号+43H(67)+要写的参数代号+写入数低字节+写入数高字节+校验码

说明
(1)地址代号:两个相同的字节,数值为(仪表地址+80H)

例如:仪表地址为10(16进制数表示为0AH,0A+80H=8AH),所以该仪表的地址代号为:8AH 8AH。

(2)参数代号:相当于命令类型,由一个字节表示
image.png
(3)校验码
读指令校验码:参数代号256+82+ADDR
写指令校验码:参数代号
256+67+写入的参数值+ADDR
求得的和与0xFFFF取余数,余数为2个字节,低字节在前,高字节在后。

测试指令:81 81 52 00 00 00 53 00

返回数据

无论读还是写,仪表都返回以下10个字节数据:
测量值 PV+给定值 SV+输出值 MV 及报警状态+所读/写参数值+校验
说明
**(1)、**PV、SV及读取的参数值均各占2个字节,是一个16位有符号补码的整数,低位字节在前,高位字节在后
**(2)、**返回校验码:为 PV+SV+(报警状态*256+MV)+参数值+ADDR 按整数加法相加后得到的余数。

注意:我手里的仪表型号为S7,经过咨询官方,此型号的模组不支持自定义的AIBUS协议。。

MODBUS兼容通信协议

AI 仪表采用 RTU(二进制)模式, 波特率必须设置为 9600bit/S,无奇偶校验位,支持 03H(读参数及数据)及 06H(写单个参数)这两条指令。

读指令

读数据要求一次性读取4个字节数据,指令如下:
**ADDR+03H+00+要读的参数代号+00+04+CRC 校验码 **
返回数据为:ADDR+03H+08H+测量值 PV 高位+测量值 PV 低位+给定值 SV 高位+SV 低位+报警状态+输出值 MV+所读参数值高位+所读参数值低位+CRC 校验码低位+CRC 校验码高位

例如可以发送:01 03 00 01 00 04 15 C9

image.png

写指令

写单个参数指令为:
**ADDR+06H+00+要写的参数代号+要写入的数据高位+要写入数据低位+CRC 校验码 **

注意:仪表默认地址为0x01。

代码实现

我们之前分享过基于Qt开发的Modbus程序,我们今天就在之前的代码基础上完成此次测试。

首先G众号后台回复:Qt-Modbus 获取基础源码,然后我们将界面重新布局为如下效果:

image.png

这个程序是在串口事件中接收并处理数据,有时会出现串口数据分包的情况。
一帧数据接收不完整,我们就没办法直接对接收到的数据进行解析,今天我们对程序进行一下优化。
我们仿照之前分享的STM32进行串口数据接收的方法——定时器法,当串口事件响应时,我们启动一个短时间的定时器,因为一帧数据包内的数据,即使分包了,那么包与包之间的时间间隔也很短,所以,在串口事件中,我们启动定时器,相当于让定时器重新计时,这样,当不能再接收到数据时,那么定时器的超时事件就会发生,我们在定时器超时的函数中,对接收的数据进行解析,这样就能够避免分包导致的数据不完整,具体实现如下:

连接信号槽

我们在打开串口的事件函数中,定义一个串口接收事件的函数和一个定时器事件函数。

//连接信号槽 当下位机发送数据QSerialPortInfo 会发送个 readyRead 信号,我们定义个槽void receiveInfo()解析数据
connect(m_serialPort,SIGNAL(readyRead()),this,SLOT(receiveInfo()));timerSerial = new QTimer(this);
connect(timerSerial,SIGNAL(timeout()),this,SLOT(TimerUpdate()));

串口接收事件

在串口接收函数中,我们启动定时器,相当于重置定时器。

此定时器的时间,根据需要和实际情况,尽量短。

//重置定时器
void MainWindow::receiveInfo()
{timerSerial->start(100);
}

定时器超时事件中处理串口数据

在定时器超时函数中,我们关闭定时器,然后一次性读取所有的串口数据,进而对接收到的串口数据进行解析。

void MainWindow::TimerUpdate()
{timerSerial->stop();qDebug()<<"receiveInfo()";QByteArray info = m_serialPort->readAll();QString strReceiveData = "";QByteArray hexData = info.toHex();strReceiveData = hexData.toUpper();qDebug()<<"接收到串口数据: "<<strReceiveData;for(int i=0; i<strReceiveData.size(); i+=2+1)strReceiveData.insert(i, QLatin1String(" "));strReceiveData.remove(0, 1);qDebug()<<"处理后的串口数据: "<<strReceiveData;ui->txtReceiveData->append(strReceiveData);//对接收到的数据进行判断处理... ...
}

主要能拿到完整的串口数据,那么对数据的解析也就简单了。

有了上面的介绍,剩下的参数代码的功能,小伙伴们自己可以尝试实现一下。

结果展示

询问了官方,我用的AI-756P型号的仪表参考719P型号的仪表通信协议即可,我们要读取仪表的当前温度,即PV值,所以寄存器地址应该为0x02。
image.png

我们演示一下操作过程,我们可以看到,没有发生串口数据分包的现象。
Qt Modbus.gif

总结

今天主要分享一个小哈哥最近使用的仪表,大家看看有个印象就好,万一哪天需要类似产品,自己找起来也有个方向。
另外就是分享一个,如果遇到Qt接收数据包不完整的情况怎么办?
好了,今天的文章内容到这里就结束了,希望对你有帮助,我们下一期见,记得给小哈哥点个赞,支持一下哈!~

程序源码

大家感兴趣的话,可以从下面的百度网盘中获取本文测试工程源码及产品手册

链接:https://pan.baidu.com/s/1Zky2QE3ylHg5Xd5W1TD53w
提取码:0101

参考阅读

使用Qt打造属于自己的串口调试助手
Qt编写Modbus从机程序
上位机与STM32串口通信​

这篇关于从0到1,我们一起调试温控仪表的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/227490

相关文章

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

如何在Visual Studio中调试.NET源码

今天偶然在看别人代码时,发现在他的代码里使用了Any判断List<T>是否为空。 我一般的做法是先判断是否为null,再判断Count。 看了一下Count的源码如下: 1 [__DynamicallyInvokable]2 public int Count3 {4 [__DynamicallyInvokable]5 get

计算机毕业设计 大学志愿填报系统 Java+SpringBoot+Vue 前后端分离 文档报告 代码讲解 安装调试

🍊作者:计算机编程-吉哥 🍊简介:专业从事JavaWeb程序开发,微信小程序开发,定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事,生活就是快乐的。 🍊心愿:点赞 👍 收藏 ⭐评论 📝 🍅 文末获取源码联系 👇🏻 精彩专栏推荐订阅 👇🏻 不然下次找不到哟~Java毕业设计项目~热门选题推荐《1000套》 目录 1.技术选型 2.开发工具 3.功能

vscode中文乱码问题,注释,终端,调试乱码一劳永逸版

忘记咋回事突然出现了乱码问题,很多方法都试了,注释乱码解决了,终端又乱码,调试窗口也乱码,最后经过本人不懈努力,终于全部解决了,现在分享给大家我的方法。 乱码的原因是各个地方用的编码格式不统一,所以把他们设成统一的utf8. 1.电脑的编码格式 开始-设置-时间和语言-语言和区域 管理语言设置-更改系统区域设置-勾选Bata版:使用utf8-确定-然后按指示重启 2.vscode

起点中文网防止网页调试的代码展示

起点中文网对爬虫非常敏感。如图,想在页面启用调试后会显示“已在调试程序中暂停”。 选择停用断点并继续运行后会造成cpu占用率升高电脑卡顿。 经简单分析网站使用了js代码用于防止调试并在强制继续运行后造成电脑卡顿,代码如下: function A(A, B) {if (null != B && "undefined" != typeof Symbol && B[Symbol.hasInstan

php 7之PhpStorm + Nginx + Xdebug运行调试

操作环境: windows PHP 7.1.10 PhpStorm-2017.2.4 Xdebug 2.5.4 Xdebug helper 1.6.1 nginx-1.12.2 注意查看端口占用情况 netstat -ano //查看所以端口netstat -aon|findstr "80" //查看指定端口占用情况 比如80端口查询情况 TCP 0.0.0.0:8

跟我一起玩《linux内核设计的艺术》第1章(四)——from setup.s to head.s,这回一定让main滚出来!(已解封)

看到书上1.3的大标题,以为马上就要见着main了,其实啊,还早着呢,光看setup.s和head.s的代码量就知道,跟bootsect.s没有可比性,真多……这确实需要包括我在内的大家多一些耐心,相信见着main后,大家的信心和干劲会上一个台阶,加油! 既然上篇已经玩转gdb,接下来的讲解肯定是边调试边分析书上的内容,纯理论讲解其实我并不在行。 setup.s: 目标:争取把setup.

【2025】基于Python的空气质量综合分析系统的设计与实现(源码+文档+调试+答疑)

博主介绍:     ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W+粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台的优质作者。通过长期分享和实战指导,我致力于帮助更多学生完成毕业项目和技术提升。 技术范围:     我熟悉的技术领域涵盖SpringBoot、Vue、SSM、HLMT

VS Code 调试go程序的相关配置说明

用 VS code 调试Go程序需要在.vscode/launch.json文件中增加如下配置:  // launch.json{// Use IntelliSense to learn about possible attributes.// Hover to view descriptions of existing attributes.// For more information,