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. Modbus TCP Client write holding registers
Forum Updated to NodeBB v4.3 + New Features

Modbus TCP Client write holding registers

Scheduled Pinned Locked Moved Solved General and Desktop
29 Posts 2 Posters 4.7k Views
  • 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.
  • D Offline
    D Offline
    Damian7546
    wrote on last edited by Damian7546
    #1

    Hi,

    I wrote simple Modbus TCP client to reading Input Registers cyclicly. It works Now I would like to write value to Holding Register form Modbus TCP Client, so I wrote wr_redy function to my thread, but I do not know how run it, any idea ?

    void ClientMachine1::run()
    {
        QModbusTcpClient mc;
        QTimer tim_event_timer;
        tim_event_timer.setSingleShot(true);
        QModbusDataUnit du(QModbusDataUnit::InputRegisters,0,10);
        QModbusReply *replyRd;
        QModbusDataUnit wr(QModbusDataUnit::HoldingRegisters,0,10);
    
    
        //define modbus write function
        auto wr_redy = [&](){
            for(int i=0; i < 10; i++)
                wr.setValue(i, m_holdRegArray[i]);
            if (auto *replyWr = mc.sendWriteRequest(wr,255)){
                if (!replyWr->isFinished()) {
                    connect(replyWr, &QModbusReply::finished, this, [this, replyWr]() {
                        if (replyWr->error() == QModbusDevice::ProtocolError) {
                            qDebug() << "Modbus TCP Client write response error";
                        } else if (replyWr->error() != QModbusDevice::NoError) {
                            qDebug() << "Modbus TCP Client write response error";
                        }
                        replyWr->deleteLater();
                    });
                } else {
                    replyWr->deleteLater();
                }
            }
            else {
                qDebug() << "Modbus TCP Client write error";
            }
        };
    
        //define modbus reply function
        auto rpl_redy =[&](){
            if(!replyRd->error()){
                emit updateDataInReg(id, replyRd->result().value(0)
                                     , replyRd->result().value(1)
                                     , replyRd->result().value(2)
                                     , replyRd->result().value(3)
                                     , replyRd->result().value(4)
                                     , replyRd->result().value(5)
                                     , replyRd->result().value(6)
                                     , replyRd->result().value(7)
                                     , replyRd->result().value(8)
                                     , replyRd->result().value(9));
            }else{
                exit();
            }
            replyRd->deleteLater();
        };
    
        //define timer timeout function
        auto timeoutRd = [&](){
            replyRd=mc.sendReadRequest(du,255);
            if(replyRd->isFinished()){
                delete replyRd;
            }else{
                connect(replyRd,&QModbusReply::finished,rpl_redy);
            }
        };
    
        //define modbus device state change function
        auto stateChange = [&](QModbusClient::State state){
            if(state==QModbusClient::ConnectedState){
                tim_event_timer.start(1000);
                qDebug() << "ModbusTCPClient is connected";
            }else if(state==QModbusClient::UnconnectedState){
                qDebug() << "ModbusTCPClient is disconnected";
                exit();
            }
        };
    
    
    
        connect(&tim_event_timer, &QTimer::timeout,timeoutRd);
        connect(&mc, &QModbusClient::stateChanged,stateChange);
    
    
    
        mc.setConnectionParameter(QModbusDevice::NetworkAddressParameter, "192.168.1.18");
        mc.setConnectionParameter(QModbusDevice::NetworkPortParameter, 5020);
        mc.setTimeout(500);
        if(!mc.connectDevice()){
            exit();
            return;
        }
        exec();
    }
    
    
    1 Reply Last reply
    0
    • D Damian7546

      @jsulm How do I do that?
      When I declare my function in *.h file :
      void wr_redy();

      And I will create definition this function outside my run() function , I do not have acces to variables defined in run()...

      jsulmJ Online
      jsulmJ Online
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #15

      @Damian7546 If you want to connect a lambda to a signal then do it properly:

      connect(this, ClientMachine1::holdRegArrayChanged, this, wr_redy);
      

      wr_redy is NOT a member of your class, so simply do not prefix it with your class name.

      https://forum.qt.io/topic/113070/qt-code-of-conduct

      D 1 Reply Last reply
      0
      • D Offline
        D Offline
        Damian7546
        wrote on last edited by
        #2

        How connect wr_redy to signal from ClientMachine1 , inside run() ?

        jsulmJ 1 Reply Last reply
        0
        • D Damian7546

          How connect wr_redy to signal from ClientMachine1 , inside run() ?

          jsulmJ Online
          jsulmJ Online
          jsulm
          Lifetime Qt Champion
          wrote on last edited by
          #3

          @Damian7546 said in Modbus TCP Client write holding registers:

          How connect wr_redy to signal from ClientMachine1 , inside run() ?

          Using connect.
          What exact problem do you have?

          https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • D Offline
            D Offline
            Damian7546
            wrote on last edited by Damian7546
            #4

            Look..
            I wold like call wr_ready when QbyteArray (m_holdRegArray) was changed, so I created code like below:

            
            void ClientMachine1::run()
            {
               ///my Modbus TCP Client code 
               ///........  
               how connect wr_redy  with  signal   holdRegArrayChanged 	
               
            }
            
            QByteArray ClientMachine1::holdRegArray() const
            {
                return m_holdRegArray;
            }
            
            void ClientMachine1::setHoldRegArray(const QByteArray &newHoldRegArray)
            {
                if (m_holdRegArray == newHoldRegArray)
                    return;
                m_holdRegArray = newHoldRegArray;
                emit holdRegArrayChanged();
            }
            

            How connect holdRegArrayChanged with wr_ready inside run() thread ?

            jsulmJ 1 Reply Last reply
            0
            • D Damian7546

              Look..
              I wold like call wr_ready when QbyteArray (m_holdRegArray) was changed, so I created code like below:

              
              void ClientMachine1::run()
              {
                 ///my Modbus TCP Client code 
                 ///........  
                 how connect wr_redy  with  signal   holdRegArrayChanged 	
                 
              }
              
              QByteArray ClientMachine1::holdRegArray() const
              {
                  return m_holdRegArray;
              }
              
              void ClientMachine1::setHoldRegArray(const QByteArray &newHoldRegArray)
              {
                  if (m_holdRegArray == newHoldRegArray)
                      return;
                  m_holdRegArray = newHoldRegArray;
                  emit holdRegArrayChanged();
              }
              

              How connect holdRegArrayChanged with wr_ready inside run() thread ?

              jsulmJ Online
              jsulmJ Online
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #5

              @Damian7546 I still don't understand the problem. If wr_ready is a slot and holdRegArrayChanged a signal then simply connect them like any other signal/slot. Can you explain what exactly is not clear?

              https://forum.qt.io/topic/113070/qt-code-of-conduct

              1 Reply Last reply
              0
              • D Offline
                D Offline
                Damian7546
                wrote on last edited by Damian7546
                #6

                Because wr_ready is not visible in the constructor:

                ClientMachine1::ClientMachine1(QObject *parent)
                    : QThread{parent}
                {
                
                    connect(this, ClientMachine1::holdRegArrayChanged, this, ClientMachine1::wr_ready);
                }
                

                In othe hand, the holdRegArrayChanged I can not connect inside run() because I have errors:

                Reference to non-static member function must be called; did you mean to call it with no arguments? (fix available)
                insert '()'
                
                No member named 'wr_redy' in 'ClientMachine1'
                
                jsulmJ 1 Reply Last reply
                0
                • D Damian7546

                  Because wr_ready is not visible in the constructor:

                  ClientMachine1::ClientMachine1(QObject *parent)
                      : QThread{parent}
                  {
                  
                      connect(this, ClientMachine1::holdRegArrayChanged, this, ClientMachine1::wr_ready);
                  }
                  

                  In othe hand, the holdRegArrayChanged I can not connect inside run() because I have errors:

                  Reference to non-static member function must be called; did you mean to call it with no arguments? (fix available)
                  insert '()'
                  
                  No member named 'wr_redy' in 'ClientMachine1'
                  
                  jsulmJ Online
                  jsulmJ Online
                  jsulm
                  Lifetime Qt Champion
                  wrote on last edited by
                  #7

                  @Damian7546 said in Modbus TCP Client write holding registers:

                  Because wr_ready is not visible in the constructor

                  Of course it's not, because you defined it inside run().
                  Simply define it as normal member of ClientMachine1...

                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                  1 Reply Last reply
                  0
                  • D Offline
                    D Offline
                    Damian7546
                    wrote on last edited by
                    #8

                    Can you tell me how create definition in *.h file to my wr_redy lambda contruction and auto type ?

                    jsulmJ 2 Replies Last reply
                    0
                    • D Damian7546

                      Can you tell me how create definition in *.h file to my wr_redy lambda contruction and auto type ?

                      jsulmJ Online
                      jsulmJ Online
                      jsulm
                      Lifetime Qt Champion
                      wrote on last edited by
                      #9

                      @Damian7546 said in Modbus TCP Client write holding registers:

                      Can you tell me how create definition in *.h file to my wr_redy lambda contruction and auto type ?

                      Why does it have to be a lambda?

                      https://forum.qt.io/topic/113070/qt-code-of-conduct

                      D 1 Reply Last reply
                      0
                      • D Damian7546

                        Can you tell me how create definition in *.h file to my wr_redy lambda contruction and auto type ?

                        jsulmJ Online
                        jsulmJ Online
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #10

                        @Damian7546 I'm also wondering why you use threads at all?
                        If you need to do something periodically then simply use QTimer.

                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                        D 1 Reply Last reply
                        0
                        • jsulmJ jsulm

                          @Damian7546 said in Modbus TCP Client write holding registers:

                          Can you tell me how create definition in *.h file to my wr_redy lambda contruction and auto type ?

                          Why does it have to be a lambda?

                          D Offline
                          D Offline
                          Damian7546
                          wrote on last edited by Damian7546
                          #11

                          @jsulm said in Modbus TCP Client write holding registers:

                          @Damian7546 said in Modbus TCP Client write holding registers:

                          Can you tell me how create definition in *.h file to my wr_redy lambda contruction and auto type ?

                          Why does it have to be a lambda?

                          I just want to know how to do it - for my own knowledge

                          1 Reply Last reply
                          0
                          • jsulmJ jsulm

                            @Damian7546 I'm also wondering why you use threads at all?
                            If you need to do something periodically then simply use QTimer.

                            D Offline
                            D Offline
                            Damian7546
                            wrote on last edited by Damian7546
                            #12

                            @jsulm said in Modbus TCP Client write holding registers:

                            @Damian7546 I'm also wondering why you use threads at all?
                            If you need to do something periodically then simply use QTimer.

                            I would like to run Client on thread and test with several clients(threads) ... how will it be with stability and read/write speed,
                            So how define wr_redy in *.h file ?

                            jsulmJ 1 Reply Last reply
                            0
                            • D Damian7546

                              @jsulm said in Modbus TCP Client write holding registers:

                              @Damian7546 I'm also wondering why you use threads at all?
                              If you need to do something periodically then simply use QTimer.

                              I would like to run Client on thread and test with several clients(threads) ... how will it be with stability and read/write speed,
                              So how define wr_redy in *.h file ?

                              jsulmJ Online
                              jsulmJ Online
                              jsulm
                              Lifetime Qt Champion
                              wrote on last edited by
                              #13

                              @Damian7546 said in Modbus TCP Client write holding registers:

                              So how define wr_redy in *.h file ?

                              Don't define it as lambda, but a normal method.

                              https://forum.qt.io/topic/113070/qt-code-of-conduct

                              D 1 Reply Last reply
                              0
                              • jsulmJ jsulm

                                @Damian7546 said in Modbus TCP Client write holding registers:

                                So how define wr_redy in *.h file ?

                                Don't define it as lambda, but a normal method.

                                D Offline
                                D Offline
                                Damian7546
                                wrote on last edited by Damian7546
                                #14

                                @jsulm How do I do that?
                                When I declare my function in *.h file :
                                void wr_redy();

                                And I will create definition this function outside my run() function , I do not have acces to variables defined in run()...

                                jsulmJ 1 Reply Last reply
                                0
                                • D Damian7546

                                  @jsulm How do I do that?
                                  When I declare my function in *.h file :
                                  void wr_redy();

                                  And I will create definition this function outside my run() function , I do not have acces to variables defined in run()...

                                  jsulmJ Online
                                  jsulmJ Online
                                  jsulm
                                  Lifetime Qt Champion
                                  wrote on last edited by
                                  #15

                                  @Damian7546 If you want to connect a lambda to a signal then do it properly:

                                  connect(this, ClientMachine1::holdRegArrayChanged, this, wr_redy);
                                  

                                  wr_redy is NOT a member of your class, so simply do not prefix it with your class name.

                                  https://forum.qt.io/topic/113070/qt-code-of-conduct

                                  D 1 Reply Last reply
                                  0
                                  • jsulmJ jsulm

                                    @Damian7546 If you want to connect a lambda to a signal then do it properly:

                                    connect(this, ClientMachine1::holdRegArrayChanged, this, wr_redy);
                                    

                                    wr_redy is NOT a member of your class, so simply do not prefix it with your class name.

                                    D Offline
                                    D Offline
                                    Damian7546
                                    wrote on last edited by
                                    #16

                                    @jsulm said in Modbus TCP Client write holding registers:

                                    @Damian7546 If you want to connect a lambda to a signal then do it properly:

                                    connect(this, ClientMachine1::holdRegArrayChanged, this, wr_redy);
                                    

                                    wr_redy is NOT a member of your class, so simply do not prefix it with your class name.

                                    Right

                                    1 Reply Last reply
                                    0
                                    • D Offline
                                      D Offline
                                      Damian7546
                                      wrote on last edited by
                                      #17

                                      @jsulm Unfortunetly my write function still doesn't work:/

                                      auto wr_redy = [&](){
                                                  for(int i=0; i < m_holdRegArray.count(); i++){
                                                      qDebug() << "count: " << i;
                                                      wr.setValue(i, m_holdRegArray[i]);
                                                  }
                                          };
                                      

                                      The application was crash when it wr.setValue(i, m_holdRegArray[i]); is called...

                                      jsulmJ 1 Reply Last reply
                                      0
                                      • D Damian7546

                                        @jsulm Unfortunetly my write function still doesn't work:/

                                        auto wr_redy = [&](){
                                                    for(int i=0; i < m_holdRegArray.count(); i++){
                                                        qDebug() << "count: " << i;
                                                        wr.setValue(i, m_holdRegArray[i]);
                                                    }
                                            };
                                        

                                        The application was crash when it wr.setValue(i, m_holdRegArray[i]); is called...

                                        jsulmJ Online
                                        jsulmJ Online
                                        jsulm
                                        Lifetime Qt Champion
                                        wrote on last edited by
                                        #18

                                        @Damian7546 said in Modbus TCP Client write holding registers:

                                        The application was crash when

                                        So, did you use debugger to see why it crashes?
                                        What is wr?

                                        https://forum.qt.io/topic/113070/qt-code-of-conduct

                                        1 Reply Last reply
                                        0
                                        • D Offline
                                          D Offline
                                          Damian7546
                                          wrote on last edited by
                                          #19

                                          @jsulm When I have status: "ModbusTCPClient is disconnected" my app crash when I try write registers..

                                          jsulmJ 1 Reply Last reply
                                          0
                                          • D Damian7546

                                            @jsulm When I have status: "ModbusTCPClient is disconnected" my app crash when I try write registers..

                                            jsulmJ Online
                                            jsulmJ Online
                                            jsulm
                                            Lifetime Qt Champion
                                            wrote on last edited by
                                            #20

                                            @Damian7546 Then don't write registers if there is no connection...

                                            https://forum.qt.io/topic/113070/qt-code-of-conduct

                                            D 1 Reply Last reply
                                            0

                                            • Login

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