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. Qt SerialPort.canReadLine() ?

Qt SerialPort.canReadLine() ?

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 5 Posters 9.2k 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.
  • J.HilkJ Online
    J.HilkJ Online
    J.Hilk
    Moderators
    wrote on last edited by
    #2

    Hi,

    Take a look at the docu here:

    Note that unbuffered devices, which have no way of determining what can be read, always return false.

    You have an unbuffered device conncted to your serial port.

    Seems obvious enough :)


    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
    1
    • M Offline
      M Offline
      mostefa
      wrote on last edited by
      #3

      Hi @Ongsk

      Qt Serial port canReadLine() doc says:

      http://doc.qt.io/qt-5/qiodevice.html#canReadLine

      Returns true if a complete line of data can be read from the device; otherwise returns false.

      Note that unbuffered devices, which have no way of determining what can be read, always return false.
      

      This function is often called in conjunction with the readyRead() signal.

      Could you add :

      qDebug() << m_Port->readall(); just inside your readData() Function

      Like that:

      void Work::readData()
      {
      qDebug() << m_Port->readall();
      while...
      .
      .
      .
      }
      
      O 1 Reply Last reply
      0
      • J.HilkJ J.Hilk

        Hi,

        Take a look at the docu here:

        Note that unbuffered devices, which have no way of determining what can be read, always return false.

        You have an unbuffered device conncted to your serial port.

        Seems obvious enough :)

        O Offline
        O Offline
        Ongsk
        wrote on last edited by
        #4

        @J.Hilk

        I am no quite sure what do you meant by unbuffered Device. The command that I sent example RT0100003054CRLF
        meaning start Address 0100
        number of word are 30
        Checksum 54
        So the Device will return header + 30 words + Checksum +CRLF

        Well May be I should test the device for
        enum QIODevice::OpenModeFlag
        flags QIODevice::OpenMode

        thks

        1 Reply Last reply
        0
        • M mostefa

          Hi @Ongsk

          Qt Serial port canReadLine() doc says:

          http://doc.qt.io/qt-5/qiodevice.html#canReadLine

          Returns true if a complete line of data can be read from the device; otherwise returns false.

          Note that unbuffered devices, which have no way of determining what can be read, always return false.
          

          This function is often called in conjunction with the readyRead() signal.

          Could you add :

          qDebug() << m_Port->readall(); just inside your readData() Function

          Like that:

          void Work::readData()
          {
          qDebug() << m_Port->readall();
          while...
          .
          .
          .
          }
          
          O Offline
          O Offline
          Ongsk
          wrote on last edited by
          #5

          @mostefa

          Hi
          By removing the while loop without checking the status of canReadLine,
          I am able to get the return from the serial device.

          I am more interested if I can apply the readline method.

          Any Idea?

          Thks

          1 Reply Last reply
          0
          • M Offline
            M Offline
            mostefa
            wrote on last edited by
            #6

            @Ongsk

            as i already said before,

            Could you add :

            qDebug() << m_Port->readall(); just inside your readData() Function
            

            Like that:

            void Work::readData()
            {
            qDebug() << m_Port->readall();
            while...
            .
            .
            .
            }
            

            And return us the result?

            I think that your data is coming in this way ,for example

            first packet "RT0100"
            second packet "003054CR"

            third packet "LF"

            i think that you should use a buffer

            O 1 Reply Last reply
            0
            • M mostefa

              @Ongsk

              as i already said before,

              Could you add :

              qDebug() << m_Port->readall(); just inside your readData() Function
              

              Like that:

              void Work::readData()
              {
              qDebug() << m_Port->readall();
              while...
              .
              .
              .
              }
              

              And return us the result?

              I think that your data is coming in this way ,for example

              first packet "RT0100"
              second packet "003054CR"

              third packet "LF"

              i think that you should use a buffer

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

              @mostefa

              Your are right, data coming in 8 bytes at a time

              "@00RD000"
              "00010002"
              "00030004"
              ...
              ...
              "56CR"

              May I know what do you meant by Buffer?

              like this ?

                      QByteArray readData = m_Port->readAll();
                      while (m_Port->waitForReadyRead(500))
                              readData.append(m_Port->readAll());
              

              thks

              jsulmJ 1 Reply Last reply
              0
              • O Ongsk

                @mostefa

                Your are right, data coming in 8 bytes at a time

                "@00RD000"
                "00010002"
                "00030004"
                ...
                ...
                "56CR"

                May I know what do you meant by Buffer?

                like this ?

                        QByteArray readData = m_Port->readAll();
                        while (m_Port->waitForReadyRead(500))
                                readData.append(m_Port->readAll());
                

                thks

                jsulmJ Online
                jsulmJ Online
                jsulm
                Lifetime Qt Champion
                wrote on last edited by
                #8

                @Ongsk Not exactly like this. You should not have this while loop. If your readData slot is connected to readyRead signal it will be called each time new data arrives - no need for blocking polling with waitForReadyRead. Just put your buffer (QByteArray readData - bad name for a buffer) as member variable in your class.

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

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

                  Just use canReadLine(), it should work, as it just checks for the '\n' character:

                  bool QIODevice::canReadLine() const
                  {
                      Q_D(const QIODevice);
                      return d->buffer.indexOf('\n', d->buffer.size(),
                                               d->isSequential() ? d->transactionPos : Q_INT64_C(0)) >= 0;
                  }
                  

                  E.g. like:

                  void Foo::onReadyRead()
                  {
                      while (m_serial->canReadLine()) {
                          QByteArray line = m_serial->readLine();
                          ...
                      }
                  }
                  

                  as in your first post.

                  If this does not work, then, please send a bug-report to the Qt core part of I/O (to QIODevice), as it is issue not from QSerialPort, but from QIODevice.

                  As workaround you can use own buffer to parse on '\n' character:

                  void Foo::onReadyRead()
                  {
                      m_buffer += m_serial->readAll();
                      
                      if (m_buffer.indexOf('\n', ...) == -1)
                          return; // we still do not have an '\n'
                  
                     // do read line from m_buffer
                  }
                  
                  O 1 Reply Last reply
                  0
                  • jsulmJ jsulm

                    @Ongsk Not exactly like this. You should not have this while loop. If your readData slot is connected to readyRead signal it will be called each time new data arrives - no need for blocking polling with waitForReadyRead. Just put your buffer (QByteArray readData - bad name for a buffer) as member variable in your class.

                    O Offline
                    O Offline
                    Ongsk
                    wrote on last edited by
                    #10

                    @jsulm
                    You are right. I realized my mistake after pondering over the function. I had changed the code accordingly.

                    By the way, may i know what do you meant by QByteArray readData - bad name for a buffer? Just curious.

                    Thanks

                    jsulmJ 1 Reply Last reply
                    0
                    • K kuzulis

                      Just use canReadLine(), it should work, as it just checks for the '\n' character:

                      bool QIODevice::canReadLine() const
                      {
                          Q_D(const QIODevice);
                          return d->buffer.indexOf('\n', d->buffer.size(),
                                                   d->isSequential() ? d->transactionPos : Q_INT64_C(0)) >= 0;
                      }
                      

                      E.g. like:

                      void Foo::onReadyRead()
                      {
                          while (m_serial->canReadLine()) {
                              QByteArray line = m_serial->readLine();
                              ...
                          }
                      }
                      

                      as in your first post.

                      If this does not work, then, please send a bug-report to the Qt core part of I/O (to QIODevice), as it is issue not from QSerialPort, but from QIODevice.

                      As workaround you can use own buffer to parse on '\n' character:

                      void Foo::onReadyRead()
                      {
                          m_buffer += m_serial->readAll();
                          
                          if (m_buffer.indexOf('\n', ...) == -1)
                              return; // we still do not have an '\n'
                      
                         // do read line from m_buffer
                      }
                      
                      O Offline
                      O Offline
                      Ongsk
                      wrote on last edited by
                      #11

                      @kuzulis

                      I came across this before started to test my code.

                      by j.Hilk
                      Take a look at the docu here:

                      Note that unbuffered devices, which have no way of determining what can be read, always return false.

                      You have an unbuffered device conncted to your serial port.

                      I also came across your posts and comments about "canReadLine" ,
                      the return is always false. So what is unbuffered device?

                      Regards

                      1 Reply Last reply
                      0
                      • O Ongsk

                        @jsulm
                        You are right. I realized my mistake after pondering over the function. I had changed the code accordingly.

                        By the way, may i know what do you meant by QByteArray readData - bad name for a buffer? Just curious.

                        Thanks

                        jsulmJ Online
                        jsulmJ Online
                        jsulm
                        Lifetime Qt Champion
                        wrote on last edited by
                        #12

                        @Ongsk "readData" is a good name for a function/method, because it says that it is doing something "read data". But for a buffer I would not use such a name, as a buffer is passive - it does not do actively anything. "buffer" or "dataBuffer" for example would be better.

                        Unbuffered device is a device which does not have internal buffer - it just gives you what it currently have, it does not accumulate data in a buffer. To be able to detect a line (means: new line character) a device needs to accumulate data, as it is not guaranteed that data will come line by line. So the device accumulates the data in a buffer and looks for new-line in it.

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

                        O 1 Reply Last reply
                        0
                        • jsulmJ jsulm

                          @Ongsk "readData" is a good name for a function/method, because it says that it is doing something "read data". But for a buffer I would not use such a name, as a buffer is passive - it does not do actively anything. "buffer" or "dataBuffer" for example would be better.

                          Unbuffered device is a device which does not have internal buffer - it just gives you what it currently have, it does not accumulate data in a buffer. To be able to detect a line (means: new line character) a device needs to accumulate data, as it is not guaranteed that data will come line by line. So the device accumulates the data in a buffer and looks for new-line in it.

                          O Offline
                          O Offline
                          Ongsk
                          wrote on last edited by
                          #13

                          @jsulm
                          Just as I thought so on the naming. The device that I am using do have buffer , I had tested with C# using Readline method successfully. So I am curious why it don't work with QT. Anyway the best and safest bet are looping and accumulate sizable of data and process it.

                          Thanks and Cheers

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

                            So what is unbuffered device?

                            QSerialPort is always BUFFERED!

                            J.HilkJ 1 Reply Last reply
                            0
                            • K kuzulis

                              So what is unbuffered device?

                              QSerialPort is always BUFFERED!

                              J.HilkJ Online
                              J.HilkJ Online
                              J.Hilk
                              Moderators
                              wrote on last edited by
                              #15

                              @Ongsk
                              @kuzulis said in Qt SerialPort.canReadLine() ?:

                              QSerialPort is always BUFFERED!

                              QSerialPort sure has always a buffer, its initialized with it.

                              Underneath QSerialPort the communication between tio the (hardware)IODevice may or maynot support readline.

                              bool QIODevice::canReadLine() const
                              
                              Returns true if a complete line of data can be read from the device; otherwise returns false.
                              
                              Note that unbuffered devices, which have no way of determining what can be read, always return false.
                              

                              also

                              qint64 QIODevice::readLine(char *data, qint64 maxSize)
                              
                              This function reads a line of ASCII characters from the device, up to a maximum of maxSize - 1 bytes, stores the characters in data, and returns the number of bytes read. If a line could not be read but no error ocurred, this function returns 0. If an error occurs, this function returns the length of what could be read, or -1 if nothing was read.
                              

                              The docu is a bit missleading I think.
                              canReadLine returns false when no "\n"-new line character- was found in the buffer of the IODevice. This was Ongsk original question I believe.

                              So, the question is, if the device is read with readAll, are there any newline characters to be found and canReadLine is faulty, or are there none.


                              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
                              • K Offline
                                K Offline
                                kuzulis
                                Qt Champions 2020
                                wrote on last edited by
                                #16

                                For me all works: https://codereview.qt-project.org/#/c/185925/

                                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