Benjamin Maurer
Benjamin Maurer

Reputation: 3753

QtSerialPort: readAll doesn't yield all data and no new readyRead signal

I'm reading from a USB serial port, but sometimes I have the problem, that data gets "stuck". On received messages, I send new messages and wait again for the answer.

I'm using Qt 5.2.1 on Windows 7 with QtSerialPort in async mode. After a while, my program gets stuck, because I am waiting for an answer indefinitely. (It is kind of a transient bug, but it does happen if you wait long enough). With the debugger, I was able to see that I have only received the fragment of a message. On further investigation, I can see that QSerialPort has the whole message in its "readChunkBuffer".

This is my "readyRead" handler:

void ModuleCommunicator::onReadyRead()
{
if (port->bytesAvailable() > 0) {
    QString msg = QString(port->readAll());
    msgBuffer->append(msg);
    //qDebug() << "onReadyRead: msg: " << msg;

    if (msg.endsWith("\n")) {
        msg = msgBuffer->join("").trimmed();
        msgBuffer->clear();
        msgBuffer->append(msg.split("\r\n"));
    } else {
        return;
    }

    for (int i = 0; i < msgBuffer->size(); i++) {
        msg = msgBuffer->at(i);

        qDebug() << "MSG: " << msg << endl;

        if (isResponse(msg)) {
            handleMsg(msg);
        }
    }

    msgBuffer->clear();
}
}

I also tried "while(port->bytesAvailiable()". But I see only part of the message in msgBuffer, but the whole one in QSerialPorts buffer. Not sure when QSerialPort emits the signal and when it actually sees the whole message.

Maybe this is also some windows driver buffer issue? What puzzles me is that if I kill my application and fire up puTTY and send a newline, I get the rest of the message. Note that this is likely not an issue of my serial communication "partner", bc. it works via puTTY etc. and I can see the msg in "readChunkBuffer".

Upvotes: 1

Views: 3376

Answers (2)

Benjamin Maurer
Benjamin Maurer

Reputation: 3753

It turned out to be a bug in the software of the embedded device that the software communicates via serial port. :/

Upvotes: 0

Denis Shienkov
Denis Shienkov

Reputation: 527

The problem can be somewhere in your code. Because the readyRead() doesn't guarantee that you will receive the whole message at once; the message can come by parts on following readyRead() calls .

Also I am strained by:

QString msg = QString(port->readAll());
msgBuffer->append(msg);

why to transform from QByteArray to QString, and then QString to QByteArray twice?

May you provide an debug output from qDebug() for:

void ModuleCommunicator::onReadyRead()
{
    ...
    QByteArray ba = port.readAll();
    qDebug() << ba;
    ...
}

when you "stuck"?

Upvotes: 0

Related Questions