QSerialPort readLine() extremely slow compared to readAll()

。_饼干妹妹 提交于 2019-11-27 02:52:55

问题


The data I'm reading from a serialport (in Qt, using QtSerialPort/QSerialPort) is separated by the newline '\n' and return '\r' characters, which is the way I intend to look at it for parsing. The line length may very, but it is very easy to extract the data from the format of each line.

//signal/slot connection on readyRead() is as follows:
connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));

where readData() is defined as:

void MainWindow::readData()
{
   //As mentioned below, which I will reiterate, I have already tried the addition of 
   // canReadLine():
   if (serial->canReadLine()){
     QByteArray data = serial->readLine();
     //QByteArray allData = serial->readAll();
     parseSerialBytes(data);
     //console->putData(data);
     //console->putData(alldata);
   }
}

However, the QIODevice::readLine() function is extremely slow, and clearly blocking data from being received at full frequency compared to QIODevice::readAll()

Can someone please explain how to properly use the readLine() function so I don't have to loop through readAll() into the QByteArray to parse each line? I used the "terminal" Qt Widgets example to create this asynchronous serialport read functionality.

Thanks in advance - this seems to be a common problem I have not yet seen answered here.


回答1:


This is a common error. The readData is called only once per a chunk of data, not necessarily once per line.

You need to keep reading lines as long as data is available. It is also a bad design to have serial line reading in a widget class. Move it to a separate object.

class Receiver : public QObject {
  Q_OBJECT
  QSerialPort m_port;
  QByteArray m_buffer;
  void processLine(const QByteArray & line) {
    ...
  }
  Q_SLOT void readData() {
    // IMPORTANT: That's a *while*, not an *if*!
    while (m_port.canReadLine()) processLine(m_port.readLine());
  }
public:
  Receiver(QObject * receiver = 0) : QObject(parent) {
    connect(&m_port, &QIODevice::readyRead, this, &Receiver::readData);
    ...
  }
}

Your error was to implement readData as shown below. Such code reads only one line no matter how many lines are available to be read. It'll appear "slow" since on each invocation there's more and more accumulated data that's left behind unread. Eventually it'll run out of heap.

void readData() {
  // WRONG!
  if (m_port.canReadLine()) processLine(m_port.readLine());
}


来源:https://stackoverflow.com/questions/24768916/qserialport-readline-extremely-slow-compared-to-readall

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!