c++qtserial-portqtserialport

QSerialPort::readLine doesn't work as expected on MS Windows


I'm trying to connect a micro-controller with my desktop PC via USB-serial cable. The OS of my desktop PC is Windows 8.1, and USB-serial cable is TTL-232R-3V3. (FTDI) (Qt version: 5.2.0 beta1, QtCreator Version: 3.0, Compiler: MSVC2012)

Now I'm trying read/write loop-back tests, and that's why RX/TX pin of USB-serial cable are connected with each other.

Here is my code.

#include <QtCore/QCoreApplication>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QtCore/QDebug>

#define PORT_NAME "COM3"
#define BAUDRATE 19600
#define TIMEOUT_MS 1000

QT_USE_NAMESPACE
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QSerialPort pSerial(PORT_NAME);
    const char strMsg[] = "#1:Send data line \n #2:Send data line\n #3:Send data line end\n";
    char strBuf[256];
    qint64 nByte;


    if(pSerial.open(QIODevice::ReadWrite)){
        pSerial.setBaudRate(BAUDRATE);
        qDebug() << "OPEN PASS";

        pSerial.write(strMsg);
        pSerial.flush();
        if(pSerial.waitForBytesWritten(TIMEOUT_MS)){
            qDebug() << "WRITE PASS";
        }


        pSerial.waitForReadyRead(TIMEOUT_MS);
        while(true){
            if( pSerial.canReadLine()){
                qDebug() << "CAN READ LINE";
                nByte = pSerial.readLine(strBuf,sizeof(strBuf));
                qDebug() << "Length: " << nByte;
                qDebug() << "Read data: " << strBuf;

            }
        }
        pSerial.close();
    } else {
        qDebug() << "OPEN FAIL\n";
    }
    return a.exec();
}

When the program starts to run, the result is different than I expected. Only first line of sent data can be received. So, "Read data: #1 Send data line" is printed on console. But the rest of sent data will never be received. Does anyone know why?

Any help would be appreciated. Thanks in advance.

EDIT: I revised my code according to Papp's comment.Then it works as I expected. All sent message has been received.

Does it mean I misunderstand the usage about readLine() or canReadLine()?

//        while(true){
//            if( pSerial.canReadLine()){
//                qDebug() << "CAN READ LINE";
//                nByte = pSerial.readLine(strBuf,sizeof(strBuf));
//                qDebug() << "Length: " << nByte;
//                qDebug() << "Read data: " << strBuf;
//            }
//        }

        pSerial.waitForReadyRead(TIMEOUT_MS);
        QByteArray readData = pSerial.readAll();
        while (pSerial.waitForReadyRead(TIMEOUT_MS)) {
            readData.append(pSerial.readAll());
        }
        qDebug() << "Read data: " << readData;

EDIT 2nd time : Following code also works for me.

while(true){
    if( pSerial.waitForReadyRead(TIMEOUT_MS) && pSerial.canReadLine()){ // I revised this line
        qDebug() << "CAN READ LINE";
        nByte = pSerial.readLine(strBuf,sizeof(strBuf));
        qDebug() << "Length: " << nByte;
        qDebug() << "Read data: " << strBuf;
        qDebug() << "Error Message: " << pSerial.errorString();

    }
}

Solution

  • That is because you need to read in a loop like this:

    QByteArray readData = serialPort.readAll();
    while (serialPort.waitForReadyRead(5000))
        readData.append(serialPort.readAll());
    

    Please see the creadersync example for the details what I added to 5.2. You can also check the creaderasync example for non-blocking operation.

    To be fair, we have not tested readLine that much, but it works for me on Unix, so does it on Windows for someone else.