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's read buffer is always empty while running another func.
Forum Updated to NodeBB v4.3 + New Features

QSerialPort's read buffer is always empty while running another func.

Scheduled Pinned Locked Moved Unsolved General and Desktop
40 Posts 6 Posters 12.7k 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
    Gokhan
    wrote on last edited by Gokhan
    #4

    Well, there are two classes in my project, one is GUI class and a form application, other is serial_port class and it makes the opening, closing, receiving, writing etc. about the port, briefly this class provides the communication between PC and MCU through the serial port.

    When the Gui application starts, the serial port's threat immediately runs for a millisecond and it calls serial_port :: readData () is in my above message via Qtconcurrent function in run function. So I can read buffer every a millisecond.

    By the way, the GUI window has a few button in order to make process with data. For example, one provides for decoding the data which have just received from the port. Other provides for starting the windows console (cmd.exe) and makes something about the application via it. If this event takes a long time (e.g. proc.waitReadyRead function takes a long time sometimes.), then the serial port thread always shows the read buffer to be empty. However, the thread normally continues the running for a millisecond. (I use the clicked event for these buttons.)

    A 1 Reply Last reply
    0
    • G Gokhan

      Well, there are two classes in my project, one is GUI class and a form application, other is serial_port class and it makes the opening, closing, receiving, writing etc. about the port, briefly this class provides the communication between PC and MCU through the serial port.

      When the Gui application starts, the serial port's threat immediately runs for a millisecond and it calls serial_port :: readData () is in my above message via Qtconcurrent function in run function. So I can read buffer every a millisecond.

      By the way, the GUI window has a few button in order to make process with data. For example, one provides for decoding the data which have just received from the port. Other provides for starting the windows console (cmd.exe) and makes something about the application via it. If this event takes a long time (e.g. proc.waitReadyRead function takes a long time sometimes.), then the serial port thread always shows the read buffer to be empty. However, the thread normally continues the running for a millisecond. (I use the clicked event for these buttons.)

      A Offline
      A Offline
      ambershark
      wrote on last edited by
      #5

      @Gokhan I don't see anything in what you said that let me figure out what's going on. You'll have to share the relevant parts of your code in order for us to help you more I think.

      Also, side note on threading.. Running a thread every 1ms is too aggressive imo. Most schedulers can't even swap threads out that fast. So your thread is basically at 100% run time. If you actually want to let the CPU rest for that thread you need to lower that time. I find I never go below 100ms for thread sleeps as that tends to be near the edge of context switching by most CPUs.

      The other potential of a 1ms sleep is that you are actually getting much more than 1ms. Again this is because the thread context swaps can't happen that fast.

      That method of threading is called polling and it isn't a good way to do things in the modern world. Qt provides signals for when there is data to be read from the QIODevice. If you handle this signal, you don't even need a timeout to kickoff the thread.

      My L-GPL'd C++ Logger github.com/ambershark-mike/sharklog

      1 Reply Last reply
      2
      • G Offline
        G Offline
        Gokhan
        wrote on last edited by Gokhan
        #6

        @ambershark Many thanks for your reply.
        I can't share all codes because they are at office's PC. I'm wondering a thing what you said about the signal method. If I also don't use thread method to read the buffer, can I all read the data only a signal method without missing?

        In addition to, e.g I'm using the console (cmd.exe) in order to move folder is huge size. After I started cmd code to move it somewhere, it immediately has the finished event. However, I want it to give me an event after it finished the data transfer. So, I can use any signals method to do it? e.g can readyReadStandardOutput() be? I guess that if I can use this method, it will be the good way to do this like you have mentioned above. Isn't it?

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #7

          Can you show the code you use for that ?

          Interested in AI ? www.idiap.ch
          Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

          1 Reply Last reply
          0
          • G Offline
            G Offline
            Gokhan
            wrote on last edited by Gokhan
            #8

            I have just checked for a new application and have the same problem. e.g. I'm using an external cmd.exe file to convert the images to bytes. I start the first conversion via a button.

            void image_down_dialog::on_convertButton_clicked()
            {
                QStringList arguments;
                QString com=QString("/k img_cvt  -i  %1   -f   0").arg(img_down[0].image_with_ext);
                arguments <<com;
                QDir::setCurrent("D://conv");
                QProcess aa ;
            
                aa.start("cmd.exe",arguments);
                proc = &aa;
            
                connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                        this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
            }
            
            void image_down_dialog::finishProcess ( int exitCode, QProcess::ExitStatus exitStatus )
            {
              QString com=QString("/k img_cvt  -i  %1   -f   0").arg(img_down[idxProcess].image_with_ext);
              arguments <<com;
              QDir dir;
              dir.setCurrent("D:/conv");
              QProcess proc;
              proc.start("cmd.exe",arguments);
            
               connect(&proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                            this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
            
            //I write proc.waitForFinished(100) to here ..
            }
            

            After I start the conversion, the process immediately gives me the finished event. Actually, it's still running, not finished. However, if I use "proc.waitForFinished(100);" in the finished event, then it normally completes them. I have to give 100 milliseconds to wait for finished otherwise, it can't finish again.

            J.HilkJ 1 Reply Last reply
            0
            • G Gokhan

              I have just checked for a new application and have the same problem. e.g. I'm using an external cmd.exe file to convert the images to bytes. I start the first conversion via a button.

              void image_down_dialog::on_convertButton_clicked()
              {
                  QStringList arguments;
                  QString com=QString("/k img_cvt  -i  %1   -f   0").arg(img_down[0].image_with_ext);
                  arguments <<com;
                  QDir::setCurrent("D://conv");
                  QProcess aa ;
              
                  aa.start("cmd.exe",arguments);
                  proc = &aa;
              
                  connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                          this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
              }
              
              void image_down_dialog::finishProcess ( int exitCode, QProcess::ExitStatus exitStatus )
              {
                QString com=QString("/k img_cvt  -i  %1   -f   0").arg(img_down[idxProcess].image_with_ext);
                arguments <<com;
                QDir dir;
                dir.setCurrent("D:/conv");
                QProcess proc;
                proc.start("cmd.exe",arguments);
              
                 connect(&proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                              this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
              
              //I write proc.waitForFinished(100) to here ..
              }
              

              After I start the conversion, the process immediately gives me the finished event. Actually, it's still running, not finished. However, if I use "proc.waitForFinished(100);" in the finished event, then it normally completes them. I have to give 100 milliseconds to wait for finished otherwise, it can't finish again.

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

              @Gokhan

              mmh maybe an error occurred during exe? that would probably result in a finished Signal.

              What does qDebug() say, if you write something like this?

              QString com=QString("/k img_cvt  -i  %1   -f   0").arg(img_down[idxProcess].image_with_ext);
                arguments <<com;
                QDir dir;
                dir.setCurrent("D:/conv");
                QProcess proc;
              
                 connect(&proc, & QProcess::errorOccurred, &proc,[=](QProcess::ProcessError error){qDebug() <<"Process had an error:" <<  error; });
                 connect(&proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                              this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
                 proc.start("cmd.exe",arguments);
              

              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
              • SGaistS Offline
                SGaistS Offline
                SGaist
                Lifetime Qt Champion
                wrote on last edited by
                #10

                In both your methods, your QProcess objects are local on the stack. They'll be destroyed at the end of the methods and will likely not have finished at that point.

                Also, you argument list doesn't look right, you are trying to put everything on one line. You should put each element separately in the QStringList object.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                1 Reply Last reply
                4
                • G Offline
                  G Offline
                  Gokhan
                  wrote on last edited by
                  #11

                  @J-Hilk Yes. it gives the "Crashed" error and "Destroyed while process ("cmd.exe") is still running." What can I do to solve this?
                  @SGaist I know they are a local variable, I can't use a global variable. I tried to use a global variable instead of them, this time it never gave the finished event. I guess I didn't completely connect this signal. Also, this argument list is running like I want, if I write the waiting function...

                  J.HilkJ 1 Reply Last reply
                  0
                  • SGaistS Offline
                    SGaistS Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on last edited by
                    #12

                    There's no need for global variables. Since you'll be using these commands several times, just keep them as member variables and setup them once in your dialog constructor.

                    Then you can re-use them as needed.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    1 Reply Last reply
                    2
                    • G Gokhan

                      @J-Hilk Yes. it gives the "Crashed" error and "Destroyed while process ("cmd.exe") is still running." What can I do to solve this?
                      @SGaist I know they are a local variable, I can't use a global variable. I tried to use a global variable instead of them, this time it never gave the finished event. I guess I didn't completely connect this signal. Also, this argument list is running like I want, if I write the waiting function...

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

                      @Gokhan said in QSerialPort's read buffer is always empty while running another func.:

                      @J-Hilk Yes. it gives the "Crashed" error and "Destroyed while process ("cmd.exe") is still running." What can I do to solve this?
                      @SGaist I know they are a local variable, I can't use a global variable. I tried to use a global variable instead of them, this time it never gave the finished event. I guess I didn't completely connect this signal. Also, this argument list is running like I want, if I write the waiting function...

                      Actually, that are to be expected error messages, for reasons, @SGaist explained!

                      QProgress does not have to be global to work e.g:

                      QString com=QString("/k img_cvt  -i  %1   -f   0").arg(img_down[idxProcess].image_with_ext);
                        arguments <<com;
                        QDir dir;
                        dir.setCurrent("D:/conv");
                        QProcess *proc = new QProcess();
                      
                         connect(proc, & QProcess::errorOccurred, proc,[=](QProcess::ProcessError error){qDebug() <<"Process had an error:" <<  error; });
                         connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                                      this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
                        connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), proc, SLOT(deleteLater()));
                         proc->start("cmd.exe",arguments);
                      

                      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
                      0
                      • G Offline
                        G Offline
                        Gokhan
                        wrote on last edited by Gokhan
                        #14

                        @SGaist and @J-Hilk many thank your reply.
                        I'm using the proc variable as a member variable that is decelerated and initialized in class. "QProcess *proc = new QProcess();" like you said. However, it never gave the finish event. Why don't I get any event?
                        And when I re-click the button, it gives an error that is "QProcess::start: Process is already running",

                        void image_down_dialog::on_convertButton_clicked()
                        {
                            idxProcess = 0;
                            find_all_imgs();
                        
                            QStringList arguments;
                            QString com=QString("/k img_cvt  -i  %1   -f   0").arg(img_down[0].image_with_ext);
                            arguments <<com;
                            QDir::setCurrent("D:/User Interface/GUI_660_HMI/conv");
                        
                            connect(proc, & QProcess::errorOccurred, proc,[=](QProcess::ProcessError error){qDebug() <<"Process had an error:" <<  error; });
                            connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                                    this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
                            connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), proc, SLOT(deleteLater()));
                        
                            proc->start("cmd.exe",arguments);
                        }
                        
                        J.HilkJ 1 Reply Last reply
                        0
                        • G Gokhan

                          @SGaist and @J-Hilk many thank your reply.
                          I'm using the proc variable as a member variable that is decelerated and initialized in class. "QProcess *proc = new QProcess();" like you said. However, it never gave the finish event. Why don't I get any event?
                          And when I re-click the button, it gives an error that is "QProcess::start: Process is already running",

                          void image_down_dialog::on_convertButton_clicked()
                          {
                              idxProcess = 0;
                              find_all_imgs();
                          
                              QStringList arguments;
                              QString com=QString("/k img_cvt  -i  %1   -f   0").arg(img_down[0].image_with_ext);
                              arguments <<com;
                              QDir::setCurrent("D:/User Interface/GUI_660_HMI/conv");
                          
                              connect(proc, & QProcess::errorOccurred, proc,[=](QProcess::ProcessError error){qDebug() <<"Process had an error:" <<  error; });
                              connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                                      this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
                              connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)), proc, SLOT(deleteLater()));
                          
                              proc->start("cmd.exe",arguments);
                          }
                          
                          J.HilkJ Offline
                          J.HilkJ Offline
                          J.Hilk
                          Moderators
                          wrote on last edited by
                          #15

                          @Gokhan
                          ok first, if you make QProcess a member variable, move the connects into the constructor:

                          QProcess *proc = new QProcess();
                          connect(proc, & QProcess::errorOccurred, proc,[=](QProcess::ProcessError error){qDebug() <<"Process had an error:" <<  error; });
                          connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                                      this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
                          

                          or you get problems when you press the button more than once.

                          also the deleteLater has to be moved to the destructor or you can use your QProcess object only once.

                          ~MyClass(){
                             proc->deleteLater();
                          }
                          

                          Why don't I get any event?
                          And when I re-click the button, it gives an error that is "QProcess::start: Process is already running",

                          it would seem your process is still running right?


                          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.

                          VRoninV 1 Reply Last reply
                          0
                          • J.HilkJ J.Hilk

                            @Gokhan
                            ok first, if you make QProcess a member variable, move the connects into the constructor:

                            QProcess *proc = new QProcess();
                            connect(proc, & QProcess::errorOccurred, proc,[=](QProcess::ProcessError error){qDebug() <<"Process had an error:" <<  error; });
                            connect(proc, SIGNAL(finished(int, QProcess::ExitStatus)),
                                        this, SLOT(finishProcess(int, QProcess::ExitStatus)) );
                            

                            or you get problems when you press the button more than once.

                            also the deleteLater has to be moved to the destructor or you can use your QProcess object only once.

                            ~MyClass(){
                               proc->deleteLater();
                            }
                            

                            Why don't I get any event?
                            And when I re-click the button, it gives an error that is "QProcess::start: Process is already running",

                            it would seem your process is still running right?

                            VRoninV Offline
                            VRoninV Offline
                            VRonin
                            wrote on last edited by
                            #16

                            @J.Hilk said in QSerialPort's read buffer is always empty while running another func.:

                            also the deleteLater has to be moved to the destructor

                            If you pass the parent in the constructor there is no need to manually do this

                            "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
                            ~Napoleon Bonaparte

                            On a crusade to banish setIndexWidget() from the holy land of Qt

                            J.HilkJ 1 Reply Last reply
                            0
                            • VRoninV VRonin

                              @J.Hilk said in QSerialPort's read buffer is always empty while running another func.:

                              also the deleteLater has to be moved to the destructor

                              If you pass the parent in the constructor there is no need to manually do this

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

                              @VRonin true, but @Gokhan said

                              I'm using the proc variable as a member variable that is decelerated and initialized in class. "QProcess *proc = new QProcess();"

                              So in this particular case the deleteLater() is needed. More convenient would of course be to give QProcess a parent.


                              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
                              0
                              • G Offline
                                G Offline
                                Gokhan
                                wrote on last edited by
                                #18

                                @J-Hilk I did them you said, but the result is the same. It never gives the finished event, so it is always running.

                                jsulmJ 1 Reply Last reply
                                0
                                • G Gokhan

                                  @J-Hilk I did them you said, but the result is the same. It never gives the finished event, so it is always running.

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

                                  @Gokhan Please read again what @SGaist wrote: each argument should be in its own string. You, instead, put all parameters into one string.

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

                                  1 Reply Last reply
                                  0
                                  • G Offline
                                    G Offline
                                    Gokhan
                                    wrote on last edited by Gokhan
                                    #20

                                    @jsulm "/k img_cvt -i %1 -f 0" this is a one line command, so it has to write in one line. While I was also manually using this cmd application before, using it the same. Also, it successfully completes the conversion and creates a new folder within hex code. However, it never gives the finished information, it is continuous running to finish. I can see it's still running when re-click the button.

                                    jsulmJ 1 Reply Last reply
                                    0
                                    • G Gokhan

                                      @jsulm "/k img_cvt -i %1 -f 0" this is a one line command, so it has to write in one line. While I was also manually using this cmd application before, using it the same. Also, it successfully completes the conversion and creates a new folder within hex code. However, it never gives the finished information, it is continuous running to finish. I can see it's still running when re-click the button.

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

                                      @Gokhan said in QSerialPort's read buffer is always empty while running another func.:

                                      /k img_cvt -i %1 -f 0

                                      Wrong it consists of several parameters: "/k" "img_cvt" "-i" "%1" "-f" "0"

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

                                      1 Reply Last reply
                                      2
                                      • G Offline
                                        G Offline
                                        Gokhan
                                        wrote on last edited by Gokhan
                                        #22

                                        That is a part of the user manual. I don't know how to use it like you said? However, it's normally running if use the waitforfinish function like I have mentioned above.

                                        The usage is : 
                                            img_cvt  -i  inputfilename  -f  format
                                        
                                                 format is as follow:
                                                    0 : ARGB1555 [default]
                                                    1 : L1
                                                    2 : L4
                                                    3 : L8
                                                    4 : RGB332
                                                    5 : ARGB2
                                                    6 : ARGB4
                                                    7 : RGB565
                                                    8 : PALETTEED [FT80X only]    
                                                    9 : L2 [FT81X only]
                                        
                                        Example : 
                                            img_cvt  -i  lenaface40.png  -f   8
                                        
                                        
                                        jsulmJ 1 Reply Last reply
                                        0
                                        • G Gokhan

                                          That is a part of the user manual. I don't know how to use it like you said? However, it's normally running if use the waitforfinish function like I have mentioned above.

                                          The usage is : 
                                              img_cvt  -i  inputfilename  -f  format
                                          
                                                   format is as follow:
                                                      0 : ARGB1555 [default]
                                                      1 : L1
                                                      2 : L4
                                                      3 : L8
                                                      4 : RGB332
                                                      5 : ARGB2
                                                      6 : ARGB4
                                                      7 : RGB565
                                                      8 : PALETTEED [FT80X only]    
                                                      9 : L2 [FT81X only]
                                          
                                          Example : 
                                              img_cvt  -i  lenaface40.png  -f   8
                                          
                                          
                                          jsulmJ Offline
                                          jsulmJ Offline
                                          jsulm
                                          Lifetime Qt Champion
                                          wrote on last edited by jsulm
                                          #23

                                          @Gokhan
                                          Just pass each parameter as one string in the string list (as shown here http://doc.qt.io/qt-5/qprocess.html):

                                          arguments <<"/k"<<"img_cvt"<<"-i"<<QString(%1).arg(img_down[0].image_with_ext)<<"-f"<<"0";
                                          

                                          Also you should connect http://doc.qt.io/qt-5/qprocess.html#errorOccurred signal to a slot to check whether something went wrong.

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

                                          1 Reply Last reply
                                          2

                                          • Login

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