16,822
社区成员




目前正在用QT的做modbus的一些东西,遇到不少问题,有几个问题一直没有办法解决.
首先是用的QT的modbus库,用rs485工作在主机端,控制3个松下A6伺服电机的驱动,如果只通讯一个设备就还好,或者是一条指令读同一个设备连续的多个地址也是可以的。
但是通讯多个设备就不行了,我干脆另外接了一条rs485线来监控,发现:
1.单一个指令发出,回复正常。
2.控制第一个设备的指令发出,如果继续发第二个设备,会出现第一个设备的回复在第二个以后,连续发第三个设备就会得不到第二个设备的回复。
3.同一个设备单独读一个地址的寄存器是正常的,或者连续读同一个地址连续的地址也是正常的,但是如果连续读同一设备不同地址的话就不正常了。
4.我加了延时,发现控制每个个设备的指令发出间隔1.2秒以后,就正常。但我确定收到指令处理完成后用的是deleteLater();
实在是无果后,我干脆不用QT的库,换了libmodbus库,却出现以下的问题:
1.单一个指令发出设备不回复,要发第二次才回复。
2.连续读取3个设备的话,每个设备要重复发2~3次才能有回复,而到第三设备就没有回复。
我更换了rs485线依然一样,然后我用串口助手就可以正常收发,确定是软件的原因。
于是我加大了响应时间依然无果,也尝试了加大字节响应也是一样
以下是QT的modbus库的读部分
void MainWindow::readmodbus(unsigned int startAddress,int number)
{
//如果没有定义modbus串口,直接返回
if (!modbustoo)
return;
// ui->readValue->clear();
//清空状态栏的显示
statusBar()->clearMessage();
//定义Modbus的基本数据单元,这里设置了modbus为0x03读模式,寄存器地址,以及传输数据的大小
//QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters,startAddress,num);
QModbusDataUnit readUnit(QModbusDataUnit::HoldingRegisters,startAddress,number);
//QModbusDataUnit readUnit(QModbusDataUnit::Coils,startAddress,number);
//发送Modbus格式的数据到从机地址为serverAddress的从机,读取相应的数据
//if(auto* reply = Master->sendReadRequest(readUnit,ServerAddress))
//获取设备地址
unsigned int serverAddress=ui->lineEdit_3->text().toInt();//ui->modbus_addr->text().toInt();
if (auto *reply = modbustoo->sendReadRequest(readUnit, serverAddress)) {
if (!reply->isFinished())
//如果有响应信息了,进入readReady函数处理接收到的数据
connect(reply, &QModbusReply::finished, this, &MainWindow::readReady);
else
//如果多次发送后没有响应,结束
delete reply; // broadcast replies return immediately
} else {
//如果发送失败,更新状态栏信息
statusBar()->showMessage(tr("读取失败: ") + modbustoo->errorString(), 5000);
}
}
下面是libmadbus在QT中的读取部分
bool MainWindow:: read_adder(int drvier,int nb)
{
int ret=0;
ret = modbus_set_slave(ctx, drvier);
if (-1 == ret)
{
fprintf(stderr, "Error: 设置从机地址失败\n");
return 0;
}
int t=0;
while (t!=link_num)
{
int i;
ret = modbus_read_registers(ctx, 0x4202, nb, tab_r); //modbus_read_registers 0x03指令
if (ret != nb)
{
qDebug()<<QString::number(ret);
qDebug()<<"err";
return 0;
}
else
{
for ( i = 0; i < nb; i++)
{
printf("reg[%d] = %d", i, tab_r[i]);
qDebug()<<QString::number(tab_r[i]);
}
}
t++;
}
return true;
}