Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Mobile and Embedded
  4. Thread that read from QSerialPort
Forum Updated to NodeBB v4.3 + New Features

Thread that read from QSerialPort

Scheduled Pinned Locked Moved Mobile and Embedded
21 Posts 4 Posters 13.4k 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.
  • T Offline
    T Offline
    t3685
    wrote on last edited by
    #2

    That is probably not the most efficient way of doing this. QSerialPort can be used either synchronously or asynchronously.

    Synchronously: use waitForReadyRead or waitForBytesWritten, but this will block your thread until either data is received or written. This is bad if you use it in the GUI thread (i.e. the main Qt thread): your application will not respond to user input until the read or write is done.

    Asynchronously: uses signal and slots. In this case you connect to the readyRead signal with your slot (ReadFromSerialPort), and each time data is available the signal will be emitted and your slot will be executed. Now you don't need to wait in a wasteful while loop for data reads or writes + no need for extra threads.
    For more information how this is done internally check:
    https://qt-project.org/wiki/Threads_Events_QObjects#285a62c361be4793a6c10d04e3823a80

    I highly recommend using the second approach, especially if you plan to use more Qt.

    1 Reply Last reply
    0
    • JKSHJ Offline
      JKSHJ Offline
      JKSH
      Moderators
      wrote on last edited by
      #3

      Hi,

      [quote author="rileo8" date="1383151640"]
      @while(!end)
      {
      sleep(1)
      }
      @
      [/quote]This is an infinite loop. It blocks the event loop, which means your thread can't receive any signals.

      How fast is your read/write rate? You might not even need separate threads. See this "official example":http://qt-project.org/doc/qt-5.1/qtserialport/terminal.html -- the QSerialPort lives in the main thread itself.

      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

      1 Reply Last reply
      0
      • R Offline
        R Offline
        rileo8
        wrote on last edited by
        #4

        Hi,

        the problem is that i'm developing an application that communicate with an external interface with the serial port so it continuosly communicate with it while the GUI need to be responsive and accept user input/show values etc...

        So i want to separate read/write from serial port AND the GUI

        What you suggest to do?

        1 Reply Last reply
        0
        • R Offline
          R Offline
          rileo8
          wrote on last edited by
          #5

          Reading the documentation i found that maybe i have to substitute

          @while(!end)
          {
          sleep(1)
          }@

          whit @exec()@

          that enters the event loop and waits until exit() is calle

          Is it correct?

          Thanks

          1 Reply Last reply
          0
          • T Offline
            T Offline
            t3685
            wrote on last edited by
            #6

            No it is not correct. You don't need a wait loop like that.

            1 Reply Last reply
            0
            • JKSHJ Offline
              JKSHJ Offline
              JKSH
              Moderators
              wrote on last edited by
              #7

              [quote author="rileo8" date="1383208867"]that enters the event loop and waits until exit() is calle

              Is it correct?[/quote]Yes, it's correct :)

              Next, read the "Thread Affinity" section of the "QObject documentation":http://doc-snapshot.qt-project.org/qt5-stable/qobject.html#thread-affinity -- it explains how to choose the thread to run your slots.

              [quote author="t3685" date="1383215445"]No it is not correct. You don't need a wait loop like that.[/quote]rileo8 realized that after reading the documentation. That's why he asked if it's correct to replace the wait loop with exec().

              Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

              1 Reply Last reply
              0
              • R Offline
                R Offline
                rileo8
                wrote on last edited by
                #8

                Ok,

                i'm understanding that i hadn;t understand qthreads before... :-)
                The question is :

                i need a "worker" thread that read and write from a serial port so i can use this approach:

                class Worker : public QObject
                {
                Q_OBJECT
                private slots:
                void onTimeout()
                {
                qDebug()<<"Worker::onTimeout get called from?: "<<QThread::currentThreadId();
                }
                };

                @class Thread : public QThread
                {
                Q_OBJECT

                private:
                void run()
                {
                qDebug()<<"From work thread: "<<currentThreadId();
                QTimer timer;
                Worker worker;
                connect(&timer, SIGNAL(timeout()), &worker, SLOT(onTimeout()));
                timer.start(1000);

                    exec&#40;&#41;;
                }
                

                };@

                the problem is...if i need that the worker thread receive signals from the GUI what i have to do? Connect with signal&slot the GUI withe theThread class and then connect always with signals/slot the thread calls with the worker class?

                1 Reply Last reply
                0
                • JKSHJ Offline
                  JKSHJ Offline
                  JKSH
                  Moderators
                  wrote on last edited by
                  #9

                  To make things simple, you don't need to subclass QThread. Just have the timer in your worker:

                  @
                  class Worker : public QObject
                  {
                  Q_OBJECT
                  QTimer* timer;

                  public:
                  Worker(QObject *parent = 0) : QObject(parent) {
                  // Worker must be parent of QTimer
                  timer = new QTimer(this);
                  connect(timer, SIGNAL(timeout()), this, SLOT(onTimeout()));
                  }

                  public slots:
                  void startWorking() { timer->start(1000); }

                  private slots:
                  void onTimeout() {...}
                  };
                  @

                  @
                  int main(int argc, char *argv[]) {
                  QApplication a(argc, argv);
                  QThread thread;
                  Worker worker;

                  QObject::connect(&thread, SIGNAL(started()),
                          &worker, SLOT(startWorking()));
                  
                  worker.moveToThread(&thread);
                  thread.start();
                  
                  int returnValue = a.exec&#40;&#41;;
                  thread.wait(&#41;;
                  return returnValue;
                  

                  }
                  @

                  You can connect signals and slots directly between your worker and your GUI.

                  Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    rileo8
                    wrote on last edited by
                    #10

                    Ok perfect,thanks to everybody for the help!
                    Now i better understand Qthreads...

                    1 Reply Last reply
                    0
                    • JKSHJ Offline
                      JKSHJ Offline
                      JKSH
                      Moderators
                      wrote on last edited by
                      #11

                      You're welcome.

                      Good luck with your project!

                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        rileo8
                        wrote on last edited by
                        #12

                        Hi, i'm stille here with another question..

                        now my code loooks like this:

                        @#include "mainwindow.h"
                        #include <QtGui/QApplication>
                        #include <QThread>

                        #include "executer.h"
                        #include "checker.h"
                        #include "networker.h"

                        int main(int argc, char *argv[])
                        {
                        QApplication a(argc, argv);
                        MainWindow w;
                        w.showMaximized();

                        Checker checker;
                        Networker networker;
                        Executer executer;

                        QThread checkerThread;
                        QThread networkerThread;
                        QThread executerThread;

                        QObject::connect(&executerThread,SIGNAL(started()),&executer,SLOT(Start()));

                        checker.moveToThread(&checkerThread);
                        networker.moveToThread(&networkerThread);
                        executer.moveToThread(&executerThread);

                        checkerThread.start();
                        networkerThread.start();
                        executerThread.start();

                        int returnValue=a.exec();

                        executerThread.wait();

                        return returnValue;

                        }
                        @

                        i neew to share an object (of a custom Configuration type) between all trheads.

                        Is it coorect to declare it in the main, pass it to all htreads and also share a mutex so that every thread lock and unlock it?

                        Thanks

                        1 Reply Last reply
                        0
                        • JKSHJ Offline
                          JKSHJ Offline
                          JKSH
                          Moderators
                          wrote on last edited by
                          #13

                          If it is not a QObject, then yes you can do that.

                          If it is a QObject, then you are not allowed to share it between threads. QObject is not thread-safe.

                          See this page for info on how to share data between threads: http://doc-snapshot.qt-project.org/qt5-stable/threads-synchronizing.html

                          Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                          1 Reply Last reply
                          0
                          • T Offline
                            T Offline
                            t3685
                            wrote on last edited by
                            #14

                            [quote author="JKSH" date="1383215991"][quote author="rileo8" date="1383208867"]that enters the event loop and waits until exit() is calle

                            Is it correct?[/quote]Yes, it's correct :)

                            Next, read the "Thread Affinity" section of the "QObject documentation":http://doc-snapshot.qt-project.org/qt5-stable/qobject.html#thread-affinity -- it explains how to choose the thread to run your slots.

                            [quote author="t3685" date="1383215445"]No it is not correct. You don't need a wait loop like that.[/quote]rileo8 realized that after reading the documentation. That's why he asked if it's correct to replace the wait loop with exec().[/quote]

                            The QSerialPort class is asynchronous. You don't need threads to do this.

                            1 Reply Last reply
                            0
                            • R Offline
                              R Offline
                              rileo8
                              wrote on last edited by
                              #15

                              It is not a QObject, is a simple c++ custom class

                              1 Reply Last reply
                              0
                              • JKSHJ Offline
                                JKSHJ Offline
                                JKSH
                                Moderators
                                wrote on last edited by
                                #16

                                [quote author="t3685" date="1383225223"]The QSerialPort class is asynchronous. You don't need threads to do this.[/quote]Yes, if I/O is slow enough, then no threads are needed. That's why I asked about the read/write rate.

                                Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                1 Reply Last reply
                                0
                                • R Offline
                                  R Offline
                                  rileo8
                                  wrote on last edited by
                                  #17

                                  Yes i understood this,
                                  infact now i have:

                                  GUI thread
                                  thread for operations on serialport 1
                                  thread for operations on serialport 2
                                  thread for network operations

                                  Now i also added a custom Configuration class that is share d between threads with a shared QMutex to enable access to it

                                  1 Reply Last reply
                                  0
                                  • T Offline
                                    T Offline
                                    t3685
                                    wrote on last edited by
                                    #18

                                    [quote author="JKSH" date="1383225543"][quote author="t3685" date="1383225223"]The QSerialPort class is asynchronous. You don't need threads to do this.[/quote]Yes, if I/O is slow enough, then no threads are needed. That's why I asked about the read/write rate.[/quote]

                                    The write function returns immediately. The readyRead() signal is only emitted when data is available. I don't think it matters then what the Baud rate is.

                                    http://qt-project.org/doc/qt-5.1/qtserialport/terminal.html

                                    1 Reply Last reply
                                    0
                                    • JKSHJ Offline
                                      JKSHJ Offline
                                      JKSH
                                      Moderators
                                      wrote on last edited by
                                      #19

                                      [quote author="t3685" date="1383225815"]
                                      The write function returns immediately. The readyRead() signal is only emitted when data is available. I don't think it matters then what the Baud rate is.[/quote]Sorry for being unclear; I meant the rate at which read() and write() need to be called (relative to other operations). An active thread will experience jitter, especially on a non-real-time OS. That raises the possibility of a buffer becoming empty. Depending on how the devices have been designed, an empty write buffer could kill the entire connection.

                                      t3685 has a very valid point though. rileo8, try running your workers in the main thread first using the asynchronous API, and see how your program performs. You might not need 3 extra threads.

                                      Qt Doc Search for browsers: forum.qt.io/topic/35616/web-browser-extension-for-improved-doc-searches

                                      1 Reply Last reply
                                      0
                                      • R Offline
                                        R Offline
                                        rileo8
                                        wrote on last edited by
                                        #20

                                        Hi,

                                        my point is that i need to accomplish different operations on 2 serial ports and also network operations so i think that putting all i t he gui can cause gui freezing...

                                        1 Reply Last reply
                                        0
                                        • K Offline
                                          K Offline
                                          kuzulis
                                          Qt Champions 2020
                                          wrote on last edited by
                                          #21

                                          Hi guys,

                                          the main point to use QtSerialPort's objects in different thread - a bug with the stopping of I/O at moving window or expanding window. Of course, this problem only in Windows OS. :)

                                          [quote]

                                          GUI thread

                                          thread for operations on serialport 1

                                          thread for operations on serialport 2

                                          thread for network operations

                                          [/quote]

                                          IMHO, it is better:

                                          1. GUI thread

                                          2. thread for operations on serialport 1, serialport 2, network

                                          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