首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >QCustomPlot海量数据绘图

QCustomPlot海量数据绘图
EN

Stack Overflow用户
提问于 2017-03-11 23:45:23
回答 1查看 2.6K关注 0票数 2

我正试图用qcustomplot类在我的Qt程序上绘制一些串行数据。当我试图绘制100个数据/秒这样的低采样频率数据时,我没有遇到任何麻烦。这张图真的很酷,而且绘制的数据很流畅。但在1000次/秒的高采样率下,绘图仪成为串行读取功能的瓶颈。它慢下来连续,有一个巨大的延迟,就像4-5秒,远离设备。直接说,绘图仪无法达到数据流的速度。那么,有什么共同的问题,我不知道或任何建议?

我以为这些人,

1-将整个程序划分为2或3线程。例如,串行部件在一个线程中运行,绘图部分在另一个线程中运行,两个线程与QSemaphore通信。

Q定制情节的2 fps是有限的。但是应该有一个解决方案,因为NI LABVIEW毫不拖延地绘制了高达2k的数据。

3-在usb协议中设计一种新的虚拟串行设备。现在,我使用ft232rl串行到usb转换器。

4-改变编程语言。在C#或java中对实时绘图的情况和类支持如何?(我知道这就像一个孩子说的那样,但这是在其他语言中体验的一个前提)

我的串行设备发送数据功能(它是用于实验的foo设备,没有严格的编码)简单地说是:

代码语言:javascript
复制
void progTask()
{

DelayMsec(1); //my delay function, milisecond

//read value from adc13
Adc13Read(adcValue.ui32Part);

sendData[0] = (char)'a';
sendData[1] = (char)'k';
sendData[2] = adcValue.bytes[0];
sendData[3] = (adcValue.bytes[1] & 15);

Qt程序读取功能是:

代码语言:javascript
复制
//send test data
UARTSend(UART6_BASE,&sendData[0],4);
}

union{
unsigned char bytes[2];
unsigned int intPart;
unsigned char *ptr;
}serData;

void MedicalSoftware::serialReadData()
{

    if(serial->bytesAvailable()<4)
    {
     //if the frame size is less than 4 bytes return and 
     //wait to full serial receive buffer
     //note: serial->setReadBufferSize(4)!!!!
     return;
    }

QByteArray serialInData = serial->readAll();

//my algorithm
if(serialInData[0] == 'a' && serialInData[1] == 'k')
{
    serData.bytes[0] = serialInData[2];
    serData.bytes[1] = serialInData[3];

}else if(serialInData[2] == 'a' && serialInData[3] == 'k')
{
    serData.bytes[0] = serialInData[0];
    serData.bytes[1] = serialInData[1];
}
else if(serialInData[1] == 'a' && serialInData[2] == 'k')
{
    serial->read(1);
    return;
}else if(serialInData[0] == 'k' && serialInData[3] == 'a')
{
    serData.bytes[0] = serialInData[1];
    serData.bytes[1] = serialInData[2];

}

plotMainGraph(serData.intPart);

serData.intPart = 0;
}

定制化的绘图设置功能是:

代码语言:javascript
复制
void MedicalSoftware::setGraphsProperties()
{
//MAIN PLOTTER
ui->mainPlotter->addGraph();
ui->mainPlotter->xAxis->setRange(0,2000);
ui->mainPlotter->yAxis->setRange(-0.1,3.5);
ui->mainPlotter->xAxis->setLabel("Time(s)");
ui->mainPlotter->yAxis->setLabel("Magnitude(mV)");
QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime());
timeTicker->setTimeFormat("%h:%m:%s");
ui->mainPlotter->xAxis->setTicker(timeTicker);
ui->mainPlotter->axisRect()->setupFullAxesBox();

QPen pen;
pen.setColor(QColor("blue"));
ui->mainPlotter->graph(0)->setPen(pen);

dataTimer = new QTimer;
}

最后是地块函数:

代码语言:javascript
复制
void MedicalSoftware::plotMainGraph(const quint16 serData)
{
static QTime time(QTime::currentTime());
double key = time.elapsed()/1000.0;
static double lastPointKey = 0;
if(key-lastPointKey>0.005)
{

    double value0 = serData*(3.3/4096);
    ui->mainPlotter->graph(0)->addData(key,value0);
    lastPointKey = key;
}
ui->mainPlotter->xAxis->setRange(key+0.25, 2, Qt::AlignRight);
counter++;

        ui->mainPlotter->replot();
        counter = 0;

}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-03-12 08:53:42

快速回答:

你试过:

代码语言:javascript
复制
ui->mainPlotter->replot(QCustomPlot::rpQueuedReplot);

根据文档,它可以提高性能时,做很多重绘。

较长的答覆:

我对您的代码的感觉是,您正在尽可能频繁地重绘以获得一个“实时”的情节。但是,如果你是在一台带有桌面操作系统的个人电脑上,就没有实时的东西。

你应该关心的是:

  • 确保读取/写入串行端口的代码不会延迟太久。对于连接的硬件来说,“太多”是要解释的。如果它变得非常重要(这似乎是您的情况),您必须优化您的读/写函数,并最终将它们单独放在一个线程中。这甚至可以为这个线程保留一个完整的硬件CPU核心。
  • 确保图形图的刷新速度足够快,以满足人眼的需要。每次收到单个数据点时,都不需要执行完整的重新绘制。

在您的例子中,您接收到1000个数据/s,这使得每毫秒有一个数据。这是相当快的,因为这超出了大多数桌面操作系统的默认定时器分辨率。这意味着在调用"serialReadData()“时,可能有多个数据点,并且可以通过减少调用次数来优化数据点(例如,每10 10调用一次,每次读取10个数据点)。然后,您可以每30毫秒调用一次" replot()“,这将每次添加30个新的数据点,与代码相比,您可以跳过大约29次每30 29调用一次,并给出~30 you。

1-将整个程序划分为2或3线程。例如,串行部件在一个线程中运行,绘图部分在另一个线程中运行,两个线程与QSemaphore通信。

在两个线程中将GUI与串行部分分开是很好的,因为您将防止GUI中的瓶颈阻塞串行通信。此外,您可以跳过使用信号量,只需依赖Qt信号/时隙连接(在Qt::QueuedConnection模式中连接)。

4-改变编程语言。在C#或java中对实时绘图的情况和类支持如何?(我知道这就像一个孩子说的那样,但这是在其他语言中体验的一个前提)

在最好的情况下,更改编程语言不会改变任何事情,也不会损害您的性能,特别是当您使用未编译到本地CPU指令的语言时。另一方面,改变绘图库可以改变性能。你可以看看Qt图Qwt。不过,我不知道他们和QCustomPlot相比有什么不同。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42742033

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档