QCustomPlot Огромное количество графиков данных

Я пытаюсь построить некоторые последовательные данные в моей программе Qt Gui, используя класс qcustomplot. У меня не было проблем, когда я пытался построить данные с низкой частотой дискретизации, например, 100 данных в секунду. График был действительно крутым и отображал данные плавно. Но при высокой частоте дискретизации, такой как 1000 данных в секунду, плоттер создает узкое место для функции последовательного чтения. Это замедляло время, как на расстоянии 4-5 секунд от устройства. Прямо говоря, плоттер не смог достичь скорости потока данных. Итак, есть ли какая-то общая проблема, о которой я не знаю, или какие-либо рекомендации?

Я думаю, что эти сценарные,

1 — разделить всю программу на 2 или 3 потока. Например, последовательная часть выполняется в одном потоке, а часть печати выполняется в другом потоке, а два потока связываются с QSemaphore.

2-кадр / с пользовательского сюжета ограничен. но должно быть решение, потому что NI LABVIEW отображает до 2 тыс. данных без каких-либо задержек

3 — для разработки нового виртуального последовательного устройства в протоколе USB. Теперь я использую ft232rl последовательный в USB конвертер.

4- изменить язык программирования. Какова ситуация и класс поддержки в C # или Java для построения графиков в реальном времени? (Я знаю, что это как ребенок говорит, но это повод, чтобы испытать на других языках)

Мое последовательное устройство отправляет функцию данных (это устройство для экспериментов, в котором нет серьезного кодирования), вкратце:

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 такова:

//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;
}

И заданная пользователем настройка сюжета:

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;
}

И последняя функция сюжета:

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;

}

0

Решение

Быстрый ответ:

Ты пытался:

ui->mainPlotter->replot(QCustomPlot::rpQueuedReplot);

в соответствии с документацией это может улучшить производительность при выполнении большого количества реплотов.

Более длинный ответ:

По твоему коду я чувствую, что ты пытаешься реплотировать так часто, как можешь, чтобы получить сюжет «в реальном времени». Но если вы работаете на ПК с настольной ОС, в реальном времени не бывает такого понятия.

То, о чем вы должны заботиться,

  • Убедитесь, что код для чтения / записи в последовательный порт не слишком задерживается. «Слишком много» следует интерпретировать относительно подключенного оборудования. Если это действительно критично ко времени (что, похоже, так и есть), вы должны оптимизировать свои функции чтения / записи и в конечном итоге поместить их в поток. Это может пойти до резервирования полного аппаратного ядра процессора для этого потока.
  • Убедитесь, что график графика обновляется достаточно быстро для человеческого глаза. Вам не нужно делать полную перерисовку каждый раз, когда вы получаете одну точку данных.

В вашем случае вы получаете 1000 данных / с, которые составляют 1 данные каждую мс. Это довольно быстро, потому что это за пределами разрешения по умолчанию таймера большинства настольных ОС. Это означает, что при вызове «serialReadData ()» у вас может быть больше одной точки данных, и вы можете оптимизировать ее, вызывая ее реже (например, вызывайте ее каждые 10 мс и каждый раз считывая 10 точек данных). Затем вы можете вызывать «replot ()» каждые 30 мс, что будет добавлять 30 новых точек данных каждый раз, пропускать около 29 вызовов replot () каждые 30 мс по сравнению с вашим кодом и давать вам ~ 30 к / с.


1 — разделить всю программу на 2 или 3 потока. Например, серийная часть
выполняется в одном потоке, а часть печати выполняется в другом потоке и двух
поток связывается с QSemaphore

Разделение графического интерфейса пользователя от последовательной части на 2 потока хорошо, потому что вы предотвратите узкое место в графическом интерфейсе, чтобы заблокировать последовательную связь. Также вы можете пропустить использование семафора и просто положиться на соединения Qt сигнал / слот (подключенные в режиме Qt :: QueuedConnection).

4- изменить язык программирования. Какова ситуация и класс
поддержка в C # или Java для построения графиков в реальном времени? (Я знаю, что это как ребенок
говорят, но это повод, чтобы испытать на других языках)

Изменение языка программирования, в лучшем случае, ничего не изменит или может ухудшить ваши характеристики, особенно если вы переходите на языки, которые не скомпилированы с собственными инструкциями ЦП.
Изменение библиотеки печати с другой стороны мог изменить выступления. Вы можете посмотреть на Qt Charts а также QWT. Я не знаю, как они сравниваются с QCustomPlot, хотя.

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]