简体   繁体   中英

Qt Serial Port communication

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM