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. Analog QSerialPort::waitForReadyRead()

Analog QSerialPort::waitForReadyRead()

Scheduled Pinned Locked Moved Unsolved General and Desktop
7 Posts 4 Posters 2.5k 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.
  • M Offline
    M Offline
    maratk1n
    wrote on last edited by maratk1n
    #1

    I need to make a request and get a response from the card through the port. I do not want to wait forever for an answer, so I need to control the timeout. For this, the method QSerialPort::waitForReadyRead() is ideal, but on the Windows platform it has problems. Are there any analogues or alternative solutions? Tried using a timer, but the port was silent.

    QByteArray ComPort::requestResponse(const QByteArray &data)
    {
        mutex->lock();
        qDebug() << "-------------------------";
        if(!serial->isOpen())
            open();
        int attempts = 1;
        QElapsedTimer waitTimer;
        readBuf.clear();
        while (attempts <= 3) {
            if (serial->isWritable())
            {
                serial->write(data);
                waitTimer.restart();
                while (waitTimer.elapsed() < 333){
                    ms_delay(5);
                    readBuf += serial->readAll();
                    if (readBuf.size() == 4){
                        close();
                        mutex->unlock();
                        return readBuf;
                    }
                }
                readBuf.clear();
                qDebug() << "Timeout...";
                close();
                open();
                attempts++;
            }
            else
            {
                qDebug() << "Port is not written";
                close();
                mutex->unlock();
                return 0;
            }
     
        }
        close();
        mutex->unlock();
        return 0;
    }
    
    aha_1980A 1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      Are you sure the port is opening properly ?

      What if you use Qt's asynchronous capabilities for the communication ?

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      M 1 Reply Last reply
      1
      • M maratk1n

        I need to make a request and get a response from the card through the port. I do not want to wait forever for an answer, so I need to control the timeout. For this, the method QSerialPort::waitForReadyRead() is ideal, but on the Windows platform it has problems. Are there any analogues or alternative solutions? Tried using a timer, but the port was silent.

        QByteArray ComPort::requestResponse(const QByteArray &data)
        {
            mutex->lock();
            qDebug() << "-------------------------";
            if(!serial->isOpen())
                open();
            int attempts = 1;
            QElapsedTimer waitTimer;
            readBuf.clear();
            while (attempts <= 3) {
                if (serial->isWritable())
                {
                    serial->write(data);
                    waitTimer.restart();
                    while (waitTimer.elapsed() < 333){
                        ms_delay(5);
                        readBuf += serial->readAll();
                        if (readBuf.size() == 4){
                            close();
                            mutex->unlock();
                            return readBuf;
                        }
                    }
                    readBuf.clear();
                    qDebug() << "Timeout...";
                    close();
                    open();
                    attempts++;
                }
                else
                {
                    qDebug() << "Port is not written";
                    close();
                    mutex->unlock();
                    return 0;
                }
         
            }
            close();
            mutex->unlock();
            return 0;
        }
        
        aha_1980A Offline
        aha_1980A Offline
        aha_1980
        Lifetime Qt Champion
        wrote on last edited by
        #3

        Hi @maratk1n,

        the waitForReady... functions are thought for usage in threads and will not work outside a thread.

        As @SGaist already said, have you thought of the readyRead signal? the timeout could be handled by a QTimer.

        Qt has to stay free or it will die.

        M 1 Reply Last reply
        1
        • SGaistS SGaist

          Hi,

          Are you sure the port is opening properly ?

          What if you use Qt's asynchronous capabilities for the communication ?

          M Offline
          M Offline
          maratk1n
          wrote on last edited by
          #4

          @SGaist
          I think that it is correctly opened, because if I change

          while (waitTimer.elapsed() < 333){
          //reading
          }
          

          for it,

          while (serial->waitForReadyRead(300)) {    //(wait 300ms). Here, randomly breaks down
          //reading
          }
          

          everything works correctly.
          The asynchronous method is not suitable for two reasons:

          1. I have to receive a response to a specific request, so I need to work synchronously
          2. I must be sure that the board has responded and only then proceed to the next actions
          jsulmJ 1 Reply Last reply
          0
          • aha_1980A aha_1980

            Hi @maratk1n,

            the waitForReady... functions are thought for usage in threads and will not work outside a thread.

            As @SGaist already said, have you thought of the readyRead signal? the timeout could be handled by a QTimer.

            M Offline
            M Offline
            maratk1n
            wrote on last edited by maratk1n
            #5

            @aha_1980
            In these examples (Blocking Master Example, Blocking Slave Example), the method works in other threads (maybe I did not understand the remark).
            In short, it should work like this

            device1.requestResponse(requestPackage)
            //do action 1
            device2.requestResponse(requestPackage)
            //do action 2
            

            Permission to proceed to the following actions only when the board has responded to my request. At the same time, if there is a timeout, I need to resend the request, because maybe the board did not receive a request and wait for a reply is useless

            aha_1980A 1 Reply Last reply
            0
            • M maratk1n

              @SGaist
              I think that it is correctly opened, because if I change

              while (waitTimer.elapsed() < 333){
              //reading
              }
              

              for it,

              while (serial->waitForReadyRead(300)) {    //(wait 300ms). Here, randomly breaks down
              //reading
              }
              

              everything works correctly.
              The asynchronous method is not suitable for two reasons:

              1. I have to receive a response to a specific request, so I need to work synchronously
              2. I must be sure that the board has responded and only then proceed to the next actions
              jsulmJ Offline
              jsulmJ Offline
              jsulm
              Lifetime Qt Champion
              wrote on last edited by
              #6

              @maratk1n said in Analog QSerialPort::waitForReadyRead():

              I have to receive a response to a specific request, so I need to work synchronously
              I must be sure that the board has responded and only then proceed to the next actions

              I don't see why it would not work with asynchronous approach. You send a request and then "wait" until readyRead signal is fired. If you get this signal then you know that the board has responded and it should be the response for the request you sent before.
              If you really want to use blocking calls (waitFor...) then you should move that part to a thread to not to block your main thread.

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

              1 Reply Last reply
              2
              • M maratk1n

                @aha_1980
                In these examples (Blocking Master Example, Blocking Slave Example), the method works in other threads (maybe I did not understand the remark).
                In short, it should work like this

                device1.requestResponse(requestPackage)
                //do action 1
                device2.requestResponse(requestPackage)
                //do action 2
                

                Permission to proceed to the following actions only when the board has responded to my request. At the same time, if there is a timeout, I need to resend the request, because maybe the board did not receive a request and wait for a reply is useless

                aha_1980A Offline
                aha_1980A Offline
                aha_1980
                Lifetime Qt Champion
                wrote on last edited by
                #7

                Hi @maratk1n,

                And you should really think if you need to keep a mutex for 300 milliseconds. That effectively makes multithreading impossible.

                But back to your topic: Is your code running in a thread? If the answer is no, then I repeat: it will not work, because with your ms_delay and waitForReadyRead you're blocking Qt's event loop.

                I have written a lot of programs working with QtSerialPort on Windows, and never had problems, neither with non-blocking nor with blocking code. You just have to take care how you use it.

                Qt has to stay free or it will die.

                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