Read the data sent By Interface Electronics via PC serial Port
-
I have an Interface Electronics that is sending some data to the PC via the serial port, it has a Baud rate of 1MHz. I am working to Make a C++ GUI in Qt that reads this data and plot it, I succeeded in reading the data but when I start working on Processing it and Plot it, the code crashes due to the huge amount of data sent and it raises this error:
ASSERT failure in QList<T>::at: "index out of range", file C:/Qt/5.15.14/mingw81_64/include/QtCore/qlist.h, line 571
12:30:37: C:\Users\Hussein.Bassal\Documents\build-untitled-Desktop_Qt_5_15_14_MinGW_64_bit-Debug\debug\untitled.exe crashed. -
I have an Interface Electronics that is sending some data to the PC via the serial port, it has a Baud rate of 1MHz. I am working to Make a C++ GUI in Qt that reads this data and plot it, I succeeded in reading the data but when I start working on Processing it and Plot it, the code crashes due to the huge amount of data sent and it raises this error:
ASSERT failure in QList<T>::at: "index out of range", file C:/Qt/5.15.14/mingw81_64/include/QtCore/qlist.h, line 571
12:30:37: C:\Users\Hussein.Bassal\Documents\build-untitled-Desktop_Qt_5_15_14_MinGW_64_bit-Debug\debug\untitled.exe crashed.@hsnb
This indicates that you are trying to read a list element at an out of range index. Regardless of speed/quantity this should not happen, so look at your own code to see what you are doing where. Also if you run this under a debugger show the stack trace when the ASSERT is hit. -
@hsnb
This indicates that you are trying to read a list element at an out of range index. Regardless of speed/quantity this should not happen, so look at your own code to see what you are doing where. Also if you run this under a debugger show the stack trace when the ASSERT is hit.@JonB I am reading the data in a buffer then take it from it and process it, the idea is that I am receiving this error every run different from the other.
This is my code for the reading.QByteArray buffer; QStringList dataSegments; QStringList decimalData; while (serialPort.isOpen() && serialPort.isReadable()){ QByteArray header = "3c3e00"; if (serialPort.waitForReadyRead(1)) { // Wait for data to be available for reading buffer.append(serialPort.readAll()); dataSegments = extractDataSegments(buffer, header); decimalData = processData(dataSegments); qDebug() << "Recording data..."; for (int i=0; i < decimalData.size(); i++){ QString element = decimalData.at(i); QStringList list = element.split(" "); yData1.append(list.at(1).toDouble()); yData2.append(list.at(2).toDouble()); yData3.append(list.at(3).toDouble()); yData4.append(list.at(4).toDouble());
// // Record the current time in milliseconds
// qint64 currentTimeMillis = QDateTime::currentMSecsSinceEpoch();
// xData.append(currentTimeMillis);qDebug()<<"The size of data during this 1 sec: "<< "yData1 size: "<<yData1.size()<< " yData2 size: "<< yData2.size()<<" yData3 size: "<<yData3.size()<<" yData4 size: "<<yData4.size();//<< " the size of xData is: "<<xData.size(); } } }
-
@JonB I am reading the data in a buffer then take it from it and process it, the idea is that I am receiving this error every run different from the other.
This is my code for the reading.QByteArray buffer; QStringList dataSegments; QStringList decimalData; while (serialPort.isOpen() && serialPort.isReadable()){ QByteArray header = "3c3e00"; if (serialPort.waitForReadyRead(1)) { // Wait for data to be available for reading buffer.append(serialPort.readAll()); dataSegments = extractDataSegments(buffer, header); decimalData = processData(dataSegments); qDebug() << "Recording data..."; for (int i=0; i < decimalData.size(); i++){ QString element = decimalData.at(i); QStringList list = element.split(" "); yData1.append(list.at(1).toDouble()); yData2.append(list.at(2).toDouble()); yData3.append(list.at(3).toDouble()); yData4.append(list.at(4).toDouble());
// // Record the current time in milliseconds
// qint64 currentTimeMillis = QDateTime::currentMSecsSinceEpoch();
// xData.append(currentTimeMillis);qDebug()<<"The size of data during this 1 sec: "<< "yData1 size: "<<yData1.size()<< " yData2 size: "<< yData2.size()<<" yData3 size: "<<yData3.size()<<" yData4 size: "<<yData4.size();//<< " the size of xData is: "<<xData.size(); } } }
@hsnb
As I wrote, you should run under debugger, allow ASSERT, look at stack trace. Then you would know.I think we can guess that
QStringList list = element.split(" "); yData4.append(list.at(4).toDouble());
Since you do nothing to check bounds (please do so in your code, and certainly if you have an error), I think we can assume the list has less than 4 elements, causing
.at(4)
or earlier to be out of bounds.... -
@JonB I am reading the data in a buffer then take it from it and process it, the idea is that I am receiving this error every run different from the other.
This is my code for the reading.QByteArray buffer; QStringList dataSegments; QStringList decimalData; while (serialPort.isOpen() && serialPort.isReadable()){ QByteArray header = "3c3e00"; if (serialPort.waitForReadyRead(1)) { // Wait for data to be available for reading buffer.append(serialPort.readAll()); dataSegments = extractDataSegments(buffer, header); decimalData = processData(dataSegments); qDebug() << "Recording data..."; for (int i=0; i < decimalData.size(); i++){ QString element = decimalData.at(i); QStringList list = element.split(" "); yData1.append(list.at(1).toDouble()); yData2.append(list.at(2).toDouble()); yData3.append(list.at(3).toDouble()); yData4.append(list.at(4).toDouble());
// // Record the current time in milliseconds
// qint64 currentTimeMillis = QDateTime::currentMSecsSinceEpoch();
// xData.append(currentTimeMillis);qDebug()<<"The size of data during this 1 sec: "<< "yData1 size: "<<yData1.size()<< " yData2 size: "<< yData2.size()<<" yData3 size: "<<yData3.size()<<" yData4 size: "<<yData4.size();//<< " the size of xData is: "<<xData.size(); } } }
@hsnb also, you don't seem to realise that, even with a high baud rate, there is no guarantee that all data is available at the serialport-buffer, when the readyRead signal is emitted.
The only guarantee you have is that there is at least 1 byte of data in the buffer since the last time readyRead was emitted.
Now, you may think, that the readyRead signal does not concern you, since you're using waitForReadyRead, which you should not be using!!!!!
However you would be wrong. The waitForReadyRead() function still reacts to the signal internally. -
@hsnb also, you don't seem to realise that, even with a high baud rate, there is no guarantee that all data is available at the serialport-buffer, when the readyRead signal is emitted.
The only guarantee you have is that there is at least 1 byte of data in the buffer since the last time readyRead was emitted.
Now, you may think, that the readyRead signal does not concern you, since you're using waitForReadyRead, which you should not be using!!!!!
However you would be wrong. The waitForReadyRead() function still reacts to the signal internally. -
@J-Hilk but when I remove the waitForReadyRead I will not read data any more, and if I remove the while loop also I will stop being able to read the data. So what do you suggest me please
@hsnb
You should not have anywhile
loop. You should not have anywaitForReadyRead()
. You should not gobuffer.append(serialPort.readAll());
and then assume a complete "frame" has been received. You should append received data (from areadyRead()
slot) to a buffer. You then then check how bytes have been received. If & when that is a complete "frame", only then should youextractDataSegments()
and proceed to process it. If it is less then a complete "frame" you should do nothing; a futurereadyRead()
will get the rest and only then should you process it.That is how asynchronous input, like from serial port, is meant to be used from Qt.