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 and missing data
Qt 6.11 is out! See what's new in the release blog

QSerialPort and missing data

Scheduled Pinned Locked Moved General and Desktop
qserialport
4 Posts 2 Posters 4.3k 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.
  • C Offline
    C Offline
    codeaway
    wrote on last edited by
    #1

    Hi,

    I've been trying to read a serial port on Windows with QSerialPort within a QThread.
    In between, I do find some data which is missing when it is read with readAll() or read()

    The relevant code:

    void Worker::process()
    {
    QByteArray Data;
    QString DataStr;

    int Bytes, Timeout = 100;
    QSerialPort port;
    
    port.setPortName("COM13");
    
    qDebug() << "Thread Started";
    emit ready();
    
    while (!quit) {
    	if (!open) {
    		if (!port.open(QIODevice::ReadWrite)) {
    			qDebug() << "Open" << port.portName() << "failed";
    			return;
    		}
    		qDebug() << port.portName() << "Open";
    		port.setBaudRate(QSerialPort::Baud9600); 
    		port.setDataBits(QSerialPort::Data8);
    		port.setParity(QSerialPort::NoParity);
    		port.setStopBits(QSerialPort::OneStop);
    		port.setFlowControl(QSerialPort::NoFlowControl);
    		open = true;
    	}
    	if (port.waitForReadyRead(1)) {
    		Bytes = port.bytesAvailable();
    		Data = port.readAll();
    		DataStr.append(Data);
    		qDebug() << "Avail:" << Bytes
    			 << "Read:" << Data.count()
    			 << "Data:" << Data
    			 << "Str:" << DataStr;
    	}
    }
    if (port.isOpen()) {
    	port.close();
    	qDebug() << port.portName() << "Closed";
    }
    

    }

    What I do get from the qDebug() output is the following:
    Thread Started
    "COM13" Open
    Avail: 1 Read: 1 Data: "0" Str: "0"
    Avail: 1 Read: 1 Data: "9" Str: "09"
    Avail: 1 Read: 1 Data: "5" Str: "095"
    Avail: 1 Read: 1 Data: "\x00" Str: "095"
    Avail: 2 Read: 2 Data: ",\x00" Str: "095,"
    Avail: 1 Read: 1 Data: "0" Str: "095,0"
    Avail: 1 Read: 1 Data: "9" Str: "095,09"
    Avail: 1 Read: 1 Data: "4" Str: "095,094"
    Avail: 1 Read: 1 Data: "\x00" Str: "095,094"
    Avail: 2 Read: 2 Data: ",\x00" Str: "095,094,"
    Avail: 1 Read: 1 Data: "0" Str: "095,094,0"
    Avail: 1 Read: 1 Data: "9" Str: "095,094,09"
    Avail: 1 Read: 1 Data: "3" Str: "095,094,093"
    Avail: 1 Read: 1 Data: "\x00" Str: "095,094,093"
    Avail: 2 Read: 2 Data: ",\x00" Str: "095,094,093,"
    Avail: 1 Read: 1 Data: "0" Str: "095,094,093,0"
    Avail: 1 Read: 1 Data: "9" Str: "095,094,093,09"
    Avail: 1 Read: 1 Data: "4" Str: "095,094,093,094"
    Avail: 2 Read: 2 Data: "\x00," Str: "095,094,093,094"
    Avail: 1 Read: 1 Data: "\x00" Str: "095,094,093,094"
    Avail: 1 Read: 1 Data: "0" Str: "095,094,093,0940"
    Avail: 1 Read: 1 Data: "9" Str: "095,094,093,09409"
    Avail: 1 Read: 1 Data: "5" Str: "095,094,093,094095"
    Avail: 1 Read: 1 Data: "\x00" Str: "095,094,093,094095"
    Avail: 2 Read: 2 Data: ",\x00" Str: "095,094,093,094095,"
    Avail: 1 Read: 1 Data: "0" Str: "095,094,093,094095,0"
    Avail: 1 Read: 1 Data: "9" Str: "095,094,093,094095,09"
    Avail: 1 Read: 1 Data: "4" Str: "095,094,093,094095,094"
    Avail: 1 Read: 1 Data: "\x00" Str: "095,094,093,094095,094"
    Avail: 3 Read: 3 Data: ",\x00""0" Str: "095,094,093,094095,094,"
    Avail: 2 Read: 2 Data: "95" Str: "095,094,093,094095,094,95"
    Avail: 3 Read: 3 Data: "\x00,\x00" Str: "095,094,093,094095,094,95"
    Avail: 1 Read: 1 Data: "0" Str: "095,094,093,094095,094,950"

    As can be seen, in between the string is missing a "comma" delimiter between each value. At some point, it is not the delimiter, but it is a valid byte itself.

    To verify the same, I used Tera Term to see whether the incoming data is anyhow corrupted. But that seems highly unlikely, as I do see the correct string.

    094,095,094,095,094,095,094,095,094,095,094,095,094,095,094,095,094,095,094,095,094,095,094,095,

    Is it that I am doing something wrong ?
    Any idea, what's going wrong ?

    Can someone help, to fix the issue ?

    Thanks in advance.

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

      All the data is read by the serial port but it doesn't show up in your debug string. If you look closer your missing comma is read but dropped when added to the string.

      Your data format is NNN<null>,<null>NNN<null>,<null>NNN

      The <null> char (\x00) is commonly used as an end of string character. When you loose your comma in the debug it is from an input that is "\x00," so somewhere between what you read and what is displayed by your debug the string is being truncated at the <null> character.

      This is called 'chasing a wild goose'. There is no problem with QSerialPort.

      Maybe read one char at a time and discard the null characters or remove all the null characters immediately after reading the data while it is still a QByteArray.

      1 Reply Last reply
      0
      • C Offline
        C Offline
        codeaway
        wrote on last edited by
        #3

        Thanks, for the quick reply and the suggestion. True that I did miss comparing the read values, but only the appended string in the commotion.

        That said, trying to read char by char from the port, I see that read() can be used, but then it has no way of checking whether the operation failed or not. Is there a better solution, other than read() ?

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

          There are a few options.

          char c;
          
          while(port.read(&c,1) > 0) // returns the number of char's read, -1 on error
          {
            if(c)
            {
              // 'c' does not contain null. do something with it
            }
          };
          

          or maybe something like this

          QByteArray data;
          
          data = port.readAll();
          
          // QByteArray & QByteArray::replace(char before, const QByteArray & after)
          data.replace(char(0x00),QByteArray()); 
          
          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