Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. ModbusTcpClient not working
Forum Updated to NodeBB v4.3 + New Features

ModbusTcpClient not working

Scheduled Pinned Locked Moved Unsolved General and Desktop
13 Posts 3 Posters 2.5k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • G Offline
    G Offline
    Gelvis
    wrote on last edited by
    #1

    Cannot get modbus to work with QT (works with other library, so no physical connection problems etc). Any idea why this does not work?

    QModbusTcpClient modbusClient;

    modbusClient.setConnectionParameter(QModbusDevice::NetworkAddressParameter, QVariant(QString("192.168.0.3")));
    modbusClient.setConnectionParameter(QModbusDevice::NetworkPortParameter, QVariant(502));
    modbusClient.connectDevice();

    if (!modbusClient.state() == QModbusDevice::ConnectedState) {
    qDebug() << "Modbus connection failed";
    }

    QModbusDataUnit readRequest(QModbusDataUnit::Coils, 0, 1);
    modbusClient.sendReadRequest(readRequest, 1);

    Application output says:
    qt.modbus: (Client) Device is not connected
    qt.modbus: (TCP client) Connected to QHostAddress("192.168.0.3") on port 502

    SPlattenS J.HilkJ 2 Replies Last reply
    0
    • G Gelvis

      Cannot get modbus to work with QT (works with other library, so no physical connection problems etc). Any idea why this does not work?

      QModbusTcpClient modbusClient;

      modbusClient.setConnectionParameter(QModbusDevice::NetworkAddressParameter, QVariant(QString("192.168.0.3")));
      modbusClient.setConnectionParameter(QModbusDevice::NetworkPortParameter, QVariant(502));
      modbusClient.connectDevice();

      if (!modbusClient.state() == QModbusDevice::ConnectedState) {
      qDebug() << "Modbus connection failed";
      }

      QModbusDataUnit readRequest(QModbusDataUnit::Coils, 0, 1);
      modbusClient.sendReadRequest(readRequest, 1);

      Application output says:
      qt.modbus: (Client) Device is not connected
      qt.modbus: (TCP client) Connected to QHostAddress("192.168.0.3") on port 502

      SPlattenS Offline
      SPlattenS Offline
      SPlatten
      wrote on last edited by SPlatten
      #2

      @Gelvis , you haven't specified if you are the slave or the master, I assume slave, is a master running at the IP 192.168.0.3 ?

      I haven't use the QModbusTcpClient however I have written lots of modbus implementations both Master and Slave on various platforms, I guess because its called QMobusTcpClient it must be a slave....check the master is running and listening on port 502.

      Kind Regards,
      Sy

      1 Reply Last reply
      0
      • G Offline
        G Offline
        Gelvis
        wrote on last edited by
        #3

        The physical device is running on 192.168.0.3.

        I have got it working with another modbus library

        (https://github.com/fz-lyu/modbuspp)

        modbus mb = modbus("192.168.0.3", 502);
        mb.modbus_set_slave_id(1);
        mb.modbus_connect();

        bool read_coil;
        mb.modbus_read_coils(0, 1, &read_coil);

        SPlattenS 1 Reply Last reply
        0
        • G Gelvis

          The physical device is running on 192.168.0.3.

          I have got it working with another modbus library

          (https://github.com/fz-lyu/modbuspp)

          modbus mb = modbus("192.168.0.3", 502);
          mb.modbus_set_slave_id(1);
          mb.modbus_connect();

          bool read_coil;
          mb.modbus_read_coils(0, 1, &read_coil);

          SPlattenS Offline
          SPlattenS Offline
          SPlatten
          wrote on last edited by SPlatten
          #4

          @Gelvis , I have no idea what QModbusClient is doing, but in order for a slave to talk to a master it must send a request, modbus is a very simple protocol, there is no connection except when a request is sent to the master then the master responds. In your first post I cannot see where you set the slave address of the client.

          In your new post, you connect then issue a request to get the coils, this is correct and a connection is only made when the request is issued.

          Move:

          if (!modbusClient.state() == QModbusDevice::ConnectedState) {
          qDebug() << "Modbus connection failed";
          }
          

          to after:

          modbusClient.sendReadRequest(readRequest, 1);
          

          Kind Regards,
          Sy

          1 Reply Last reply
          0
          • G Offline
            G Offline
            Gelvis
            wrote on last edited by Gelvis
            #5

            I do not understand QModbusTcpClient myself

            I guessed the 1 in "modbusClient.sendReadRequest(readRequest, 1);" is the slave address

            Tried modbusClient.setSlaveAddress(1), but that method does not exist

            Moving the check made no difference

            SPlattenS 1 Reply Last reply
            0
            • G Gelvis

              I do not understand QModbusTcpClient myself

              I guessed the 1 in "modbusClient.sendReadRequest(readRequest, 1);" is the slave address

              Tried modbusClient.setSlaveAddress(1), but that method does not exist

              Moving the check made no difference

              SPlattenS Offline
              SPlattenS Offline
              SPlatten
              wrote on last edited by
              #6

              @Gelvis , also there are various inconsistencies in the protocol, for example in the protocol, all addresses start from 0, but 0 actually translates in the real world to 1. This is a serious gotcha.

              Kind Regards,
              Sy

              G 1 Reply Last reply
              0
              • SPlattenS SPlatten

                @Gelvis , also there are various inconsistencies in the protocol, for example in the protocol, all addresses start from 0, but 0 actually translates in the real world to 1. This is a serious gotcha.

                G Offline
                G Offline
                Gelvis
                wrote on last edited by
                #7

                @SPlatten

                I guess. However setting it to 0 made no difference

                SPlattenS 1 Reply Last reply
                0
                • G Gelvis

                  @SPlatten

                  I guess. However setting it to 0 made no difference

                  SPlattenS Offline
                  SPlattenS Offline
                  SPlatten
                  wrote on last edited by
                  #8

                  @Gelvis , please explain? I suggest downloading the Modicon Modbus Protocol Specification. It’s very easy to follow and freely available.

                  Kind Regards,
                  Sy

                  G 1 Reply Last reply
                  0
                  • G Gelvis

                    Cannot get modbus to work with QT (works with other library, so no physical connection problems etc). Any idea why this does not work?

                    QModbusTcpClient modbusClient;

                    modbusClient.setConnectionParameter(QModbusDevice::NetworkAddressParameter, QVariant(QString("192.168.0.3")));
                    modbusClient.setConnectionParameter(QModbusDevice::NetworkPortParameter, QVariant(502));
                    modbusClient.connectDevice();

                    if (!modbusClient.state() == QModbusDevice::ConnectedState) {
                    qDebug() << "Modbus connection failed";
                    }

                    QModbusDataUnit readRequest(QModbusDataUnit::Coils, 0, 1);
                    modbusClient.sendReadRequest(readRequest, 1);

                    Application output says:
                    qt.modbus: (Client) Device is not connected
                    qt.modbus: (TCP client) Connected to QHostAddress("192.168.0.3") on port 502

                    J.HilkJ Online
                    J.HilkJ Online
                    J.Hilk
                    Moderators
                    wrote on last edited by
                    #9

                    @Gelvis I would suggest looking at the return value of modbusClient.connectDevice(); it hopefully returns true .

                    this one modbusClient.sendReadRequest(readRequest, 1); returns a QModbusReply instance, you completely ignore that one, that is super wrong.

                    Because you have to listen to the finished() signal of that reply! Only once that signal is emitted can you actually read the received data.


                    Be aware of the Qt Code of Conduct, when posting : https://forum.qt.io/topic/113070/qt-code-of-conduct


                    Q: What's that?
                    A: It's blue light.
                    Q: What does it do?
                    A: It turns blue.

                    1 Reply Last reply
                    1
                    • G Offline
                      G Offline
                      Gelvis
                      wrote on last edited by Gelvis
                      #10

                      I did test for the modbusClient.state() == QModbusDevice::ConnectedState which gives true (connectDevice also returns true)

                      I also have more code reading the reply, but my point was that it will never get to that after sendReadRequest gives this error: qt.modbus: (Client) Device is not connected

                      (fails on first line, never gets to qDebug messages or errorString)

                      edit: gets to the last one obviously "Read request failed, check connection status"

                      // Wait for the response
                      if (auto *reply = modbusClient.sendReadRequest(readRequest, 1)) {
                          if (!reply->isFinished())
                              connect(reply, &QModbusReply::finished, this, [this, reply]() {
                                  if (reply->error() == QModbusDevice::NoError) {
                                      const QModbusDataUnit unit = reply->result();
                                      qDebug() << "Read register value:" << unit.value(0);
                                  } else {
                                      qDebug() << "Error:" << reply->errorString();
                                  }
                                  reply->deleteLater();
                              });
                          else
                              reply->deleteLater();
                      } else {
                          qDebug() << "Read request failed, check connection status";
                      }
                      
                      1 Reply Last reply
                      0
                      • SPlattenS SPlatten

                        @Gelvis , please explain? I suggest downloading the Modicon Modbus Protocol Specification. It’s very easy to follow and freely available.

                        G Offline
                        G Offline
                        Gelvis
                        wrote on last edited by
                        #11

                        @SPlatten

                        I might have to. I was hoping I did not have to implement the whole thing myself for this simple task

                        I got this working in 5 minutes on Linux with a header file I found on github, however I have to make this for Windows for the assignment

                        SPlattenS 1 Reply Last reply
                        0
                        • G Gelvis

                          @SPlatten

                          I might have to. I was hoping I did not have to implement the whole thing myself for this simple task

                          I got this working in 5 minutes on Linux with a header file I found on github, however I have to make this for Windows for the assignment

                          SPlattenS Offline
                          SPlattenS Offline
                          SPlatten
                          wrote on last edited by
                          #12

                          @Gelvis , you only need to implement the messages you intend to provide services for , coils, status inputs, input registers and holding registers.

                          Kind Regards,
                          Sy

                          1 Reply Last reply
                          0
                          • G Offline
                            G Offline
                            Gelvis
                            wrote on last edited by
                            #13

                            Turned out an event loop was needed to make QModbus work. I had no idea.

                            Connecting a timer to a method to read registers worked
                            connect(&m_timer, &QTimer::timeout, this, &ModbusController::readInputRegisters);

                            1 Reply Last reply
                            1

                            • Login

                            • Login or register to search.
                            • First post
                              Last post
                            0
                            • Categories
                            • Recent
                            • Tags
                            • Popular
                            • Users
                            • Groups
                            • Search
                            • Get Qt Extensions
                            • Unsolved