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 5.8.0 Serial Problems when reading and writing to a serial port connected to itself
QtWS25 Last Chance

QT 5.8.0 Serial Problems when reading and writing to a serial port connected to itself

Scheduled Pinned Locked Moved Solved General and Desktop
qt5.8.0serialconnectionwindows10python
10 Posts 3 Posters 8.0k 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.
  • P Offline
    P Offline
    pitr
    wrote on 22 Mar 2017, 17:22 last edited by
    #1

    Hello, I'm attempting to use QT to write a message to a serial port and read the message. I have a SBT-USC1M Usb to serial adapter, I've connected ports 2 and 3 such that sending information will just be read back in the same port.

    I have a QT application which already opens a serial port with user specified information via QT gui. This works on a real hardware and I don't have any problems with it from that perspective, however I'm only reading data there.

    I've added code after verifying that the port is open that looks like this with the marked output:

    	QString tstring = "AAAAAAA";
            tstring.append("\0");
            QByteArray ba = tstring.toLocal8Bit();
            m_serial->write(ba);
            
            if (m_serial->waitForBytesWritten(1000)) {
                qDebug() << m_serial->bytesAvailable();
                if (m_serial->waitForReadyRead(1000)) {
                    QByteArray arr = m_serial->read(1);
                    qDebug() << arr;
                    //error handling afterwards...
    		
            ---OUTPUT---
    		
    	0
    	""
    

    Device manager says my device has the following properties:

    BPS 9600,
    Databits 8,
    Parity none,
    stop bits 1,
    flow control None,
    port name COM4,

    Using the following code in Python pyserial,

    #!/usr/bin/
    
    import serial
    
    
    
    def main():
    	print('hello')
    	serialport = serial.Serial('COM4', 19200, timeout=1)
    	serialport.write(b'hello')
    	s = serialport.read(6)
    	print(s)
    	serialport.close()
    	pass
    
    
    if __name__ == "__main__":
    	main()			
    

    results in:

    hello
    b'hello'
    

    So clearly this is not a hardware problem, Additionally its not like the port isn't getting the data, when iviewing m_serial d_ptr in debugmode, the following is shown after the timeout fails for waitReadyForRead()

    >readChunkBuffer "AAAAAAA\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000"... (512)
    

    Am I missing something here? scouring google, SO, and even QT forums have not turned up relevant solutions, and turned up troubling information about QT's checkered past with regression bugs being introduced that stop this sort of thing from happening.

    1 Reply Last reply
    0
    • P Offline
      P Offline
      pitr
      wrote on 22 Mar 2017, 20:02 last edited by pitr
      #2

      This problem does not appear to exist when the code provided exists as its own context not inside a thread. There must be a setting done to the port that makes it so it can't read properly, this lead me to look through the original source and find out if the normal read call for other functionality not even present was still being called on a hunch. It turns out that by adding a callback to readyRead() for the serial port, It would only call this other callback function, and reset the "readyRead()" flag even if nothing happened to read.

      I'm marking this as solved now, to reiterate, because I attached the callback for readyRead() to another function, any other serialized functionality outside of readyRead() could no longer function as if the serial port was ready to be read from because the flag for readyRead() event inside the QSerialPort object is automatically set to false.

      I'm not sure QT should be doing 'magic' things like that with out the users explicit invocation of such actions, reeks of bad code smell.

      1 Reply Last reply
      0
      • S Offline
        S Offline
        SGaist
        Lifetime Qt Champion
        wrote on 22 Mar 2017, 22:12 last edited by
        #3

        Hi and welcome to devnet,

        Technically you main function has several flows. You don't create a QApplication or QCoreApplication for that matter thus the Qt internals are not setup like they should.

        Then you don't use waitForReadyRead which is the way to do things if you have to wait for a while.

        Just calling read(6) like that doesn't guarantee that you get 6 bytes.

        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
        • P Offline
          P Offline
          pitr
          wrote on 23 Mar 2017, 14:31 last edited by
          #4

          what I posted was not full compilable code, merely a small piece that is called inside a much larger program, as such it does not have the issues you mentioned, a QAapplication is created in a main source file, where this isn't located (its inside the logic for a custom QT thread).

          Also I do use waitForReadyRead? (or at least I did) or did you mean to not use it?

          Just calling read(6) like that doesn't guarantee that you get 6 bytes.

          that was not the issue, the issue was what I explained above, nothing was being read despite the readbuffer containing all the data I sent (hence why I put that in the original post) and this was because the flag in order to start a read was being overwritten after readyRead() was called. At this point I'm even having issues with that, I can now read it, but it seems to miss bytes, under normal conditions QT works fine and reads serial normally with this configuration, but the code I'm working with isn't something I made.

          Is it normal practice to attach another function as a callback to readyRead() event?

          M 1 Reply Last reply 23 Mar 2017, 16:31
          0
          • P pitr
            23 Mar 2017, 14:31

            what I posted was not full compilable code, merely a small piece that is called inside a much larger program, as such it does not have the issues you mentioned, a QAapplication is created in a main source file, where this isn't located (its inside the logic for a custom QT thread).

            Also I do use waitForReadyRead? (or at least I did) or did you mean to not use it?

            Just calling read(6) like that doesn't guarantee that you get 6 bytes.

            that was not the issue, the issue was what I explained above, nothing was being read despite the readbuffer containing all the data I sent (hence why I put that in the original post) and this was because the flag in order to start a read was being overwritten after readyRead() was called. At this point I'm even having issues with that, I can now read it, but it seems to miss bytes, under normal conditions QT works fine and reads serial normally with this configuration, but the code I'm working with isn't something I made.

            Is it normal practice to attach another function as a callback to readyRead() event?

            M Offline
            M Offline
            mrjj
            Lifetime Qt Champion
            wrote on 23 Mar 2017, 16:31 last edited by
            #5

            @pitr said in QT 5.8.0 Serial Problems when reading and writing to a serial port connected to itself:

            Is it normal practice to attach another function as a callback to readyRead() event?

            Well its more normal to use a signal to say "DATA READY" for another thread to process the data.
            A plain call back would not work across threads in same elegant way but if you are only using it
            as a reset thing from same thread , it should be ok.

            Its funny/odd you have such issues in 5.8 as i actually tested Serial class in 5.6 using a bridged setup as u mentioned and i left to run on
            linux box for 3 weeks transferring a little above 1.2 TB over the class with no data loss. ( using checksums)

            I wondering how you do the bridged setup ? I was using a real wire to loop it.

            P 1 Reply Last reply 23 Mar 2017, 17:04
            0
            • M mrjj
              23 Mar 2017, 16:31

              @pitr said in QT 5.8.0 Serial Problems when reading and writing to a serial port connected to itself:

              Is it normal practice to attach another function as a callback to readyRead() event?

              Well its more normal to use a signal to say "DATA READY" for another thread to process the data.
              A plain call back would not work across threads in same elegant way but if you are only using it
              as a reset thing from same thread , it should be ok.

              Its funny/odd you have such issues in 5.8 as i actually tested Serial class in 5.6 using a bridged setup as u mentioned and i left to run on
              linux box for 3 weeks transferring a little above 1.2 TB over the class with no data loss. ( using checksums)

              I wondering how you do the bridged setup ? I was using a real wire to loop it.

              P Offline
              P Offline
              pitr
              wrote on 23 Mar 2017, 17:04 last edited by pitr
              #6

              @mrjj

              currently what is happening is that normal processing for data that would normally come from an external device (not the same port) is being handled in a single thread (but user defined) where the readyRead() event is linked to a callback function within the same thread within that thread. This callback appears to be causing data loss in software (since debugging, the python program, and normal usage of serial ports within QT itself does not actually show this issue).

              I've since 'fixed' this issue by calling waitForReadyRead() when the number of bytes available is less than expected. I believe the callback causes a loss of readyRead() events some how when trying to process directly with out waiting for all the data.

              Its funny/odd you have such issues in 5.8 as i actually tested Serial class in 5.6 using a bridged setup as u mentioned and i left to run on
              linux box for 3 weeks transferring a little above 1.2 TB over the class with no data loss. ( using checksums)

              You misunderstand me, there is absolutely no hardware problem, as I've demonstrated time and time again, there is absolutely no known problem with following QT examples on how to accomplish serial communication, or using pyserial, or when looking inside the buffers in debugmode, the problem only occurs when using the readyRead() attached to a callback. In this configuration the string (now changed)
              I am using a real wire to wire pins 2 and 3.

               "ABCDEFG"
              

              will come out as anything from:

              "ABCF"
              

              to

              "ABEG"
              

              and

              "ABCFG"
              

              the code now looks as follows:

              connect(m_serial, &QSerialPort::readyRead, this, &MyThread::readyReadCallback);
              ...
              void MyThread::somefunction(...){
              	...
              	m_serial->write("ABCDEFG");
              	...
              }
              
              void MyThread::readyReadCallback(){
                      if(m_serial->bytesAvailable() < num_bytes_needed){
              		m_serial->waitForReadyRead(10);
              	}
              	else{
              		... read the data
              	}
              }
              

              this consistently gets me the correct results, but is an awkward solution for an awkward design decision the original author made.

              1 Reply Last reply
              0
              • M Offline
                M Offline
                mrjj
                Lifetime Qt Champion
                wrote on 23 Mar 2017, 17:30 last edited by
                #7

                Ah I see. Most of the time I just call other function from
                readyRead slot so im not sure how that would be different from a callback, but I guess that
                whatever this callback made happen it must be related to using multiple threads.
                I cant however see why it should skip/miss some chars if the callback does as normally with buffer+=incoming until enough been read.

                1 Reply Last reply
                0
                • P Offline
                  P Offline
                  pitr
                  wrote on 23 Mar 2017, 17:53 last edited by
                  #8

                  @mrjj can you give a quick example of:

                  Most of the time I just call other function from
                  readyRead slot so im not sure how that would be different from a callback

                  this method?

                  M 1 Reply Last reply 23 Mar 2017, 17:54
                  0
                  • P pitr
                    23 Mar 2017, 17:53

                    @mrjj can you give a quick example of:

                    Most of the time I just call other function from
                    readyRead slot so im not sure how that would be different from a callback

                    this method?

                    M Offline
                    M Offline
                    mrjj
                    Lifetime Qt Champion
                    wrote on 23 Mar 2017, 17:54 last edited by
                    #9

                    @pitr
                    Yes I mean, since u name it a call back, does it differ in any way of just calling another member function?

                    1 Reply Last reply
                    0
                    • P Offline
                      P Offline
                      pitr
                      wrote on 23 Mar 2017, 19:38 last edited by
                      #10

                      @mrjj
                      no, a callback is just the nomenclature you use to describe functions passed as arguments to other functions to be invoked later.

                      1 Reply Last reply
                      0

                      3/10

                      22 Mar 2017, 22:12

                      topic:navigator.unread, 7
                      • Login

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