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.
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());
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With