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 emitting of readyRead()

QSerialPort emitting of readyRead()

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

    Hey guys,

    I am currently working with a device that is controlled via a serial Port. I am using Qt for GUI purposes and want to use it for the serial Port functions as well. Point is I got trouble noticing when data is being resceived by the computer.

    I got something like the following. Where serialPort is a QSerialPort and member of ComPortControl
    @
    ComPortControl::ComPortControl(){
    //some blabla
    connect(&serialPort, SIGNAL(readyRead()), this, SLOT(someReadFunction()));
    }

    ComPortControl::someReadFunction(){
    QByteArray arrivedMsg = serialPort.readAll();

     //fancy stuff I do with the message
    

    }
    @

    This does not work as intended. The readyRead() signal is emitted only after a certain amount of data has been resceived at the Serial Port. I have pretty short individual messages and must request data multiple times until the signal is emitted. At this point I get all the data from all the requests at the same time.

    Is there a way, to tell the Port to emit the signal as soon as there is something in the read buffer. Preferably without polling.

    1 Reply Last reply
    0
    • R Offline
      R Offline
      Rondog
      wrote on last edited by
      #2

      I had some issues with this as well.

      In my case I ended up not depending on this signal. I check a modified 'bytesAvailable()' function periodically in a separate thread (polling, not what you wanted). The waitForReadyRead(1) was necessary to have it 'update' itself or whatever.

      @
      d_serial_device->waitForReadyRead(1);
      return d_serial_device->bytesAvailable();
      @

      It is possible that calling waitForReadyRead(1) might also do the trick without having to poll but you would have to call this regularly.

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

        bq. The readyRead() signal is emitted only after a certain amount of data has been resceived at the Serial Port.

        This is the OS && the driver && the port speed dependent thing.

        bq. Is there a way, to tell the Port to emit the signal as soon as there is something in the read buffer.

        Currently it is so works. The readyRead() emits when at least one byte were received. But in practice about 5-10 bytes during this time manage to come (I mean a time until the system Rx event was triggered up to data will be read into internal buffer of class). Therefore in each of readyRead() about 5-10 bytes are available to reading. This behavior is a driver && OS && speed specific (as I wrote above).

        bq. The waitForReadyRead(1) was necessary to have it ‘update’ itself or whatever.

        The waitForReadyRead() just "override" the Qt event loop. Internally - it is works similar with Qt event loop, but, maybe a little quicker than Qt event-loop. But in this case, maybe too you will receive about 5-10 bytes after every waitForReadyRead() call (need to check it).

        bq. I have pretty short individual messages and must request data multiple times until the signal is emitted.

        In common case this is impossible to implement as you want (if I understand correctly). In case your short messages follow one after another with small delay, then the serial port will interpret it as continuous data stream; in case your messages has a long delay, then, maybe, in each readyRead() will be located a whole message.

        But there is a small trick: to reconfigure serial port on the blocking reception of data with a desired timeout, using QSerialPort::handle() method. In this case you can specify desired count of bytes (or timeout) to receive.

        For this purpose you should to use:

        • on Windows, try to reconfigure the

        COMMTIMEOUTS structure: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363190(v=vs.85).aspx
        using SetCommTimeouts function: https://msdn.microsoft.com/en-us/library/windows/desktop/aa363437(v=vs.85).aspx

        • on Linux/Mac/BSD and other, try to reconfigure the termios structure
          using VMIN/VTIME fields.

        maybe this will helps for you, but in this case you should to move whole of QSerialPort instance into separate thread, since now the I/O will be blocking and can freeze Qt event-loop.

        1 Reply Last reply
        1
        • P Offline
          P Offline
          prashant.qt.developer
          wrote on last edited by
          #4

          You don't require to increase the emission frequency of readyRead() signal, I believe.

          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