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. Use QIODevice Asynchronous Interface with Synchronous API

Use QIODevice Asynchronous Interface with Synchronous API

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 5 Posters 1.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.
  • P Offline
    P Offline
    Patrick Wright
    wrote on last edited by
    #1

    Hello,

    I am communicating with a device in Qt using a QIODevice (specifically a QSerialPort). Normally it is easy to use the asynchronous signals/slots mechanism of QIODevice to process replies from the device and perform actions. However, the particular device I am controlling has an API which is not suited to asynchronous communication (I have no way to determine which replies correspond to which command other than the order they occur in). That being said, I need to send a command to the device then wait for a reply to that immediate command before processing more commands.

    I can think of two was to go about doing this in Qt. The first method is to have a sendCommand() slot in my object which queues the command in an outgoing queue. A timer (or some other mechanism) then pulls these commands one at a time from the queue, sends the command to the device, then puts the command into an incoming queue. I then use the readyRead() signal from the QIODevice to get responses from the device. I associate a given response to a given command by the order in which it is received and the next command in the incoming queue. I will assume that the response corresponds to the next item in the queue. This method seems a little bad because I have no real way of determining timeout from a particular command or other error conditions.

    My second idea is to create a new thread which then uses the synchonous (waitForReadyRead) API of the QIODevice to communicate. I would have a sendCommand() slot and commandResponse() signal (that also sends back a pointer or some method to identify the originally send command). The sendCommand() method would add commands to a queue which would then be processed in a loop by the thread. The thread would read the command from the queue, send the data to the QIODevice, block until a reply is receive, process the reply, then emit a signal. I am not entirely sure how to create a thread with the ability to use signals and slots however.

    What I would like to know is if there is one method that would be better and if there is a better method I have not considered.

    Thanks!

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

      Hi,

      Do you really need a queue of command ? How often are you going to send them ?

      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
        Patrick Wright
        wrote on last edited by
        #3

        I will probably only send commands every few hundred milliseconds at most. However, the device sometimes can take up to a few seconds to respond to certain commands which means I need some was to buffer commands sent to the device within my program.

        aha_1980A 1 Reply Last reply
        0
        • P Patrick Wright

          I will probably only send commands every few hundred milliseconds at most. However, the device sometimes can take up to a few seconds to respond to certain commands which means I need some was to buffer commands sent to the device within my program.

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

          hi @Patrick-Wright,

          hand-shake based communication can perfectly be do asynchronous. you just need a send buffer (a QQueue, e.g.) once you got an answer, you parse it and send the next command from the queue. a QTimer restarts the communication when an answer does not come in (completely).

          I've programmed different apps that way, both ASCII or binary protocols. You can use the same approach for sockets, too.

          Regards

          Qt has to stay free or it will die.

          1 Reply Last reply
          2
          • P Offline
            P Offline
            Patrick Wright
            wrote on last edited by
            #5

            Ok. Would a good method in Qt be to do the following.

            1. I add a command to the send queue using a slot
            2. If there is only one item in the queue, I send this command to the device
            3. When the readyRead() slot is called by the QIODevice, I attempt to parse the command from the device
            4. Once a command is successfully received, I emit a signal and pull the next command from the queue

            The only problem I can see is how to correlate different replies to different commands. For example, my device has a series of GET commands which all return data with exactly the same format (only the values differ) so I have no way of knowing which type of GET reply it is. I need to somehow have a good method of keeping track of which signal to emit when I process the command based upon which command was just sent.

            jsulmJ 1 Reply Last reply
            0
            • P Patrick Wright

              Ok. Would a good method in Qt be to do the following.

              1. I add a command to the send queue using a slot
              2. If there is only one item in the queue, I send this command to the device
              3. When the readyRead() slot is called by the QIODevice, I attempt to parse the command from the device
              4. Once a command is successfully received, I emit a signal and pull the next command from the queue

              The only problem I can see is how to correlate different replies to different commands. For example, my device has a series of GET commands which all return data with exactly the same format (only the values differ) so I have no way of knowing which type of GET reply it is. I need to somehow have a good method of keeping track of which signal to emit when I process the command based upon which command was just sent.

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

              @Patrick-Wright said in Use QIODevice Asynchronous Interface with Synchronous API:

              how to correlate different replies to different commands

              If you only send one command and wait until you get the reply before sending next command then you always know to which command the current reply belongs. Or are you going to send several commands at the same time?

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

              P 1 Reply Last reply
              3
              • jsulmJ jsulm

                @Patrick-Wright said in Use QIODevice Asynchronous Interface with Synchronous API:

                how to correlate different replies to different commands

                If you only send one command and wait until you get the reply before sending next command then you always know to which command the current reply belongs. Or are you going to send several commands at the same time?

                P Offline
                P Offline
                Patrick Wright
                wrote on last edited by
                #7

                @jsulm
                Yes, you are correct that I would only send a single command thus I would know which one I am receiving a reply for. I suppose I am just confused as to the exact/proper way to go about this in the signals/slots world where my reply comes in a different function. Perhaps I send the command, place it into some sort of buffer, then when the reply slot is called, I look into that buffer to see what command caused the reply and act accordingly. I could also use a QTimer to implement some sort of timeout which discards the command buffer and emits an error/timeout signal.

                J.HilkJ 1 Reply Last reply
                0
                • P Patrick Wright

                  @jsulm
                  Yes, you are correct that I would only send a single command thus I would know which one I am receiving a reply for. I suppose I am just confused as to the exact/proper way to go about this in the signals/slots world where my reply comes in a different function. Perhaps I send the command, place it into some sort of buffer, then when the reply slot is called, I look into that buffer to see what command caused the reply and act accordingly. I could also use a QTimer to implement some sort of timeout which discards the command buffer and emits an error/timeout signal.

                  J.HilkJ Offline
                  J.HilkJ Offline
                  J.Hilk
                  Moderators
                  wrote on last edited by
                  #8

                  @Patrick-Wright
                  Qt has the container class of QQueue for situations just as yours ;-)


                  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
                  1

                  • Login

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