Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-91037

MODBUS custom command doesn't work

    XMLWordPrintable

Details

    • Windows
    • 2c0bb738e988d84f36169e0103d051745b678479 (qt/qtserialbus/dev) 17ac276e9b4fcde0f2e2b9a68a01ef6cdde31cf5 (qt/tqtc-qtserialbus/tqtc/lts-5.15)

    Description

      I'm trying to create a custom modbus command. The command is being sent and then received on the other side, the reply is sent back but I always receive an empty invalid reply. The same problem was discussed here - https://bugreports.qt.io/browse/QTBUG-62192
       

      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          QObject *connector = new QObject();
      
          QModbusTcpClient *client = new QModbusTcpClient();
          client->setConnectionParameter(QModbusDevice::NetworkAddressParameter, "127.0.0.1");
          client->setConnectionParameter(QModbusDevice::NetworkPortParameter, 8899);
          client->connectDevice();
      
          QModbusResponse::registerDataSizeCalculator(QModbusPdu::CustomFun_ReadData, [](const QModbusResponse &)-> int
          {
              qInfo() << "Custom data size calculator"; // this line wasn't printed out
              return 42;
          });
      
          connector->connect(client, &QModbusClient::stateChanged, connector, [connector, client]()
          {
              if(client->state() == QModbusClient::ConnectedState)
              {
                  auto cmd = QModbusPdu::FunctionCode(QModbusPdu::CustomFun_ReadData);
                  QModbusRequest request(cmd);
                  qInfo() << "Is request valid? " << request.isValid(); // true
                  QModbusReply* reply = client->sendRawRequest(request, 1);
                  qInfo() << "Reply is null: " << (reply == nullptr); // false
                  qInfo() << "Is response valid? " << reply->rawResult().isValid(); // false, we didn't get it yet
       
                  connector->connect(reply, &QModbusReply::finished, connector, [reply]()
                  {
                      qInfo() << "isFinished? " << reply->isFinished(); // true
                      qInfo() << "Is response valid? " << reply->rawResult().isValid(); // false, even though reply finished
                      qInfo() << "Raw result fun code: " << reply->rawResult().functionCode(); // 0
                      qInfo() << "Error? " << reply->errorString(); // ""
                      qInfo() << "Reply data size: " << reply->rawResult().dataSize(); // 0
                      qInfo() << "Reply size: " << reply->rawResult().data().size(); // 0
                      QByteArray data = reply->rawResult().data(); // ""
                  });
              }
          });
      
          return a.exec();
      }

      As you can see, the response I get is invalid, even though the function code is within limits (0x66), it's a part of FunctionCode enum, and it has a data size calculator.

      If I change

      QModbusResponse::registerDataSizeCalculator(QModbusPdu::CustomFun_ReadData ...

      to

      QModbusResponse::registerDataSizeCalculator(QModbusPdu::WriteSingleCoil ...

      and make another side answer with a function code 0x05 instead of 0x66, then the response becomes valid and the data size calculator is called.

      So, it seems to me, the problem is how QModbusResponse is assembled, if the function is code is custom, then it's never assigned, and therefore a default function code (invalid) stays.

      Is there any way to fix the problem?

      Attachments

        For Gerrit Dashboard: QTBUG-91037
        # Subject Branch Project Status CR V

        Activity

          People

            heimrich Karsten Heimrich
            yurym Yury Malyshev
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes