我正在使用Qt5和QModbusTcpClient
类编写Modbus客户端程序。这是我用来打开连接并阅读内容的代码:
QModbusClient *_modbus;
bool ModbusMaster::open(QString host, int port)
{
// Disconnect and delete any existing instance
if (_modbus)
{
_modbus->disconnectDevice();
delete _modbus;
}
// Create and open the new connection
_modbus = new QModbusTcpClient(this);
_modbus->setConnectionParameter(QModbusDevice::NetworkPortParameter, port);
_modbus->setConnectionParameter(QModbusDevice::NetworkAddressParameter, host);
_modbus->setTimeout(250);
_modbus->setNumberOfRetries(1);
return _modbus->connectDevice();
}
bool ModbusMaster::read(QModbusDataUnit::RegisterType type, int startAddress, quint16 count)
{
if (!_modbus) return false;
if (_modbus->state() != QModbusDevice::ConnectedState) return false;
QModbusDataUnit req(type, startAddress, count);
if (auto *reply = _modbus->sendReadRequest(req, _id))
{
if (!reply->isFinished()) connect(reply, &QModbusReply::finished, this, &ModbusMaster::readReady);
else delete reply;
return true;
}
return false;
}
void ModbusMaster::readReady()
{
auto reply = qobject_cast<QModbusReply *>(sender());
if (!reply) return;
reply->deleteLater();
if (reply->error() == QModbusDevice::NoError)
{
// do something
}
else if (reply->error() == QModbusDevice::ProtocolError)
{
qDebug() << QString("Read response error: %1 (Mobus exception: 0x%2)").
arg(reply->errorString()).
arg(reply->rawResult().exceptionCode(), -1, 16);
} else {
qDebug() << QString("Read response error: %1 (code: 0x%2)").
arg(reply->errorString()).
arg(reply->error(), -1, 16);
}
}
有时,当我从远程设备读取内容时,设备会返回异常0x5。读official Modbus documentation,在第48页,我读到:
结合编程的专门用途 命令。 服务器已接受该请求,并且 处理它,但是会持续很长时间 必须这样做。此响应返回到 防止发生超时错误 客户。 客户接下来可以发布投票计划 完整的消息,以确定是否正在处理 完成。
[大胆是我的]
我找不到此“轮询程序完成消息”的描述,似乎我必须使用它来处理异常0x5。
我搜索错了吗?还有另一种方法可以处理此异常吗?
答案 0 :(得分:1)
这取决于您使用的设备的类型。您只需要遵循设备手册中针对此特殊异常所描述的逻辑即可。
通常没有特殊的“程序完成”事件。这就是说,因为它是为0x5编写的-“与编程命令一起专门使用”。因此,您只需要轮询(读取)设备中的一些标志,这意味着导致此异常的设备内部过程已完成。
仅作为示例,我在继电保护装置中遇到了这样的异常,该异常是在其正在编写故障记录的过程中发出的。我只需要一段时间检查一下记录是否准备就绪。