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. QSerialPort - opening port in non-blocking way causes readyRead not to be automatically emitted later on
Forum Updated to NodeBB v4.3 + New Features

QSerialPort - opening port in non-blocking way causes readyRead not to be automatically emitted later on

Scheduled Pinned Locked Moved Solved General and Desktop
8 Posts 4 Posters 738 Views 3 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.
  • M Offline
    M Offline
    michelson
    wrote on last edited by
    #1

    Hello,

    When QSerialPort::open is called program (GUI) freezes for a little bit (~3-5s) for the port to open. I wanted to avoid this small inconvinience by opeining it async way and reporting the result. However I found out that later on this causes QIODevice::readyRead signal not to be emitted.

        connect(m_port, &QSerialPort::readyRead, []() { qDebug() << "ready read!"; });
        connect(m_port, &QSerialPort::bytesWritten, [](int i) { qDebug() << "bytes written" << i; });
    
        //this makes readyRead work
        //m_port->open(QIODevice::ReadWrite); 
    
        // and this not
        using FW = QFutureWatcher<bool>;
        FW *w = new FW();
        connect(w, &FW::started, this, &RJ6::setBusy);
        connect(w, &FW::finished, w, &FW::deleteLater);
        connect(w, &FW::finished, this, &RJ6::onOpenFinished);
        connect(w, &FW::finished, this, &RJ6::setIdle);
        connect(w, &FW::canceled, this, &RJ6::close);
    
        QFuture<bool> f = QtConcurrent::run([=]() { return m_port->open(QIODevice::ReadWrite); });
    
        w->setFuture(f);
    

    setBusy, setIdle, onOpenFinished are just emitting signals, nothing else is going on there.

    This piece of code is triggered on write request

      qInfo() << QTime::currentTime().toString("hh:mm:ss.zzz") <<  "----- new write request - prev one should be already read-ready reported ----";
      qInfo() << "write" << data.toHex() << m_port->write(data);
      qInfo() << "flush" << m_port->flush();
      //qInfo() << "read all" << m_port->readAll().toHex();
    

    And now I noticed that when I write data to the port, I need to manually read it since QIODevice::readyRead is not emmited autmatically, seems like only after I try QSerialPort::readAll port "realizes" that there is data available for reading

    SerialWidget::onSendClicked "02"
    "16:38:46.209" ----- new write request - prev one should be already read-ready reported ----
    write "02" 1
    flush true
    read all ""
    bytes written 1
    SerialWidget::onSendClicked "02"
    "16:38:58.218" ----- new write request - prev one should be already read-ready reported ----
    write "02" 1
    flush true
    read all ""
    bytes written 1
       ready read! <-------- this is only showed when I uncomment readAll() call
    SerialWidget::onSendClicked "02"
    "16:39:15.771" ----- new write request - prev one should be already read-ready reported ----
    write "02" 1
    flush true
    read all "52454a3030364a4417"
    bytes written 1
       ready read! <-------- this is only showed when I uncomment readAll() call
    

    However when I just stick to the blocking way of simply calling m_port->open(QIODevice::ReadWrite) without any QFuture fanciness all works perfectly - readyRead is emitted correctly.

    Do you know what is wrong here?

    Environment: Qt\5.15.0\msvc2019_64 @ Win10

    1 Reply Last reply
    0
    • Kent-DorfmanK Offline
      Kent-DorfmanK Offline
      Kent-Dorfman
      wrote on last edited by
      #2

      so if there is a delay during open, why do the open() in the main thread? Why not offload it and check the status when the worker thread completes?

      M 1 Reply Last reply
      0
      • Kent-DorfmanK Kent-Dorfman

        so if there is a delay during open, why do the open() in the main thread? Why not offload it and check the status when the worker thread completes?

        M Offline
        M Offline
        michelson
        wrote on last edited by michelson
        #3

        @Kent-Dorfman
        That is basically what I did! I mean - I don't explicitly create another thread, I just run QSerialPort::open on, what I understood from the docs, one of the threads from the global pool (QThreadPool::globalInstance()). I don't understand why this has influence on QSerialPort::readyRead signal.

        1 Reply Last reply
        0
        • SGaistS Offline
          SGaistS Offline
          SGaist
          Lifetime Qt Champion
          wrote on last edited by
          #4

          Hi,

          You did just move the open call to another thread. What @Kent-Dorfman suggest is to implement a worker object to full manage your serial port in another thread.

          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
          • M Offline
            M Offline
            michelson
            wrote on last edited by
            #5

            Yes, I understand the idea. However I thought that this will be not necessary - I am using readyRead/bytesWritten to communicate with the device and it was working fine for me - no other thread was needed - until this open thing poped up.

            Alright, I assume either a little lag on open is acceptable or rewriting while thing to be handled in separate thread is necessary...

            1 Reply Last reply
            0
            • SGaistS Offline
              SGaistS Offline
              SGaist
              Lifetime Qt Champion
              wrote on last edited by
              #6

              The fact that your serial port opens slowly does not mean there's a bug in Qt. Did you check with another application whether it behaves the same ?

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

                @SGaist said in QSerialPort - opening port in non-blocking way causes readyRead not to be automatically emitted later on:

                The fact that your serial port opens slowly does not mean there's a bug in Qt.

                Is it related to this bug?

                Environment: Qt\5.15.0\msvc2019_64 @ Win10

                Ahh. no..

                Most likelly the problem is in your HW device or driver. Also you should not call the QSP methods from the different threads (as daid before).

                1 Reply Last reply
                1
                • M Offline
                  M Offline
                  michelson
                  wrote on last edited by
                  #8

                  @SGaist I did not say that there is a bug, to be honest I was quiet sure that it is me who is doing something wrong. And yes - I tried Bluetooth Serial Terminal (from Win10 store) and it also takes a few seconds to connect to device as well. I assume it might be the device (it is a custom thing I'd say) that lags on open.

                  Alright, at least I understand now that either I need to move all the stuff to some kind of worker handling QSP on separate thread or accept that there will be a lag on open.

                  Thanks, guys!

                  1 Reply Last reply
                  1

                  • Login

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