Modbus异常0x5如何处理
How to handle Modbus exception 0x5
我正在使用 Qt5 和 QModbusTcpClient
class 编写 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);
}
}
有时,当我从远程设备读取某些内容时,设备 returns 会发生异常 0x5。阅读 official Modbus documentation,在第 48 页我读到:
Specialized use in conjunction with programming
commands.
The server has accepted the request and is
processing it, but a long duration of time will be
required to do so. This response is returned to
prevent a timeout error from occurring in the
client. The client can next issue a Poll Program
Complete message to determine if processing is
completed.
[粗体是我的]
我找不到这个 "Poll Program Complete message" 的描述,似乎我必须用它来处理异常 0x5。
我是不是搜索错了?还有其他方法可以处理这个异常吗?
这取决于您使用的设备类型。您只需要遵循设备手册中针对此特定异常描述的逻辑即可。
大体上没有特殊的'Program Complete'事件。这意味着,因为它是为 0x5 - "Specialized use in conjunction with programming commands." 编写的。所以你只需要从你的设备中轮询(读取)一些标志,这意味着导致这个异常的设备内部进程已经完成。
举个例子,我在继电保护装置中遇到过这样的异常,是在写入故障记录的过程中发出的。我只是在一段时间内检查该记录是否准备就绪。
我正在使用 Qt5 和 QModbusTcpClient
class 编写 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);
}
}
有时,当我从远程设备读取某些内容时,设备 returns 会发生异常 0x5。阅读 official Modbus documentation,在第 48 页我读到:
Specialized use in conjunction with programming commands. The server has accepted the request and is processing it, but a long duration of time will be required to do so. This response is returned to prevent a timeout error from occurring in the client. The client can next issue a Poll Program Complete message to determine if processing is completed.
[粗体是我的]
我找不到这个 "Poll Program Complete message" 的描述,似乎我必须用它来处理异常 0x5。
我是不是搜索错了?还有其他方法可以处理这个异常吗?
这取决于您使用的设备类型。您只需要遵循设备手册中针对此特定异常描述的逻辑即可。
大体上没有特殊的'Program Complete'事件。这意味着,因为它是为 0x5 - "Specialized use in conjunction with programming commands." 编写的。所以你只需要从你的设备中轮询(读取)一些标志,这意味着导致这个异常的设备内部进程已经完成。
举个例子,我在继电保护装置中遇到过这样的异常,是在写入故障记录的过程中发出的。我只是在一段时间内检查该记录是否准备就绪。