问题锁定
参考网友的思路:
Qt5.9 Modbus request timeout 0x5异常解决
- 网友认为是Qt的bug, 我也认同;
- 网友认为可以更新模块, 我也认同, 我也编译了Qt5.15.0的code并成功安装到Qt5.9.9中进行使用,界面拖动QModbusRTU离线问题解决!
Note: 为什么使用Qt5.15.0, 因为其他更高的版本改动较大,已经更Qt5.9.9差异变大了,移植到Qt5.9.9恐怕会有问题
编译Qt5.15.0 QSerialbus模块步骤
1. 下载QtSerialBus 5.15.0 模块, 只下载模块就好
https://mirrors.tuna.tsinghua.edu.cn/qt/official_releases/qt/5.15/5.15.0/submodules/
2. 解压,使用Qt Creator 打开里面的qtserialbus.pro, 点击编译, 编译之后报错如3
3. 错误罗列如下
- Qt::hex 全局替换成 hex
- Qt::endl 全局替换成endl
- Qt:: hex 全局替换成hex
- qmodbustcpclient_p.h
cpp
setupTcpSocket() 中 &QAbstractSocket::errorOccurred 改为-》
static_cast<void(QAbstractSocket::*)(QAbstractSocket::SocketError)>(&QAbstractSocket::error)
- qmodbusserver.cpp
增加头文件
cpp
#include <bitset>
QModbusServerPrivate::readBits 函数内
cpp
// Using byteCount * 8 so the remaining bits in the last byte are zero
QBitArray bytes(byteCount * 8);
address = 0; // The data range now starts with zero.
for ( ; address < count; ++address)
bytes.setBit(address, unit.value(address));
QByteArray payload = QByteArray::fromRawData(bytes.bits(), byteCount);
payload.prepend(char(byteCount));
return QModbusResponse(request.functionCode(), payload);
替换成
cpp
address = 0; // The data range now starts with zero.
QVector<quint8> bytes;
for (int i = 0; i < byteCount; ++i) {
std::bitset<8> byte;
// According to the spec: If the returned quantity is not a multiple of eight,
// the remaining bits in the final data byte will be padded with zeros.
for (int currentBit = 0; currentBit < 8; ++currentBit)
byte[currentBit] = unit.value(address++); // The padding happens inside value().
bytes.append(static_cast<quint8> (byte.to_ulong()));
}
return QModbusResponse(request.functionCode(), byteCount, bytes);
4. 最终编译, 编译通过, 在项目中添加install指令使模块安装到Qt5.9.9中
执行即可, 或创建新的编译, 最后再检查是否更新到Qt5.9.9的模块中了!
如下代表着有新的Qt5.15.0的QSerialbus库安装到Qt5.9.9中了
Note: 注意编译流程和安装流程是否有错, 要排错, 否则不一定完整安装!