Qcustomplot converter data in "setData"
Hello everyone,
I made a program that collects data from an Arduino
in x,y format in a listwidget. These x, y values ??must then be sent to the Qcustomplot and that's where there is a problem.
There is a comma between x and y. They arrive like that from the Arduino to be used in the Excel graph.
My problem is when collecting the data in the ui->customplot->graph(0)->setData(x,y) function;
I can't convert the data from the "QString(data)" to convert them
Here is the blocking part: (after ui->listwidget..)
Code:
void NetworkPlot::readData()
{
qDebug() <<"Serialport works"; // it's ok (control port com)
auto data = arduino->readAll(); // it's ok
ui
->listWidget
->addItem
(QString(data
));
// it's ok
if (parts.size() == 2) {
qDebug() << parts.at(1).toDouble() << parts.at(2).toDouble();
mag.append(x) = parts.at(1).toDouble();
num.append(y) = parts.at(2).toDouble();
QVector<double> mag;
QVector<double> num;
ui->customplot->graph(0)->setData(x,y);
ui->customplot->replot();
ui->customplot->update();
}
My first test;
Code:
void NetworkPlot::readData()
{
qDebug() <<"Serialport works"; //ok
auto data = arduino->readAll(); //ok
ui
->listWidget
->addItem
(QString(data
));
//ok QVector<double> x,y;
ui->customplot->graph(0)->setData(x,y);
ui->customplot->replot();
ui->customplot->update();
}
There is a formatting that totally escapes me and I spent hours testing. This is my first application in C++ and I only have knowledge in basic and arduino but it is progressing.
I specify that I am French-speaking and I translate my request.
Thank you for your help
[IMG]https://i.postimg.cc/SKTDxbts/Application.jpg[/IMG]
Re: Qcustomplot converter data in "setData"
Your first code example shouldn't even compile. You are using your QVector variables mag and num before you have declared them. In your second example, your QVector variables x and y have no content.
Quote:
There is a comma between x and y. They arrive like that from the Arduino to be used in the Excel graph.
If that is the case, then why are you using QString ::split( " " )? This is telling QString to split the string on a blank space, not a comma.
First question: What is arduino->readAll() returning? One (x,y) point or multiple points? From your code, it looks like you are receiving only one (x,y) pair for each call to readAll(). In that case, calling setData() on the QCustomPlot will only plot a single point, not a line.
Your code should look something like this:
Code:
// NetworkPlot.h
{
Q_OBJECT
// ... Normal code
protected slots:
void onDataReady();
private:
QVector< double > xValues;
QVector< double > yValues;
};
// NetwokPlot.cpp
// This slot reads data from the arduino when the serial port emits the readyRead() signal
void NetworkPlot::onDataReady()
{
auto data
= QString( arduino
->readAll
() );
if ( !data.empty() )
{
if ( parts.size() == 2 )
{
x = parts[0].toDouble();
y = parts[1].toDouble();
xValues.push_back( x );
yValues.push_back( y );
ui->customplot->graph(0)->setData( xValues, yValues );
ui->customplot->replot();
ui->customplot->update();
}
}
}
// Call this method to start the data collection
void NetworkPlot::collectAndPlotData()
{
// Connect the Arduino's serial port signal to the data reader slot so data can be received
connect( arduino, &QIODevice::readyRead, this, &NetworkPlot::onDataReady() );
// Loop forever
while ( true )
{
// Wait 5 seconds for the arduino to respond with a readyRead() signal
if ( !arduino->waitForReadyRead( 5000 ) )
break; // An error occurred or the wait timed out
// Keep the UI "alive" by processing any events in the event queue
}
// Disconnect the Arduino's serial port signal from the data reader slot; no more data will be read
disconnect( arduino, &QIODevice::readyRead, this, &NetworkPlot::onDataReady() );
}
There are several important parts to this code:
1 - Reading data from a serial port is asynchronous. The port tells your program that data is available by sending a readyRead() signal.
2 - Your program must have code that receives the readyRead() signal. This is the onDataReady() slot.
3 - The data has to be stored outside of the read method. If you do not keep the data in member variables of your class, but use local variables instead, then every time the local variables go out of scope, the data disappears. That is why xValues and yValues are members of the NetworkPlot class.
4 - The loop in collectAndPlotData() will run forever, until an error occurs on the arduino or no data is received for 5 seconds. Since waitForReadyRead() will block the execution of the program until more data is ready, the ui will "freeze" if the loop is always waiting. To make sure this doesn't happen, the loop calls processEvents() so other parts of the ui can update themselves (like the plot).
I can't test this code so you will have to experiment to see if it works for you. I hope when you translate it into French it makes sense.