Plotting of QProcess output taking about 5 minutes to plot single value.
Hello all ,
I am new to Qt , i am designing a system which will receive values from sensors and Plot in GUI. I have complete C code for serial port setting and data Processing . By using Q Process i am running this C program and Plotting the Processed values .
My GUI contain a text Edit for displaying Proceeded output readings and widget for plotting processed values with respect to time . Output values and Plot are as expected . Device sending with 4800 Baud rate and with odd parity , which is set in C program .But its taking more than 5 Minutes to read and plot one value and taking more than 30 minutes to read and plot about 6 values . why it taking this much time to read ?
My Code is attached ...
Code:
ui->setupUi(this);
QVector<double> data_x(101), data_y(101);
timer.start();
init_port();
init_line_plot();
x_position = 0;
}
graphwidget::~graphwidget()
{
delete ui;
}
void graphwidget::init_port()
{
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(receive()));
process->start("./test2");
process->waitForStarted();
qDebug()<<"process error code:" <<process->error();
}
void graphwidget::init_line_plot()
{
ui->customPlot->addGraph();
// ui->customPlot->setMinimumSize(500,500);
ui->customPlot->xAxis->setLabel("t");
ui->customPlot->yAxis->setLabel("V");
ui->customPlot->axisRect()->setAutoMargins(QCP::msNone);
ui->customPlot->axisRect()->setMargins(QMargins(0,0,0,0));
}
void graphwidget::receive()
{
// recieves data as ASCII string
int datalength = 1000;
char data [1000];
int bytesRead =process->readLine(data, datalength);
data[bytesRead]='\0';
ui
->textEdit
->append
(QString(data
));
out << data << endl;
addDataPoint(atof(data));
}
void graphwidget::addDataPoint(double datapoint)
{
if (x_position>60)data_x.pop_front();
double ms = timer.elapsed();
data_x.push_back((double)ms/1000);
x_position++;
if (x_position>60) data_y.pop_front();
data_y.push_back(datapoint);
ui->customPlot->graph(0)->setData(data_x,data_y);
ui->customPlot->xAxis->grid()->setSubGridVisible(false);
ui->customPlot->yAxis->grid()->setSubGridVisible(false);
ui->customPlot->xAxis->grid()->setVisible(false);
ui->customPlot->yAxis->grid()->setVisible(false);
ui
->customPlot
->graph
(0)->setPen
(QPen(QColor(0,
200,
0)));
ui->customPlot->setBackground(Qt::black);
ui->customPlot->graph(0)->rescaleAxes();
ui->customPlot->replot();
}
please suggest necessary changes ........
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
data_x and data_y in line 2 are local stack variables (I assume this is your class constructor) and have no relationship to the variables of the same name you use later.
In line 56, you increment x_position. I don't see anywhere where you reset its value, so once it reaches 60, it will continue to increase.
Otherwise, there doesn't appear to be anything in the code you have posted which would cause such delays. I would write a test program that strips out everything except the communication between your sensors and your monitoring program and see if that is where the trouble starts. No GUI, no writing to files, no plotting, just qDebug() statements to write what you receive to the console. And run it in the debugger, of course.
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
k. But i tested same qt program with simple C program . it will just print 1,2,3,4,5,4,3,2,1... and no serial port setting in C program , it worked fine and giving continues output without delay .
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
Quote:
Originally Posted by
suhairkp
k. But i tested same qt program with simple C program . it will just print 1,2,3,4,5,4,3,2,1... and no serial port setting in C program , it worked fine and giving continues output without delay .
So the problem is with the serial port. Why You don't use QSerialPort ?
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
Serial port is set in C program , so calling QProcess will set serial port . thats y not using Qserialport in Qt .Also , C program process the received signal from serial port and print output . this output is storing in byte array and using for plot .
I compiled C program from terminal and getting correct output in terminal . but Qt taking more time call QProcess and plot , don't getting idea where this delay occurring ...
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
I still think you need to break the problem down into the smallest piece possible, than add more features. I would start by writing a Qt program that simply starts the listener process, reads the output from your sensor and prints it using qDebug(). No printing it to a text edit, no logging to files, no plotting. At this point, you have no idea which step in this chain is going wrong, so eliminate everything except the first one: getting data successfully from the QProcess into your program. Once that seems to be working in the same way as your C program, then you know the communication works, so add the graphics and other features.
You might also try using QProcess:readAllStandardOutput() to get all of the available data at once instead of using readLine(). Use QByteArray::data() or QByteArray::constData() to get the NULL-terminated C string it contains. This way you do not have to worry about the buffer size or whether you have read it all.
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
k . sir. I am testing it without plot . in my above code , it displaying "process error code : 2 " in Application output area of Qt Creator , when output gui display open and saying " Qprocess : Destroyed while process is still running ". when i changed process->waitForStarted from process->waitForFinished , it show that "process error code : 5 "
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
Once again : why You use external program to read data from serial port ? Why You don't do it in Qt program ?
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
I have complete C code for processing different sensor value . there are 4 sensors and it takes about two years to complete this C code . this system working perfectly using frame buffer . Now i want to design GUI using Qt . If i am going to write complete code in Qt , sometime it will take more time . To reduce this time , i am using Q Process .
Added after 16 minutes:
I tested Code without plotting. Output of QProces is reading using QProcess:readAllStandardOutput() and qDebug() will print output .
Code:
ui->setupUi(this)
init_port();
}
graphwidget::~graphwidget()
{
delete ui;
}
void graphwidget::init_port()
{
connect(process, SIGNAL(readyReadStandardOutput()), this, SLOT(receive()));
process->start("./test2");
process->waitForReadyRead();
qDebug()<<"process error code:" <<process->error();
}
void graphwidget::receive()
{
QString data
= process
->readAllStandardoutput
();
qDebug << data ;
out << data << endl;
}
it also displaying "process error code : 2" and taking more time to print .After 4 minutes , it print about 50 values then stopped . I googled about process error code , didn't get any details about .
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
Just look in the Qt documentation: a value of 2 means The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again..
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
Is your C program writing its output to stdout or stderr and are you reading the correct channel? Look at QProcess:setProcessChannelMode and perhaps use QProcess::MergedChannels if you want both stdout and stderr to be merged, etc.
Since you are timing out waiting to read output from the C program, perhaps your C program is writing its output to stderr?
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
Quote:
Originally Posted by
Lesiok
Just look in the
Qt documentation: a value of 2 means
The last waitFor...() function timed out. The state of QProcess is unchanged, and you can try calling waitFor...() again..
is it is by adding waitFor...() many times?
Added after 5 minutes:
Quote:
Originally Posted by
jefftee
Is your C program writing its output to stdout or stderr and are you reading the correct channel? Look at
QProcess:setProcessChannelMode and perhaps use QProcess::MergedChannels if you want both stdout and stderr to be merged, etc.
Since you are timing out waiting to read output from the C program, perhaps your C program is writing its output to stderr?
i used printf to write output from Qprocess. so i used QProcess::readAllStandardoutput().
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
Quote:
Originally Posted by
suhairkp
i used printf to write output from Qprocess. so i used QProcess::readAllStandardoutput().
And do you have a newline at the end of your output and are you flushing stdout like so: fflush(stdout)?
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
s. each output values are in new line . but not flushing stdout.
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
Quote:
process->start("./test2");
So if you open a terminal window, cd to this directory, and execute "./test2", you see the expected output immediately in the terminal window? No delay at all?
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
s... getting currect output without delay in terminal , but QProcess taking more time to print out.
Re: Plotting of QProcess output taking about 5 minutes to plot single value.
I just noticed that the initial code you posted seems to omit the function definition that should preceed line 1. It would appear that this is your graphwidget constructor, which I presume is based on QObject and probably allocated on the stack in main.
In that same constructor, you are starting the timer and executing those init* methods, which then actually creates and starts your QProcess, all before you have started the message loop.
I would recommend that you take the processing logic out of the constructor and put into a separate init method, so that you execute the initialization *after* your graphwidget object is fully constructed and then you can being your processing.
For example, add a slot to graphwidget named init() or whatever you want to name it, then make the following changes to graphwidget (untested):
Code:
graphwidget
::graphwidget(QObject *parent
){
ui->setupUi(this);
x_position = 0;
QTimer::singleShot(0,
this,
SLOT(init
));
}
void graphwidget::init()
{
timer.start();
init_port();
init_line_plot();
}
This way, your graphwidget will be completely constructed and the singleshot timer will execute your init routine as soon as the event loop is started, etc. While I can't guarantee this is your problem, it's easy to try...