赞
踩
目前在使用Qt的modbus模块做项目,在使用过程中发现有一些这样那样的问题或者知识点。下面做一些总结,或者说列举。看情况会持续增加:
1.QModbusRtuSerialMaster 在运行一段时间后会出现无法收发数据的情况,只有disconnectDevice()重新connectDevice()才可以。而且也没留个flush接口,所以挺无语的。。
----20211126,突然发现QSerialPort有个errorOccurred的信号,可能对于解决这个问题有效(至少可以用这个来检查设备的拔插)
connect(mSerialPort, &QSerialPort::errorOccurred, [=](QSerialPort::SerialPortError error){
qDebug() << "error:" << error;
if(error != QSerialPort::NoError)
{
closePort();
}
});
----20220914,目前项目上又用到了这个。本质上还是没找到解决的办法,目前用了个偏方:定时检查。比如说目前我设置轮询modbus从机的周期为500ms,那么正常情况下,大约1000ms内一定会收到读取回来的信号QModbusReply::finished。
因此,可以设置一个定时器,比如说设置超时时间为2000ms(具体时间要根据从机数量、波特率灵活设置),一旦超时,就对串口进行断开、连接处理。然后此计时器在接收到QModbusReply::finished时,重新计时。
如此,一旦 串口阻塞–》定时器没有重新计时–》定时器超时–》串口重启
2.关于超时以及重试次数的问题,
mMaster->setTimeout(200);
mMaster->setNumberOfRetries(1);
上面这两个函数就是设置超时和重试次数的,那么这两个参数的作用是什么呢?假设超时时间为m,重试次数为n,那么假如通讯完全失败的话,在你执行读取函数后的 m*(n + 1) 毫秒后,你会从reply那里收到一个超时错误返回。比如我上面就是 200 * (1 + 1) = 400 毫秒后收到一个超时错误。
别人做的关于modbus的一些总结
https://www.cnblogs.com/ioufev/articles/10830028.html
3.关于Modbus TCP的问题
在使用modbus tcp时,一个client貌似每次只能连接一个IP(一个设备),然后通过slaveID来读写寄存器。但是,假如我是连接到了一个局域网里面,这个局域网里面有好多slave等待我去读写,基本确定是通过轮询的方式去读写他们,那,我只能通过不断地连接、断开、连接断开各个IP,然后读写他们?这样(不断建立、断开TCP/IP连接)不会很耗时吗?
在RS485/422网络中,直接通过指定不同的slaveID就可以访问不同的设备寄存器了。
到底通过Modbus tcp轮询设备的正确方式是怎样的?
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。