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. When does QSerialPort send data from the buffer to the serial interface?

When does QSerialPort send data from the buffer to the serial interface?

Scheduled Pinned Locked Moved Solved General and Desktop
qserialportbufferserial interfac
13 Posts 4 Posters 17.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.
  • S Offline
    S Offline
    SGaist
    Lifetime Qt Champion
    wrote on 4 Nov 2015, 13:45 last edited by
    #3

    Hi,

    Did you check that you currently have the correct permission to write to the device ?

    For the code formatting the @ as been replaced by ``` (three back ticks)

    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 Nov 2015, 15:08
    0
    • R Offline
      R Offline
      Rondog
      wrote on 4 Nov 2015, 14:33 last edited by
      #4

      I have experieced part of what you described.

      Using the older ExtSerialPort (external to Qt) the data sent out the serial port was not buffered (except on Windows for some reason ?).

      Using QSerialPort built into Qt5 the data is buffered. You need to be careful about certain things if there is any protocol or handshaking you are trying to follow. I have QSerialPort in a separate thread and using waitForBytesWritten(-1) makes sure the data is sent and everything is in sync.

      I have not used the 'flush' command. Likely it will simply block until the buffer is emptied anyway (I hope). I wouldn't expect you would loose data though. If you close the serial port before the buffer is emptied you will loose whatever has not been sent (calling 'flush' then 'close' might delete data if 'flush' does not wait until all the data is actually sent).

      You can change the buffer size by the way. I am aware that you can do this but I didn't go this route when I ran into buffer problems. It might be the best option if you set the buffer size really small or zero in your case.

      1 Reply Last reply
      0
      • M mrdebug
        4 Nov 2015, 13:40

        I assure QSerialPort works perfectly.
        I suggest to do not use signals but qthread to manage read and write.
        Are you sure is not a problem related to the hardware interface? Is a full duplex interface or half duplex (485)?

        ? Offline
        ? Offline
        A Former User
        wrote on 4 Nov 2015, 15:00 last edited by A Former User 11 Apr 2015, 15:16
        #5

        Thanks for your answers!

        @mrdebug Using it as in my code snippet, everything works perfect, indeed. Problems only arise when using the flush method or no waitForBytesWritten(). Also, http://doc.qt.io/qt-5/qserialport.html#flush states that in the absence of an event loop one should use waitForBytesWritten(). I'm not a Qt expert, but I think that there should be an event loop in my case (at least for reacting on GUI button press events). So I was asking myself if there would be more documentation on this and didn't find any so far.
        I don't think that it is a problem with the hardware, since transmission obviously works. Yet it could be a problem with the g_serial driver I use. This is a gadget driver (Linux) using USB as a virtual serial interface.
        Thanks for the hint with the qthread - will have a look at threads in qt also.

        1 Reply Last reply
        1
        • S SGaist
          4 Nov 2015, 13:45

          Hi,

          Did you check that you currently have the correct permission to write to the device ?

          For the code formatting the @ as been replaced by ``` (three back ticks)

          ? Offline
          ? Offline
          A Former User
          wrote on 4 Nov 2015, 15:08 last edited by
          #6

          @SGaist I think it is not a problem with permissions, since using the above code works. Also flushing using the flush method obviously works, but causing problems on the data.
          Thanks for the hint with ``` - I've already updated the code in my post! Is there also some help page on features like this of the forum?

          @Rondog Maybe writing to the buffer is blocked when it is being flushed and the write function can sometimes write only part of the data to it?
          How can I change the write buffer size? On http://doc.qt.io/qt-5/qserialport.html I've only found a method for changing the read buffer size...

          R 1 Reply Last reply 4 Nov 2015, 23:14
          0
          • S Offline
            S Offline
            SGaist
            Lifetime Qt Champion
            wrote on 4 Nov 2015, 21:14 last edited by
            #7

            Sorry, I misread your problem. One thing you can try before starting with thread is to use the bytesWritten signal to trigger the following write

            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
            • ? A Former User
              4 Nov 2015, 15:08

              @SGaist I think it is not a problem with permissions, since using the above code works. Also flushing using the flush method obviously works, but causing problems on the data.
              Thanks for the hint with ``` - I've already updated the code in my post! Is there also some help page on features like this of the forum?

              @Rondog Maybe writing to the buffer is blocked when it is being flushed and the write function can sometimes write only part of the data to it?
              How can I change the write buffer size? On http://doc.qt.io/qt-5/qserialport.html I've only found a method for changing the read buffer size...

              R Offline
              R Offline
              Rondog
              wrote on 4 Nov 2015, 23:14 last edited by
              #8

              @MarkusBraitner You are right about having access only to the read buffer; I forgot about that one. Putting it in a thread with a blocking waitForBytesWritten() works well, just don't forget to call the event loop on occasion.

              I noticed similarities when using other methods like QTcpSocket. With QTcpSocket the data is sent very fast so you generally don't notice any buffering but I have had problems with data being truncated intermittently which was a real head scratcher (it was due to closing the connection before the write buffer was emptied; it only happened once in a while which made it hard to track down).

              1 Reply Last reply
              0
              • ? Offline
                ? Offline
                A Former User
                wrote on 5 Nov 2015, 09:38 last edited by
                #9

                @SGaist No problem. Thanks for the hint with the bytesWritten signal!

                @Rondog Thanks for sharing your experience on qTcpSocket with me! Yes, I've already read for QSerialPort that one has to be careful not to close the interface before the buffer has been flushed.

                1 Reply Last reply
                0
                • ? Offline
                  ? Offline
                  A Former User
                  wrote on 5 Nov 2015, 16:46 last edited by
                  #10

                  In case somebody else finds it useful, these are the solutions that I've tried out now, and which work:

                  • Using waitForBytesWritten() after each call to write() as in the code above (blocking)
                  • Constructing a QByteArray of the whole file to send using the append() method and writing it to the buffer as a whole. The interface closing is triggered by the bytesWritten signal when there are no more bytes in the write buffer left. My code is as follows:
                  void MainWindow::on_pushButton_clicked()
                  {
                  
                      if(!(serial == 0)){
                          qDebug() << "interface currently busy...";
                      }
                      else{
                          serial = new QSerialPort(this);
                          connect(serial, &QIODevice::bytesWritten, this, &MainWindow::closeSerialPort);
                          openSerialPort();
                          QFile file("/user_data/big2.txt");
                          if (!file.open(QIODevice::ReadOnly)) return;
                          writeData(testdata);
                          QByteArray testdata;
                          while (!file.atEnd()){
                              QByteArray testdata_a = file.readLine();
                              testdata.append(testdata_a);
                          }
                          serial->write(testdata_a);
                        }
                      }
                  }
                  
                  void MainWindow::openSerialPort()
                  {
                      serial->setPortName("/dev/ttyGS0");
                      serial->setBaudRate(9600);
                      serial->setDataBits(QSerialPort::Data8);
                      serial->setParity(QSerialPort::NoParity);
                      serial->setStopBits(QSerialPort::OneStop);
                      serial->setFlowControl(QSerialPort::NoFlowControl);
                      if(serial->open(QIODevice::ReadWrite)) {
                      } else {
                  //        qDebug() << "Error opening serial port...";
                      }
                  }
                  
                  void MainWindow::closeSerialPort()
                  {
                      if(!serial->bytesToWrite()){
                          serial->close();
                          // Set interface object pointer to zero
                          serial = 0;
                      }
                  }
                  }
                  
                  • Using the linux command "cat" to directly copy the file via shell command. This is blocking and i guess could also go to a thread.
                  QProcess process;
                      QString command = "/bin/sh";
                      QStringList args;
                      args << "-c" << "cat /user_data/big2.txt > /dev/ttyGS0";
                      process.start(command, args, QIODevice::ReadOnly);
                      process.waitForFinished();
                      QString StdOut = process.readAllStandardOutput();
                      QString StdErr = process.readAllStandardError();
                      qDebug() << StdOut;
                      qDebug() << StdErr;
                  
                  • same as last item, but using the system() function (also blocking):
                  system("cat /user_data/big2.txt > /dev/ttyGS0");
                  

                  Obviously, writing to the write buffer while it is being flushed, causes problems.

                  Also, I have found two docu pages, which seem helpful - don't know, why I didn't find them before...

                  • http://doc.qt.io/qt-5/qtserialport-terminal-example.html (non-blocking approach)
                  • http://doc.qt.io/qt-5/qtserialport-blockingslave-example.html (blocking approach)

                  Kind regards,

                  Markus

                  1 Reply Last reply
                  1
                  • S Offline
                    S Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 5 Nov 2015, 20:47 last edited by
                    #11

                    Since you will dump the content of the file anyway, why not use: serial->write(file.readAll()); directly ?

                    Your QProcess solution is blocking because you call waitForFinished. If you want it to run without blocking just drop that call, allocate QProcess on the heap and handle the rest through signals and slots.

                    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
                    • ? Offline
                      ? Offline
                      A Former User
                      wrote on 6 Nov 2015, 08:37 last edited by
                      #12

                      @SGaist Good hint with the direct call :-) Sometimes one is just immersed into coding and overlooks the obvious... :-)
                      Yes, I was aware of the fact that waitForFinished makes it blocking. But thanks for your hint to allocate QProcess on the heap! Will eventually also try it.

                      In the meanwhile I've also found the forum guide at https://forum.qt.io/topic/52200/forum-general-guide, explaining me also the use of the voting buttons (since there are no tooltips available for them, I could only guess that they could be voting buttons) ;-) So I could give you some votes to say thank you for your help now :-)

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on 6 Nov 2015, 20:28 last edited by
                        #13

                        I didn't saw that there was no tooltip for them… At least there is for the flag and quote :)

                        Thanks :)

                        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

                        12/13

                        6 Nov 2015, 08:37

                        • Login

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