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. Why serialport invokes readAll() twice or more?
Forum Updated to NodeBB v4.3 + New Features

Why serialport invokes readAll() twice or more?

Scheduled Pinned Locked Moved General and Desktop
12 Posts 4 Posters 4.3k 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.
  • jensen82J Offline
    jensen82J Offline
    jensen82
    wrote on last edited by
    #2

    Hi! I have the same problems and still waiting for an answer. Please let me know if you found something. I also will inform you if i got something.

    1 Reply Last reply
    0
    • C Offline
      C Offline
      Cancer
      wrote on last edited by
      #3

      [quote author="jensen82" date="1395086841"]Hi! I have the same problems and still waiting for an answer. Please let me know if you found something. I also will inform you if i got something.[/quote]
      Okay, will inform you

      1 Reply Last reply
      0
      • A Offline
        A Offline
        andreyc
        wrote on last edited by
        #4

        I'm not a QSerialPort expert, just a wild guess.

        If you try to send the same data without Qt, something like
        @
        echo "123456789" > /dev/ttyS0 # or what ever serial port devices you have
        @

        Does it respond in one string without any delays?

        1 Reply Last reply
        0
        • C Offline
          C Offline
          Cancer
          wrote on last edited by
          #5

          If I use another terminal it returns whole string at one time.
          I cannot send any data from cmd, don't know why

          1 Reply Last reply
          0
          • jensen82J Offline
            jensen82J Offline
            jensen82
            wrote on last edited by
            #6

            Oh...i forgot to mention that i already have a workaround for it. I create a class member QByteArray m_data. If i send a message i clear the bytearray and on receive i simply append the data. So it's clear.

            The next step is to check if the message is completed by checking that the first token is STX-Start of transmission and check that the last received token is EOT-End of transmission and if possible, check the checksum.

            The easiest way is to append on receive and clear the receice buffer after you send your request.

            1 Reply Last reply
            0
            • C Offline
              C Offline
              Cancer
              wrote on last edited by
              #7

              I must receive continous sending data from device. I thinked about start-stop bits

              1 Reply Last reply
              0
              • A Offline
                A Offline
                andreyc
                wrote on last edited by
                #8

                I guess it is related to the fact that CPU is much faster than a serial port.

                QSerialPort reads data in a loop (see below) and if result is 0 then loop is finished. It is possible that some bits come a microsecond late and call to read() will return 0. Next call to readAll() will pickup the next set of bits.

                I think the approach that jensen82 uses is the only solution here if you have send/recv cycle.

                • Qt5.2.1/5.2.1/Src/qtbase/src/corelib/io/qiodevice.cpp
                  @
                  if (d->isSequential() || (theSize = size()) == 0) {
                  // Size is unknown, read incrementally.
                  qint64 readResult;
                  do {
                  result.resize(result.size() + QIODEVICE_BUFFERSIZE);
                  readResult = read(result.data() + readBytes, result.size() - readBytes);
                  if (readResult > 0 || readBytes == 0)
                  readBytes += readResult;
                  } while (readResult > 0);
                  } else {
                  @
                1 Reply Last reply
                0
                • C Offline
                  C Offline
                  Cancer
                  wrote on last edited by
                  #9

                  okay, will try tomorrow, thanks

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Cancer
                    wrote on last edited by
                    #10

                    Okay, can I workaround this behaviour of qiodevice?
                    I must get whole packet not only when I sent anything to port.

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

                      This is normal behavior!

                      QtSerialPort works in a non-blocking asynchronous mode (on event-based mode) when operation of reading comes back immediately.

                      In this case, in case of origin of an EV_RXCHAR event, the internal logic of class reads all data from the FIFO (which available in FIFO in current moment) in the internal buffer of a class, and emit readyRead().

                      So, the method readAll() (or any read()) just return the content of the internal read buffer; the method bytesAvailable() - returns a size of the internal read buffer. And do nothing anymore.

                      To learn that a whole packet is received can be do:

                      1. Call the bytesAvailable() in each readyRead() and do nothing more. In case bytesAvailable() == expectedLength we can be sure that package is received and then we can do read and process package.

                      2. At first trigger of the readyRead() can be run the QTimer. The timeout() signal will be signalize to us that package is received or occured an timeout error (depends on your handling way).

                      3. Use the some communication protocol, where can be specified the size of the package, and, maybe, other control fields.. In this case also can be combine way 1 and 2 and something else.

                      Anyway, the behavior of QtSerialPort is a streaming mode, where there is no concept of the beginning and the end of packet. You shall define it independently, having selected your specific solution of handling.

                      1 Reply Last reply
                      0
                      • C Offline
                        C Offline
                        Cancer
                        wrote on last edited by
                        #12

                        Good, I will use some kind of protocol, where I will set end byte. So, thank you!

                        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