QSerialPort and missing data



  • 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.



  • 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.



  • 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() ?



  • 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()); 
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.