I am writing a Qt application to communicate with another computer over a serial port. I have 2 real issues.

1. I can send and receive data fine, but sometimes the serial port "eats" part of my input. For example if I send:

cd /application/bin

sometimes (not always) it will only receive:

cd /applica

(Since it's a terminal it echoes the input back. Also my prompt tells me I'm clearly in the wrong spot.)

2. Also, sometimes the Qt slot which fires when there is data available doesn't fire even though I know that there's data I can receive. If I send another \r\n down the port the slot will fire. For example sometimes I'll ls something, and the command name will be read back from the port, but the contents of the folder sit there in limbo until I hit return again. Then I get the listing of the directory and two prompts.

Here's my code:

void Logic::onReadyRead(){        
        QByteArray incomingData;  
        incomingData = port->readAll();
        QString s(incomingData);
        emit dataAvailable(s);// this is a Qt slot if you don't know what it is.
        qDebug() << "in:"<< s.toLatin1();     
}

void Logic::writeToTerminal(QString string )
{
    string.append( "\r\n");
    port->write((char*)string.data(), string.length());
    if ( port->bytesToWrite() > 0){
        port->flush();
    }
    qDebug() << "out:" << string.toLatin1();
}
有帮助吗?

解决方案

I found the solution, and I suspect it was an encoding error, but I'm not sure. Instead of sending a QString down the serial port, sending a QByteArray fixed both problems. I changed the writeToTerminal() method:

void Logic::writeToTerminal(QString string )
{
    string.append( "\r");
    QByteArray ba = string.toAscii();
    port->write(ba);
}

其他提示

From this forum, it appears that sometimes not all the data gets sent, and whatever does gets sent has a '\0' appended to it. So if

cd /applica'\0' got sent, then the port->readAll() would stop there, because it thinks it has read everything.

One suggested answer on that forum was to read line by line, which your code almost does. So I think in your case, you can change your code to:

void Logic::onReadyRead(){        
    QByteArray incomingData;  
    if(port->canReadLine()) {
      incomingData = port->readLine();
      QString s(incomingData);
      emit dataAvailable(s);// this is a Qt slot if you don't know what it is.
      qDebug() << "in:"<< s.toLatin1();
    }     
}

void Logic::writeToTerminal(QString string )
{
    string.append( "\r\n");
    port->write((char*)string.data(), string.length());
    if ( port->bytesToWrite() > 0){
        port->flush();
    }
    qDebug() << "out:" << string.toLatin1();
}
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top