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. How read correct data from QSerialPort

How read correct data from QSerialPort

Scheduled Pinned Locked Moved Unsolved General and Desktop
16 Posts 5 Posters 10.8k 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.
  • E Offline
    E Offline
    erytcg
    wrote on last edited by
    #1

    Hello I have problem with reading correct answer from serial port.
    I send command to device - XXX
    and device respond me number between 0 - 1023.
    I use this code but it's not good idea I think beacuse I always read 3 digit.

    serialPort->write("XXX\n");
    QByteArray data = serialPort->read(3);
    

    Answer:

    "320"
    "33"
    "1"
    ""
    "333"
    

    I want read only correct number, I use timer to send command

    jsulmJ 1 Reply Last reply
    0
    • mrdebugM Offline
      mrdebugM Offline
      mrdebug
      wrote on last edited by
      #2

      Please download, run and watch how this software is written to have an idea now how to use serial ports in Qt.

      https://www.linux-apps.com/p/1127795/

      Need programmers to hire?
      www.labcsp.com
      www.denisgottardello.it
      GMT+1
      Skype: mrdebug

      1 Reply Last reply
      0
      • JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by JonB
        #3

        QSerialPort::read(qint64 maxSize) only reads up to the number of bytes specified. You cannot assume it will return 3 bytes --- it could read between 1 and 3 bytes (I'm not sure about 0), depending on what is available.

        Read http://doc.qt.io/qt-5/qserialport.html#details carefully. You may need any combination of

        • for reading: repeated read()s, readAll(), waitForReadyRead(), bytesAvailable()
        • for writing: waitForBytesWritten(), flush()

        P.S.

        and device respond me number between 0 - 1023.
        I use this code but it's not good idea I think beacuse I always read 3 digit

        Values >= 1000 will not fit into 3 bytes!

        1 Reply Last reply
        2
        • E erytcg

          Hello I have problem with reading correct answer from serial port.
          I send command to device - XXX
          and device respond me number between 0 - 1023.
          I use this code but it's not good idea I think beacuse I always read 3 digit.

          serialPort->write("XXX\n");
          QByteArray data = serialPort->read(3);
          

          Answer:

          "320"
          "33"
          "1"
          ""
          "333"
          

          I want read only correct number, I use timer to send command

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

          @erytcg You should connect a slot to http://doc.qt.io/qt-5/qiodevice.html#readyRead signal of your serial port and read the data there using readAll(). Else it will not work. You can't just read at any random time.

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

          JonBJ 1 Reply Last reply
          2
          • jsulmJ jsulm

            @erytcg You should connect a slot to http://doc.qt.io/qt-5/qiodevice.html#readyRead signal of your serial port and read the data there using readAll(). Else it will not work. You can't just read at any random time.

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

            @jsulm said in How read correct data from QSerialPort:

            @erytcg You should connect a slot to http://doc.qt.io/qt-5/qiodevice.html#readyRead signal of your serial port and read the data there using readAll(). Else it will not work. You can't just read at any random time.

            Even then, just because readyRead signal is emitted it won't necessarily mean that > 1 byte is available to read, will it?

            jsulmJ 1 Reply Last reply
            0
            • JonBJ JonB

              @jsulm said in How read correct data from QSerialPort:

              @erytcg You should connect a slot to http://doc.qt.io/qt-5/qiodevice.html#readyRead signal of your serial port and read the data there using readAll(). Else it will not work. You can't just read at any random time.

              Even then, just because readyRead signal is emitted it won't necessarily mean that > 1 byte is available to read, will it?

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

              @JNBarchan No. That's why it is even more complex: one should read until everything was received and buffer the data.

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

              JonBJ 1 Reply Last reply
              0
              • jsulmJ jsulm

                @JNBarchan No. That's why it is even more complex: one should read until everything was received and buffer the data.

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

                @jsulm
                As @jsulm says, the usual technique here is: you write your own "wrapper" around the reads (e.g. in readyRead signal handler), in which you copy the bytes received into your own buffer. Then the caller reads out of that buffer, not direct from the port. You keep a note of how many bytes have been read into the buffer, and where the "read pointer" is currently which gets incremented as bytes are read. You could derive from QSerialPort to do this, or just write utility functions.

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

                  @JNBarchan said in How read correct data from QSerialPort:

                  n which you copy the bytes received into your own buffer.

                  It is unnecessary, as all data are cached in buffer inside of QSP. Just use peek() && bytesAvailable() && read() to parse a data.

                  JonBJ 1 Reply Last reply
                  0
                  • K kuzulis

                    @JNBarchan said in How read correct data from QSerialPort:

                    n which you copy the bytes received into your own buffer.

                    It is unnecessary, as all data are cached in buffer inside of QSP. Just use peek() && bytesAvailable() && read() to parse a data.

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

                    @kuzulis said in How read correct data from QSerialPort:

                    @JNBarchan said in How read correct data from QSerialPort:

                    n which you copy the bytes received into your own buffer.

                    It is unnecessary, as all data are cached in buffer inside of QSP. Just use peek() && bytesAvailable() && read() to parse a data.

                    That's not the point. The goal is to accumulate the input into your own buffer, so that you can control the reading of full data.

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

                      @JNBarchan said in How read correct data from QSerialPort:

                      That's not the point. The goal is to accumulate the input into your own buffer, so that you can control the reading of full data.

                      You do not need in a separate buffer for that purpose. The QSP's buffer already accumulates all data. Just read required portions of data from QSP.

                      JonBJ 1 Reply Last reply
                      0
                      • K kuzulis

                        @JNBarchan said in How read correct data from QSerialPort:

                        That's not the point. The goal is to accumulate the input into your own buffer, so that you can control the reading of full data.

                        You do not need in a separate buffer for that purpose. The QSP's buffer already accumulates all data. Just read required portions of data from QSP.

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

                        @kuzulis I do not agree with your approach.

                        It may work as the OP has phrased his question. However, consider the following protocol:

                        • Since he already does not know whether the device returns between 1 and 4 bytes for number 1 to 1024, he changes the protocol to put a \n terminator at the end of the response.
                        • So he does not know how many bytes received constitute a "complete" response.
                        • If bytesAvailable() returns 1, and read returns that byte, what does he do with that byte, given that he has to wait for more bytes before it's a number he can convert? he will end up having to buffer it. Which is why a buffered wrapper around the reads is the neatest solution.

                        BTW, this buffering is the same approach as used by all C runtimes for reading bytes from a FILE. It does not return the underlying OS read buffer. This makes, say, fscanf(fp, "%d") a lot easier to implement than if the underlying read buffer was returned without buffered wrapping...

                        K 1 Reply Last reply
                        0
                        • E Offline
                          E Offline
                          erytcg
                          wrote on last edited by
                          #12

                          Tomorrow I will check if my device is sending "\n" after answer. Now helped, setting timer interval for more than 0.

                          JonBJ 1 Reply Last reply
                          0
                          • mrdebugM Offline
                            mrdebugM Offline
                            mrdebug
                            wrote on last edited by
                            #13

                            Have you got a document with the device protocol?
                            Normally there is a start and stop byte, a crc byte ....

                            Need programmers to hire?
                            www.labcsp.com
                            www.denisgottardello.it
                            GMT+1
                            Skype: mrdebug

                            1 Reply Last reply
                            0
                            • E erytcg

                              Tomorrow I will check if my device is sending "\n" after answer. Now helped, setting timer interval for more than 0.

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

                              @erytcg You didn't tell us you were only using 0 in your timer delay! It may indeed work (better) if you put in a delay, though it's still "naughty" code! Don't forget to look at your protocol, because the way you have specified it the device won't be able to send back 3 bytes for a numbers 1000 to 1023, and for numbers < 100 it had better be padding with leading zeroes... !

                              1 Reply Last reply
                              0
                              • JonBJ JonB

                                @kuzulis I do not agree with your approach.

                                It may work as the OP has phrased his question. However, consider the following protocol:

                                • Since he already does not know whether the device returns between 1 and 4 bytes for number 1 to 1024, he changes the protocol to put a \n terminator at the end of the response.
                                • So he does not know how many bytes received constitute a "complete" response.
                                • If bytesAvailable() returns 1, and read returns that byte, what does he do with that byte, given that he has to wait for more bytes before it's a number he can convert? he will end up having to buffer it. Which is why a buffered wrapper around the reads is the neatest solution.

                                BTW, this buffering is the same approach as used by all C runtimes for reading bytes from a FILE. It does not return the underlying OS read buffer. This makes, say, fscanf(fp, "%d") a lot easier to implement than if the underlying read buffer was returned without buffered wrapping...

                                K Offline
                                K Offline
                                kuzulis
                                Qt Champions 2020
                                wrote on last edited by kuzulis
                                #15

                                @JNBarchan said in How read correct data from QSerialPort:

                                If bytesAvailable() returns 1, and read returns that byte

                                Why do you need to use read()? Use peek() to look to that byte. If that byte in not 'delimiter', then just drop this byte using read().

                                PS: Besides, if the user used correct '\n' delimiters, then I do not see any problems at all, just use canReadLine() && readLine().

                                PS2: I repeat again: QSP already is buffered! Do you understand it? You do not need in separate buffer in common case (but, you can write own code as you want, I'm don't care about).

                                JonBJ 1 Reply Last reply
                                1
                                • K kuzulis

                                  @JNBarchan said in How read correct data from QSerialPort:

                                  If bytesAvailable() returns 1, and read returns that byte

                                  Why do you need to use read()? Use peek() to look to that byte. If that byte in not 'delimiter', then just drop this byte using read().

                                  PS: Besides, if the user used correct '\n' delimiters, then I do not see any problems at all, just use canReadLine() && readLine().

                                  PS2: I repeat again: QSP already is buffered! Do you understand it? You do not need in separate buffer in common case (but, you can write own code as you want, I'm don't care about).

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

                                  @kuzulis

                                  Why do you need to use read()? Use peek() to look to that byte. If that byte in not 'delimiter', then just drop this byte using read().

                                  You can't "drop" it, it's the first digit of the response, you need to save it somewhere, in order to use it later to parse for the number. Where are you going to put the bytes received so that you can parse the string? That's what the buffer is for.

                                  PS2: I repeat again: QSP already is buffered! Do you understand it?

                                  Of course I understand that. My buffering suggestion is not to prevent loss of data, it's a means to easy parsing. I gave the example of C FILE which uses this technique even though the underlying OS read "is already buffered".

                                  You do not need in separate buffer in common case (but, you can write own code as you want, I'm don't care about).

                                  Shall we put this down to a difference of opinion/style then and leave it at that? If the OP wants to leave the bytes in the QSP buffer and write code which accumulates bytes directly from there to achieve the goal, that's up to him.

                                  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