QT技巧系列(8) QModbus发送汉字字符串的方法
Modbus 协议简介
Modbus 协议是应用于电子控制器上的一种通用语言。通过此协议,控制器相互之间、控制器经由网络(例如以太网)和其它设备之间可以通信。它已经成为一通用工业标准。有了它,不同厂商生产的控制设备可以连成工业网络,进行集中监控。
此协议定义了一个控制器能认识使用的消息结构,而不管它们是经过何种网络进行通信的。它描述了一控制器请求访问其它设备的过程,如果回应来自其它设备的请求,以及怎样侦测错误并记录。它制定了消息域格局和内容的公共格式。
当在一Modbus网络上通信时,此协议决定了每个控制器须要知道它们的设备地址,识别按地址发来的消息,决定要产生何种行动。如果需要回应,控制器将生成反馈信息并用Modbus协议发出。在其它网络上,包含了Modbus协议的消息转换为在此网络上使用的帧或包结构。这种转换也扩展了根据具体的网络解决节地址、路由路径及错误检测的方法。
我们直接用QModbus类,包含文件:
#include <QModbusRtuSerialMaster>
#include <QModbusDataUnit>
#include <QModbusTcpClient>
汉字字符串解析及转换发送的代码:
void shortInfoThread::on_writeTor(QString tin)
{
if (!modbusDevice)
return;
QByteArray str1 =tin.toUtf8().data();
int cnt = str1.size();
int tsize =0;
if (cnt % 2 == 0)
{
tsize =cnt /2 +1;
}else
tsize =cnt /2 +2;
QModbusDataUnit writeUnit = QModbusDataUnit(QModbusDataUnit::HoldingRegisters, 800, tsize);
//每2BYTE组成赋值给寄存器
for (int i=0; i< tsize -1; ++i)
{
ushort num =0;
if ((2*i+1) < str1.size()){
num = ((str1[2*i+1]) & 0x000000FF);
}else num =0;
num |= (str1[2*i] << 8) & 0x0000FF00;
writeUnit.setValue(i,num);
}
writeUnit.setValue(tsize-1,0);
if (auto *reply = modbusDevice->sendWriteRequest(writeUnit, 255)) { //1->modbus 地址
if (!reply->isFinished()) {
connect(reply, &QModbusReply::finished, this, [this, reply]() {
if (reply->error() == QModbusDevice::ProtocolError)
{
emit statusBar(tr("Write response error: %1 (Mobus exception: 0x%2)")
.arg(reply->errorString()).arg(reply->rawResult().exceptionCode(), -1, 16));
} else if (reply->error() != QModbusDevice::NoError)
{
emit statusBar(tr("Write response error: %1 (code: 0x%2)").
arg(reply->errorString()).arg(reply->error(), -1, 16));
}
qDebug()<<"write sucess!";
reply->deleteLater();
});
} else {
// broadcast replies return immediately
reply->deleteLater();
}
} else {
emit statusBar(tr("Write error: ") + modbusDevice->errorString());
}
}
这是项目中实际代码,仅供参考。
注:实战示例,解疑答惑。
--不间端地思考,实时地批判你的工作!