Serial port data loss
-
Hi.
I have a problem with serial port which is not working well for keeping track of huge amounts of incoming data.
As you can see from below code, when 7 bytes of data is received, data is started to processing. But this function (process_data) is slow compared to incoming data. And when data rates go up to 10kbytes or over, some data is get lost.
Lets say, MCU is sending "0-1-2-3-4-5-6". Then after a 2-3 seconds, it becomes "3-4-5-6-0-1-2". And after some time, it becomes "4-5-6-0-1-2-3".
Why is that? And how to solve this problem?
By the way, I`m using ft232 usb converter with 1M baud rates but this has nothing to do with the problem because i have tested it other usb devices and softwares. The problem seems to me is it is because of while loop inside serialreceived slot.QByteArray serialdata; serialreceived(){ serial->blockSignals(true); if(serial->bytesAvailable()<7){ serial->blockSignals(false); return; } serialdata.append(serial->readAll()); while(serialdata.count()>6){ serialdata.append(serial->readAll()); process_data(); serialdata.remove(0,7); } ui->widget->replot(QCustomPlot::rpQueued); serial->blockSignals(false); }
-
Hi @donquixote, welcome to the forums
serial->blockSignals(true);
What do you expect from this? Blocking signals may of course lead to loss of data.
serialdata.append(serial->readAll());
At this point you have read everything from the serial buffer. Blocking your event queue by staying in this function will forbid further receiving.
while(serialdata.count()>6){
serialdata.append(serial->readAll());How should that work? you have already read all data. you should leave the slot and continue after the next readyRead() signal.
Regards
-
Hi @aha_1980 . Thank you.
serial->blockSignals(true);
What do you expect from this? Blocking signals may of course lead to loss of data.
I used it because i thought maybe the problem is that new incoming data is interrupting the function before the previous one has not finished yet. The problem was still in there before that.
serialdata.append(serial->readAll());
At this point you have read everything from the serial buffer. Blocking your event queue by staying in this function will forbid further receiving.
Isn't it just blocking signals? I mean, Qt'll still continue to buffer incoming data at its serial buffer but it will not process the serialreceived slot.
To make it clear, my idea is:- wait for new data
- enter serialreceived slot
- read all available data
- process data and block serial signals at the time
- QT'll continue to buffer data at the time
- after that, read new received bytes from buffer and process them.
while(serialdata.count()>6){
serialdata.append(serial->readAll());How should that work? you have already read all data. you should leave the slot and continue after the next readyRead() signal.
Regards
OK, got your idea. That should be the problem since i don't wait for readyread signal in the loop, right?
Best.
-
@donquixote said in Serial port data loss:
I used it because i thought maybe the problem is that new incoming data is interrupting the function before the previous one has not finished yet. The problem was still in there before that.
Slots are not interrupted. They are called one by one from the event loop in the background. Think of your slots are like a subroutine that is called from main if there is work to do.
process data and block serial signals at the time
QT'll continue to buffer data at the timeAnd I guess that will not work out. Even if it works on one platform, it may fail on another one.
OK, got your idea. That should be the problem since i don't wait for readyread signal in the loop, right?
Yeah, but don't wait for readyRead, leave the slot and give Qt the possibility to process the data. It will call your slot again once new data is ready.
Regards