QModbusTcpClient像QTcpSocket一样,首先得连接到相应的服务器,通过setConnectionParameter函数设置要连接的ip和端口号,设置超时值,和服务器没有回应时的重发次数,最后连接上去即可,如下
modbusClient = new QModbusTcpClient(this);
//连接状态发生改变时处理函数(connect or discennect)
modbusClient->setConnectionParameter(QModbusDevice::NetworkAddressParameter, ui->ip->text());
modbusClient->setConnectionParameter(QModbusDevice::NetworkPortParameter, ui->port->text().toInt());
modbusClient->setTimeout(500);
modbusClient->setNumberOfRetries(3);//服务器没有回应的重发次数
modbusClient->connectDevice();//
判断QModbusTcpClient有没有连接上服务器,使用它的信号判断即可
connect(modbusClient, &QModbusClient::stateChanged, this, &Widget::onStateChanged);
void Widget::onStateChanged(QModbusDevice::State newState)
{
if (newState == QModbusDevice::ConnectedState) {
qDebug()<<"QModbusDevice连接成功";
ui->send->setDisabled(false);
// 连接成功
} else if (newState == QModbusDevice::UnconnectedState) {
// 连接断开
qDebug()<<"QModbusDevice连接断开";
ui->send->setDisabled(true);
}
}
数据的封装采用QModbusDataUnit进行,然后将这个对象丢给QModbusClient的接口发送给服务器
QModbusClient默认构造
QModbusDataUnit(寄存器类型, 寄存器地址, 寄存器数量)
QModbusDataUnit(QModbusDataUnit::RegisterType type, int address, quint16 size)
编码转换后发送给服务端
QModbusReply *QModbusClient::sendWriteRequest(const QModbusDataUnit &write, int serverAddress)
第一个参数为已封装的数据unit,第二个参数为设备地址,根据文档或者询问厂家即可
void Widget::sendWriteRequest(QModbusDataUnit &unit, int address)
{
qDebug() << "写数据内容为:" << unit.values();
auto *reply = modbusClient->sendWriteRequest(unit, address);
if (reply)
{
if (!reply->isFinished())
{
//完毕之后 自动触发槽函数
connect(reply, &QModbusReply::finished, this, [this, reply]{
if (reply->error() == QModbusDevice::ProtocolError)
{
qDebug()<<QString("Write Protocaol response error: %1").arg(reply->errorString());
}
else if (reply->error() != QModbusDevice::NoError)
{
qDebug()<<QString("Write response error: %1").arg(reply->errorString());
}
else
{
qDebug() << "写响应的数据: " << reply->result().values();
}
reply->deleteLater();
});
}
else
{
//广播消息 不需要返回响应
reply->deleteLater();
}
}
else
{
qDebug()<<QString(("Write Error: ") + modbusClient->errorString());
}
}