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. QSerialPort and QThread
Forum Updated to NodeBB v4.3 + New Features

QSerialPort and QThread

Scheduled Pinned Locked Moved Solved General and Desktop
13 Posts 4 Posters 1.1k 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.
  • O Offline
    O Offline
    oBOXPOH
    wrote on last edited by oBOXPOH
    #1

    Hello everyone!

    I still trying to learn how to use QSerialPort correctly. And I am getting new problems.

    I create QThread in some PARENT class:

        thread = new QThread; // Create QThread
    
        task = new ThreadClass; // CHILD class, in which I have methods for reading and writing data with QSerialPort
    
        task->moveToThread(thread); // Move needed class to created thread
        connect(thread, SIGNAL(started()), task, SLOT(writeData_slot()); // Connect to writeData_slot() method, when I will start the thread
    

    and I have in this PARENT class another method, where I want to start or stop (now there is while cycle for check) the thread:

    if (isConnected)
        {
            thread->start();
        }
        else
        {
            int count = 0;
    
            while (count < 5)
            {
                count++;
                QThread::msleep(1000);
                qDebug("WE ARE HERE!");
            }
        }
    

    In CHILD class (for thread) I have two methods for reading and writing data with QSerialPort:

    void Thread::readyWrite_slot()
    {
        serialPort->write(writeData);
        qDebug("WRITE");
        QThread::msleep(1000);
    }
    
    void Thread::readyRead_slot()
    {
        readData.append(serialPort->readAll());
    
        if (readData.count() == 5)
        {
            readData.clear();
            qDebug("READ");
            emit readyWrite_signal();
        }
    }
    
        connect(serialPort, &QSerialPort::readyRead, this, &Thread::readyRead_slot);
        connect(this, SIGNAL(readyWrite_signal()), SLOT(readyWrite_slot()));
    

    So, I start thread and get data, but when I want to stop getting data, I want to get all data last time, but I can't:

    WRITE
    READ // In CHILD Thread
    WRITE
    READ // In CHILD Thread
    WRITE
    READ // In CHILD Thread
    WRITE
    WE ARE HERE! // Here I want to close CHILD Thread in PARENT class
    WE ARE HERE!
    WE ARE HERE!
    WE ARE HERE!
    WE ARE HERE!
    READ  // But only here I get my last data in CHILD Thread
    WRITE
    READ // 1 WRITE - 1 READ
    WRITE
    READ // 1 WRITE - 1 READ
    WRITE
    READ // 1 WRITE - 1 READ
    WRITE
    READ // 1 WRITE - 1 READ
    

    It means, that thread doesn't work parallel, but it's not true, because I wrote endless while cycle in readyWrite_slot() with message, for example, and got this message together with WE ARE HERE message. Then, my conclusion, I can't get readyRead() signal for some reason, but after cycle with WE ARE HERE message I continue get readyRead() signal. I don't close SerialPort, I just execute while() cycle 5 times and all. After that thread continues to work correctly.

    So, I can't stop correctly my thread, because I can't get last data, but I need it. I don't know what I can do to fix it.

    Hope for your help and advice! Thank you in advance!

    jsulmJ J.HilkJ 2 Replies Last reply
    0
    • O oBOXPOH

      Hello everyone!

      I still trying to learn how to use QSerialPort correctly. And I am getting new problems.

      I create QThread in some PARENT class:

          thread = new QThread; // Create QThread
      
          task = new ThreadClass; // CHILD class, in which I have methods for reading and writing data with QSerialPort
      
          task->moveToThread(thread); // Move needed class to created thread
          connect(thread, SIGNAL(started()), task, SLOT(writeData_slot()); // Connect to writeData_slot() method, when I will start the thread
      

      and I have in this PARENT class another method, where I want to start or stop (now there is while cycle for check) the thread:

      if (isConnected)
          {
              thread->start();
          }
          else
          {
              int count = 0;
      
              while (count < 5)
              {
                  count++;
                  QThread::msleep(1000);
                  qDebug("WE ARE HERE!");
              }
          }
      

      In CHILD class (for thread) I have two methods for reading and writing data with QSerialPort:

      void Thread::readyWrite_slot()
      {
          serialPort->write(writeData);
          qDebug("WRITE");
          QThread::msleep(1000);
      }
      
      void Thread::readyRead_slot()
      {
          readData.append(serialPort->readAll());
      
          if (readData.count() == 5)
          {
              readData.clear();
              qDebug("READ");
              emit readyWrite_signal();
          }
      }
      
          connect(serialPort, &QSerialPort::readyRead, this, &Thread::readyRead_slot);
          connect(this, SIGNAL(readyWrite_signal()), SLOT(readyWrite_slot()));
      

      So, I start thread and get data, but when I want to stop getting data, I want to get all data last time, but I can't:

      WRITE
      READ // In CHILD Thread
      WRITE
      READ // In CHILD Thread
      WRITE
      READ // In CHILD Thread
      WRITE
      WE ARE HERE! // Here I want to close CHILD Thread in PARENT class
      WE ARE HERE!
      WE ARE HERE!
      WE ARE HERE!
      WE ARE HERE!
      READ  // But only here I get my last data in CHILD Thread
      WRITE
      READ // 1 WRITE - 1 READ
      WRITE
      READ // 1 WRITE - 1 READ
      WRITE
      READ // 1 WRITE - 1 READ
      WRITE
      READ // 1 WRITE - 1 READ
      

      It means, that thread doesn't work parallel, but it's not true, because I wrote endless while cycle in readyWrite_slot() with message, for example, and got this message together with WE ARE HERE message. Then, my conclusion, I can't get readyRead() signal for some reason, but after cycle with WE ARE HERE message I continue get readyRead() signal. I don't close SerialPort, I just execute while() cycle 5 times and all. After that thread continues to work correctly.

      So, I can't stop correctly my thread, because I can't get last data, but I need it. I don't know what I can do to fix it.

      Hope for your help and advice! Thank you in advance!

      jsulmJ Offline
      jsulmJ Offline
      jsulm
      Lifetime Qt Champion
      wrote on last edited by
      #2

      @oBOXPOH My first question: why do you need a thread? QSerialPort is asynchronous - there is usually no need for a thread.

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

      O 1 Reply Last reply
      3
      • jsulmJ jsulm

        @oBOXPOH My first question: why do you need a thread? QSerialPort is asynchronous - there is usually no need for a thread.

        O Offline
        O Offline
        oBOXPOH
        wrote on last edited by
        #3

        @jsulm said in QSerialPort and QThread:

        @oBOXPOH My first question: why do you need a thread? QSerialPort is asynchronous - there is usually no need for a thread.

        Because I need to represent my data parallel without losing of control in PARENT class, where I have some buttons, for example.

        JonBJ 1 Reply Last reply
        0
        • O oBOXPOH

          @jsulm said in QSerialPort and QThread:

          @oBOXPOH My first question: why do you need a thread? QSerialPort is asynchronous - there is usually no need for a thread.

          Because I need to represent my data parallel without losing of control in PARENT class, where I have some buttons, for example.

          JonBJ Offline
          JonBJ Offline
          JonB
          wrote on last edited by JonB
          #4

          @oBOXPOH
          Don't understand what you mean here. As @jsulm says, QSerialPort is asynchronous, you just don't usually need a thread, why do you need one? If you mean you are passing a parent to your QSerialPort which then goes out of scope taking the port with it, then don't use that parent!

          O 1 Reply Last reply
          0
          • JonBJ JonB

            @oBOXPOH
            Don't understand what you mean here. As @jsulm says, QSerialPort is asynchronous, you just don't usually need a thread, why do you need one? If you mean you are passing a parent to your QSerialPort which then goes out of scope taking the port with it, then don't use that parent!

            O Offline
            O Offline
            oBOXPOH
            wrote on last edited by
            #5

            @JonB said in QSerialPort and QThread:

            @oBOXPOH
            Don't understand what you mean here. As @jsulm says, QSerialPort is asynchronous, you just don't usually need a thread, why do you need one? If you mean you are passing a parent to your QSerialPort which then goes out of scope taking the port with it, then don't use that parent!

            I can use call to method for writing data instead of creating thread:

            if (isConnected)
                {
                    //thread->start();
            
                    task->readyWrite_slot();
                }
            

            but then I get only one WRITE message and no more, i.e. I can't reach method for reading.

            JonBJ 1 Reply Last reply
            0
            • O oBOXPOH

              @JonB said in QSerialPort and QThread:

              @oBOXPOH
              Don't understand what you mean here. As @jsulm says, QSerialPort is asynchronous, you just don't usually need a thread, why do you need one? If you mean you are passing a parent to your QSerialPort which then goes out of scope taking the port with it, then don't use that parent!

              I can use call to method for writing data instead of creating thread:

              if (isConnected)
                  {
                      //thread->start();
              
                      task->readyWrite_slot();
                  }
              

              but then I get only one WRITE message and no more, i.e. I can't reach method for reading.

              JonBJ Offline
              JonBJ Offline
              JonB
              wrote on last edited by
              #6

              @oBOXPOH
              Then if you have some "ready write" slot you can also write a "ready read" slot, https://doc.qt.io/qt-5/qiodevice.html#readyRead.

              O 1 Reply Last reply
              5
              • JonBJ JonB

                @oBOXPOH
                Then if you have some "ready write" slot you can also write a "ready read" slot, https://doc.qt.io/qt-5/qiodevice.html#readyRead.

                O Offline
                O Offline
                oBOXPOH
                wrote on last edited by
                #7

                @JonB said in QSerialPort and QThread:

                @oBOXPOH
                Then if you have some "ready write" slot you can also write a "ready read" slot, https://doc.qt.io/qt-5/qiodevice.html#readyRead.

                See before, I have it.

                void Thread::readyRead_slot()
                {
                    readData.append(serialPort->readAll());
                
                    if (readData.count() == 5)
                    {
                        readData.clear();
                        qDebug("READ");
                        emit readyWrite_signal();
                    }
                }
                

                Thread is just class. I don't use it like QThread. And I haven't readyRead() signal.

                1 Reply Last reply
                0
                • O oBOXPOH

                  Hello everyone!

                  I still trying to learn how to use QSerialPort correctly. And I am getting new problems.

                  I create QThread in some PARENT class:

                      thread = new QThread; // Create QThread
                  
                      task = new ThreadClass; // CHILD class, in which I have methods for reading and writing data with QSerialPort
                  
                      task->moveToThread(thread); // Move needed class to created thread
                      connect(thread, SIGNAL(started()), task, SLOT(writeData_slot()); // Connect to writeData_slot() method, when I will start the thread
                  

                  and I have in this PARENT class another method, where I want to start or stop (now there is while cycle for check) the thread:

                  if (isConnected)
                      {
                          thread->start();
                      }
                      else
                      {
                          int count = 0;
                  
                          while (count < 5)
                          {
                              count++;
                              QThread::msleep(1000);
                              qDebug("WE ARE HERE!");
                          }
                      }
                  

                  In CHILD class (for thread) I have two methods for reading and writing data with QSerialPort:

                  void Thread::readyWrite_slot()
                  {
                      serialPort->write(writeData);
                      qDebug("WRITE");
                      QThread::msleep(1000);
                  }
                  
                  void Thread::readyRead_slot()
                  {
                      readData.append(serialPort->readAll());
                  
                      if (readData.count() == 5)
                      {
                          readData.clear();
                          qDebug("READ");
                          emit readyWrite_signal();
                      }
                  }
                  
                      connect(serialPort, &QSerialPort::readyRead, this, &Thread::readyRead_slot);
                      connect(this, SIGNAL(readyWrite_signal()), SLOT(readyWrite_slot()));
                  

                  So, I start thread and get data, but when I want to stop getting data, I want to get all data last time, but I can't:

                  WRITE
                  READ // In CHILD Thread
                  WRITE
                  READ // In CHILD Thread
                  WRITE
                  READ // In CHILD Thread
                  WRITE
                  WE ARE HERE! // Here I want to close CHILD Thread in PARENT class
                  WE ARE HERE!
                  WE ARE HERE!
                  WE ARE HERE!
                  WE ARE HERE!
                  READ  // But only here I get my last data in CHILD Thread
                  WRITE
                  READ // 1 WRITE - 1 READ
                  WRITE
                  READ // 1 WRITE - 1 READ
                  WRITE
                  READ // 1 WRITE - 1 READ
                  WRITE
                  READ // 1 WRITE - 1 READ
                  

                  It means, that thread doesn't work parallel, but it's not true, because I wrote endless while cycle in readyWrite_slot() with message, for example, and got this message together with WE ARE HERE message. Then, my conclusion, I can't get readyRead() signal for some reason, but after cycle with WE ARE HERE message I continue get readyRead() signal. I don't close SerialPort, I just execute while() cycle 5 times and all. After that thread continues to work correctly.

                  So, I can't stop correctly my thread, because I can't get last data, but I need it. I don't know what I can do to fix it.

                  Hope for your help and advice! Thank you in advance!

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  @oBOXPOH said in QSerialPort and QThread:

                  Then, my conclusion, I can't get readyRead() signal for some reason

                  Yes, of course, you're calling QThread::Sleep all over the place. Every time you call that, no Signals will be processed, until the sleep is over.

                  I highly doubt, that you're programming (with Qt) for a micro controller -> do not use QThread::Sleep, at all.


                  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.

                  O 1 Reply Last reply
                  4
                  • J.HilkJ J.Hilk

                    @oBOXPOH said in QSerialPort and QThread:

                    Then, my conclusion, I can't get readyRead() signal for some reason

                    Yes, of course, you're calling QThread::Sleep all over the place. Every time you call that, no Signals will be processed, until the sleep is over.

                    I highly doubt, that you're programming (with Qt) for a micro controller -> do not use QThread::Sleep, at all.

                    O Offline
                    O Offline
                    oBOXPOH
                    wrote on last edited by oBOXPOH
                    #9

                    @J-Hilk said in QSerialPort and QThread:

                    @oBOXPOH said in QSerialPort and QThread:

                    Then, my conclusion, I can't get readyRead() signal for some reason

                    Yes, of course, you're calling QThread::Sleep all over the place. Every time you call that, no Signals will be processed, until the sleep is over.

                    I highly doubt, that you're programming (with Qt) for a micro controller -> do not use QThread::Sleep, at all.

                    Oh, it's, I think, really useful answer! Thank you! But can you then, please, tell me what I need to use to make some delay?

                    J.HilkJ 1 Reply Last reply
                    0
                    • O oBOXPOH

                      @J-Hilk said in QSerialPort and QThread:

                      @oBOXPOH said in QSerialPort and QThread:

                      Then, my conclusion, I can't get readyRead() signal for some reason

                      Yes, of course, you're calling QThread::Sleep all over the place. Every time you call that, no Signals will be processed, until the sleep is over.

                      I highly doubt, that you're programming (with Qt) for a micro controller -> do not use QThread::Sleep, at all.

                      Oh, it's, I think, really useful answer! Thank you! But can you then, please, tell me what I need to use to make some delay?

                      J.HilkJ Offline
                      J.HilkJ Offline
                      J.Hilk
                      Moderators
                      wrote on last edited by
                      #10

                      @oBOXPOH
                      That really depends on your situation, but one usually uses QTimer, or more conveniently one of the static single Shot variants for example
                      https://doc.qt.io/qt-5/qtimer.html#singleShot


                      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.

                      O 1 Reply Last reply
                      3
                      • J.HilkJ J.Hilk

                        @oBOXPOH
                        That really depends on your situation, but one usually uses QTimer, or more conveniently one of the static single Shot variants for example
                        https://doc.qt.io/qt-5/qtimer.html#singleShot

                        O Offline
                        O Offline
                        oBOXPOH
                        wrote on last edited by
                        #11

                        @J-Hilk said in QSerialPort and QThread:

                        @oBOXPOH
                        That really depends on your situation, but one usually uses QTimer, or more conveniently one of the static single Shot variants for example
                        https://doc.qt.io/qt-5/qtimer.html#singleShot

                        It's really bad, if another good way isn't exists.

                        Because developer needs to write such things instead of some sleep string:

                        QTimer::singleShot(100, this, SLOT(slot()));
                        

                        and developer need to create slot() method, where he writes all actions, which he want to execute after 100ms delay. And it's bad, if you want to make delay not in thread, because in thread you can use:

                        QThread::currentThread()->msleep(100);
                        

                        and not in thread - thing before with singleShot() method. I hope, I am wrong.

                        JonBJ jsulmJ 2 Replies Last reply
                        0
                        • O oBOXPOH

                          @J-Hilk said in QSerialPort and QThread:

                          @oBOXPOH
                          That really depends on your situation, but one usually uses QTimer, or more conveniently one of the static single Shot variants for example
                          https://doc.qt.io/qt-5/qtimer.html#singleShot

                          It's really bad, if another good way isn't exists.

                          Because developer needs to write such things instead of some sleep string:

                          QTimer::singleShot(100, this, SLOT(slot()));
                          

                          and developer need to create slot() method, where he writes all actions, which he want to execute after 100ms delay. And it's bad, if you want to make delay not in thread, because in thread you can use:

                          QThread::currentThread()->msleep(100);
                          

                          and not in thread - thing before with singleShot() method. I hope, I am wrong.

                          JonBJ Offline
                          JonBJ Offline
                          JonB
                          wrote on last edited by JonB
                          #12

                          @oBOXPOH
                          It's not "bad". Signals/slots/event-driven is a different architectural design from linear "sleep" approach. Many SDKs or languages use this approach these days, it has its advantages.

                          Experts may not thank me for mentioning this, but if you really want to you may be able to use a "sleep"-type and still allow signals/slots/events if you use QEventLoop + QTimer in your thread. You'd have to try it.

                          1 Reply Last reply
                          4
                          • O oBOXPOH

                            @J-Hilk said in QSerialPort and QThread:

                            @oBOXPOH
                            That really depends on your situation, but one usually uses QTimer, or more conveniently one of the static single Shot variants for example
                            https://doc.qt.io/qt-5/qtimer.html#singleShot

                            It's really bad, if another good way isn't exists.

                            Because developer needs to write such things instead of some sleep string:

                            QTimer::singleShot(100, this, SLOT(slot()));
                            

                            and developer need to create slot() method, where he writes all actions, which he want to execute after 100ms delay. And it's bad, if you want to make delay not in thread, because in thread you can use:

                            QThread::currentThread()->msleep(100);
                            

                            and not in thread - thing before with singleShot() method. I hope, I am wrong.

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

                            @oBOXPOH You are using an event driven framework (Qt is not the only one by the way). In such frameworks you should never block the event loop with long lasting loops and sleep() calls. This is simply working against the framework.

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

                            1 Reply Last reply
                            5

                            • Login

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