请教一下在QT中开发modbus的问题

zhxc531 2021-12-08 17:34:10

       目前正在用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;
}

 

...全文
1570 2 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
「已注销」 2021-12-09
  • 打赏
  • 举报
回复 1

我以前QT用过libmodbus RS232没问题,你试试串口通信码率设置到最大,我用9600频繁收发出现过没响应的,改成115200就好了

zhxc531 2021-12-09
  • 举报
回复
@「已注销」 我现在就是用115200

16,822

社区成员

发帖
与我相关
我的任务
社区描述
Qt 是一个跨平台应用程序框架。通过使用 Qt,您可以一次性开发应用程序和用户界面,然后将其部署到多个桌面和嵌入式操作系统,而无需重复编写源代码。
社区管理员
  • Qt
  • 亭台六七座
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧