c++qtserial-portqtserialport

QtSerialPort: duplicate reads on Windows 7


My application is communicating with an embedded system via serial port (usb serial).

I'm developing with Qt 4.8 and QtSerialPort from gitorious (https://qt.gitorious.org/qt/qtserialport/) and I'm also testing in a VM with Windows 7 and Qt 5.2.1

It works fine under Linux, but I get double, triple quadruple reads of the same message. I can verify that these messages are only sent once, communicating via puTTY.

So the question is, is it an issue with QtSerialPort, the VM (although it works with putty?), the serial driver... etc.

Is this a known issue? (I couldn't find anything, though) Any ideas how to get to the bottom of this?

this is how I read:

EDIT: moar code:

ModuleCommunicator::ModuleCommunicator(const QString &device, SBStateModel &state_model)
: upstate(UpdateDone), model(state_model)
{
port = new QSerialPort(device);

if (!port->open(QIODevice::ReadWrite /*| QIODevice::Truncate*/)) {
    qDebug() << "Failed to open - Portname: " << port->portName() << endl;
    qDebug() << "Error: " << port->errorString() << endl;

    return;
}

port->setBaudRate(QSerialPort::Baud115200, QSerialPort::AllDirections);
port->setParity(QSerialPort::NoParity);
port->setStopBits(QSerialPort::OneStop);
port->setDataBits(QSerialPort::Data8);
port->setFlowControl(QSerialPort::NoFlowControl);

msgBuffer = new QStringList();

log_init = false;

connect(port, SIGNAL(readyRead()), this, SLOT(onReadyRead()));
connect(port, SIGNAL(error(QSerialPort::SerialPortError)), this, SLOT(onError(QSerialPort::SerialPortError)));
connect(port, SIGNAL(aboutToClose()), this, SLOT(devClosing()));

/* Timer for log level */
conTimer = new QTimer(this);
connect(conTimer, SIGNAL(timeout()), this, SLOT(timerFired()));
}

ModuleCommunicator::~ModuleCommunicator()
{
  if (port->isOpen())
      port->close();
  delete msgBuffer;
  delete port;
}

...
void ModuleCommunicator::onReadyRead()
{
if (port->bytesAvailable()) {
    QString msg = QString(port->readAll());
    msgBuffer->append(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();
}
}

EDIT: Interesting. Uncommenting a "flush()" makes things work. With the flush I see multiplied messages. But on the receiving end? Is it possible, that messages are SENT multiple times because of "flush()"?

void ModuleCommunicator::handleMsg(const QString &msg)
{
// Parse msg
QSharedPointer<USBResponse> resp = QSharedPointer<USBResponse>(parse_message(msg));

if (!resp->is_valid()) {
    // LOG
    return; // Invalid response
}

// omitted 

/* Find completion handler for response
  Match to first command in Queue with same command & address,
  or same command and wildcard adress */
// Omitted

// Sending next msg in queue if there is one
if (!sendQueue.isEmpty()) {
    QueuedCommand qc = sendQueue.takeFirst();
    QString nxtcmd = qc.cmdstr;
    completionHandlerQueue.append(qc.ch);
    qDebug() << "handleMsg: Sending next msg: " << qc.cmdstr;
    if (port->write(nxtcmd.toLatin1()) == -1) {
        qDebug() << "handleMsg: write failed!";
    }
    // !!! Removing the following line makes things work?!
    port->flush();
}

return;

}


Solution

  • The issues was caused by calling the "flush" method. Removing flush calls after writing to the serial port fixes the problem.

    It seems like there are known issues with the "flush" method (although a hint in the documentation would be nice, until it is fixed). Here is the bug report I found:

    https://bugreports.qt-project.org/browse/QTBUG-36726

    Quote:

    Yes, a flush() method has bugs yet. Please do not use a flush().