Qt SerialPort.canReadLine() ?
-
Hi:
I am having this issue which is giving me headache.void Work::readData() { while (m_Port->canReadLine()) { processLine(m_Port->readLine()); } }
I have a signal/slot that triggered the readdata()
connect(m_Port,SIGNAL(readyRead()),this,SLOT(readData()));
The canReadline is always false!
But If I do this
if (m_Port->isOpen() && m_Port->isWritable())
{// count+=1; QByteArray output; output = "@00RD0100003054*""\r\n"; m_Port->write(output); m_Port->flush(); m_Port->waitForBytesWritten(500); QByteArray readData = m_Port->readAll(); while (m_Port->waitForReadyRead(500)) readData.append(m_Port->readAll()); qDebug()<< readData;
I am able to read to newLine.
By the way, my serial operation is Write to Device and Wait for Device to response
and the response will always has a ChrLF.What am I doing wrong,
Thanks
-
Hi,
Take a look at the docu here:
Note that unbuffered devices, which have no way of determining what can be read, always return false.
You have an unbuffered device conncted to your serial port.
Seems obvious enough :)
-
Hi @Ongsk
Qt Serial port canReadLine() doc says:
http://doc.qt.io/qt-5/qiodevice.html#canReadLine
Returns true if a complete line of data can be read from the device; otherwise returns false.
Note that unbuffered devices, which have no way of determining what can be read, always return false.
This function is often called in conjunction with the readyRead() signal.
Could you add :
qDebug() << m_Port->readall(); just inside your readData() Function
Like that:
void Work::readData() { qDebug() << m_Port->readall(); while... . . . }
-
I am no quite sure what do you meant by unbuffered Device. The command that I sent example RT0100003054CRLF
meaning start Address 0100
number of word are 30
Checksum 54
So the Device will return header + 30 words + Checksum +CRLFWell May be I should test the device for
enum QIODevice::OpenModeFlag
flags QIODevice::OpenModethks
-
as i already said before,
Could you add :
qDebug() << m_Port->readall(); just inside your readData() Function
Like that:
void Work::readData() { qDebug() << m_Port->readall(); while... . . . }
And return us the result?
I think that your data is coming in this way ,for example
first packet "RT0100"
second packet "003054CR"third packet "LF"
i think that you should use a buffer
-
Your are right, data coming in 8 bytes at a time
"@00RD000"
"00010002"
"00030004"
...
...
"56CR"May I know what do you meant by Buffer?
like this ?
QByteArray readData = m_Port->readAll(); while (m_Port->waitForReadyRead(500)) readData.append(m_Port->readAll());
thks
-
@Ongsk Not exactly like this. You should not have this while loop. If your readData slot is connected to readyRead signal it will be called each time new data arrives - no need for blocking polling with waitForReadyRead. Just put your buffer (QByteArray readData - bad name for a buffer) as member variable in your class.
-
Just use canReadLine(), it should work, as it just checks for the '\n' character:
bool QIODevice::canReadLine() const { Q_D(const QIODevice); return d->buffer.indexOf('\n', d->buffer.size(), d->isSequential() ? d->transactionPos : Q_INT64_C(0)) >= 0; }
E.g. like:
void Foo::onReadyRead() { while (m_serial->canReadLine()) { QByteArray line = m_serial->readLine(); ... } }
as in your first post.
If this does not work, then, please send a bug-report to the Qt core part of I/O (to QIODevice), as it is issue not from QSerialPort, but from QIODevice.
As workaround you can use own buffer to parse on '\n' character:
void Foo::onReadyRead() { m_buffer += m_serial->readAll(); if (m_buffer.indexOf('\n', ...) == -1) return; // we still do not have an '\n' // do read line from m_buffer }
-
I came across this before started to test my code.
by j.Hilk
Take a look at the docu here:Note that unbuffered devices, which have no way of determining what can be read, always return false.
You have an unbuffered device conncted to your serial port.
I also came across your posts and comments about "canReadLine" ,
the return is always false. So what is unbuffered device?Regards
-
@Ongsk "readData" is a good name for a function/method, because it says that it is doing something "read data". But for a buffer I would not use such a name, as a buffer is passive - it does not do actively anything. "buffer" or "dataBuffer" for example would be better.
Unbuffered device is a device which does not have internal buffer - it just gives you what it currently have, it does not accumulate data in a buffer. To be able to detect a line (means: new line character) a device needs to accumulate data, as it is not guaranteed that data will come line by line. So the device accumulates the data in a buffer and looks for new-line in it.
-
@jsulm
Just as I thought so on the naming. The device that I am using do have buffer , I had tested with C# using Readline method successfully. So I am curious why it don't work with QT. Anyway the best and safest bet are looping and accumulate sizable of data and process it.Thanks and Cheers
-
So what is unbuffered device?
QSerialPort is always BUFFERED!
-
@Ongsk
@kuzulis said in Qt SerialPort.canReadLine() ?:QSerialPort is always BUFFERED!
QSerialPort sure has always a buffer, its initialized with it.
Underneath QSerialPort the communication between tio the (hardware)IODevice may or maynot support readline.
bool QIODevice::canReadLine() const Returns true if a complete line of data can be read from the device; otherwise returns false. Note that unbuffered devices, which have no way of determining what can be read, always return false.
also
qint64 QIODevice::readLine(char *data, qint64 maxSize) This function reads a line of ASCII characters from the device, up to a maximum of maxSize - 1 bytes, stores the characters in data, and returns the number of bytes read. If a line could not be read but no error ocurred, this function returns 0. If an error occurs, this function returns the length of what could be read, or -1 if nothing was read.
The docu is a bit missleading I think.
canReadLine
returns false when no "\n"-new line character- was found in the buffer of the IODevice. This was Ongsk original question I believe.So, the question is, if the device is read with
readAll
, are there any newline characters to be found andcanReadLine
is faulty, or are there none. -
For me all works: https://codereview.qt-project.org/#/c/185925/