Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Solved Show low level Modbus packet in UI

    General and Desktop
    3
    11
    1080
    Loading More Posts
    • 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.
    • M
      Mark81 last edited by

      I know I can enable low level Modbus logging in this way:

      QLoggingCategory::setFilterRules(QStringLiteral("qt.modbus* = true"));
      

      and I can get a debug output like this:

      qt.modbus: (TCP client) Connected to QHostAddress("192.168.1.157") on port 502
      qt.modbus.lowlevel: (TCP client) Sent TCP ADU: "00000000000601010000000a"
      qt.modbus: (TCP client) Sent TCP PDU: 0x010000000a with tId: 0
      qt.modbus.lowlevel: (TCP client) Response buffer: "000000000003018101"
      qt.modbus: (TCP client) tid: 0 size: 3 server address: 1
      qt.modbus: (TCP client) Received PDU: 1 "01"
      qt.modbus: (TCP client) Connection closed.

      I'm interested to show in the UI (TextEdit) both sent and received packets: ADU and PDU.
      Is there a way to retrieve them?

      1 Reply Last reply Reply Quote 0
      • mrjj
        mrjj Lifetime Qt Champion last edited by

        Hi
        you mean like
        http://doc.qt.io/qt-5/qtglobal.html#qInstallMessageHandler
        so all QDebug goes to your own function ?

        1 Reply Last reply Reply Quote 1
        • M
          Mark81 last edited by

          It might be a solution if there's no way to retrieve the raw data (the whole packets) directly from the Modbus classes. Like the sendData and reveiceData of EasyModbus.

          I'll try it. Thanks.

          mrjj 1 Reply Last reply Reply Quote 0
          • mrjj
            mrjj Lifetime Qt Champion @Mark81 last edited by

            @Mark81
            Hi
            I have not used the modBus so i cant say.
            Maybe Mr. @aha_1980 knows if possible.

            aha_1980 1 Reply Last reply Reply Quote 0
            • M
              Mark81 last edited by

              Following this method, I can put myMessageOutput inside my MainWindow class? Otherwise I don't understand how I can show the data in the UI.

              int main(int argc, char *argv[])
              {   
                  QLoggingCategory::setFilterRules(QStringLiteral("qt.modbus* = true"));
              
                  QApplication a(argc, argv);
              
                  MainWindow w;
                  qInstallMessageHandler(w.myMessageOutput);
                  w.showMaximized();
              
                  return a.exec();
              }
              

              it says:

              error: reference to non-static member function must be called

              but that function is not static:

              class MainWindow : public QMainWindow
              {
                  Q_OBJECT
              
              public:
                  explicit MainWindow(QWidget *parent = nullptr);
                  ~MainWindow();
                  void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg);
              }
              
              mrjj 1 Reply Last reply Reply Quote 0
              • mrjj
                mrjj Lifetime Qt Champion @Mark81 last edited by

                @Mark81
                Hi
                It has to a be a global function. Cannot be a member. sadly.
                I used a global QObject class (pointer) as as proxy so i could emit from the global function.
                Not pretty but only other alternative is a file or ifstream redirection
                with cout and a custom std::streambuf child.

                1 Reply Last reply Reply Quote 1
                • M
                  Mark81 last edited by

                  Tried with no luck, surely due to lack of my knowledge:

                  class MessageHandler: public QObject
                  {
                      Q_OBJECT
                      MessageHandler() {}
                  
                  public:
                      static MessageHandler *instance()
                      {
                          if (!_instance) _instance = new MessageHandler;
                          return _instance;
                      }
                      static void messageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
                      {
                          emit messageOutput_received(type, context, msg);
                      }
                  
                  signals:
                      static void messageOutput_received(QtMsgType type, const QMessageLogContext &context, const QString &msg);
                  
                  protected:
                      static MessageHandler *_instance;
                  };
                  
                  MessageHandler *MessageHandler::_instance = nullptr;
                  
                  int main(int argc, char *argv[])
                  {   
                      QLoggingCategory::setFilterRules(QStringLiteral("qt.modbus* = true"));
                  
                      QApplication a(argc, argv);
                      MainWindow w;
                      MessageHandler *mh = MessageHandler::instance();
                      qInstallMessageHandler(&mh->messageOutput);
                      QObject::connect(mh, &MessageHandler::messageOutput_received, &w, &MainWindow::myMessageOutput);
                      w.showMaximized();
                  
                      return a.exec();
                  }
                  

                  But it does't like the connect function:

                  error: no matching function for call to 'QObject::connect(MessageHandler*&, void ()(QtMsgType, const QMessageLogContext&, const QString&), MainWindow, void (MainWindow::*)(QtMsgType, const QMessageLogContext&, const QString&))'
                  QObject::connect(mh, &MessageHandler::messageOutput_received, &w, &MainWindow::myMessageOutput);
                  ^

                  mrjj 1 Reply Last reply Reply Quote 0
                  • mrjj
                    mrjj Lifetime Qt Champion @Mark81 last edited by

                    Hi
                    The MessageHandler should not be as a singleton ( with static)
                    Just a small proxy that can be used to send in the global function.
                    MessageHandler *globalMSG; // and new it in main.cpp after QApplication
                    // the new function
                    void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg) {
                    ...
                    globalMSG->emit(xxxxx)
                    }

                    Globals are not pretty so maybe someone has a more clean solution !
                    ( i didnt find one so i used this )

                    1 Reply Last reply Reply Quote 1
                    • aha_1980
                      aha_1980 Lifetime Qt Champion @mrjj last edited by

                      @mrjj said in Show low level Modbus packet in UI:

                      Maybe Mr. @aha_1980 knows if possible.

                      I'm not aware of an official way to do this. qInstallMessageHandler might indeed by a solution to that.

                      Regards

                      Qt has to stay free or it will die.

                      1 Reply Last reply Reply Quote 2
                      • M
                        Mark81 last edited by

                        Got it. It works, but a native way to retrieve the raw data will be very appreciated!

                        aha_1980 1 Reply Last reply Reply Quote 0
                        • aha_1980
                          aha_1980 Lifetime Qt Champion @Mark81 last edited by

                          @Mark81

                          Then please file a suggestion at bugreports.qt.io (and give a link to it here).

                          Qt has to stay free or it will die.

                          1 Reply Last reply Reply Quote 1
                          • First post
                            Last post