我正在尝试使用 qcustomplot 类在我的 Qt Gui 程序上绘制一些串行数据。当我尝试绘制 100 个数据/秒的低采样频率数据时,我没有遇到任何问题。该图非常酷,并且可以流畅地绘制数据。但是在 1000 数据/秒这样的高采样率下,绘图仪成为串行读取功能的瓶颈。它减慢了串行速度,距离设备有 4-5 秒的巨大延迟。直截了当,绘图仪无法达到数据流速度。那么,是否有任何我不知道的常见问题或任何建议?
我认为这些场景,
1-将整个程序分配给 2 或 3 个线程。例如,串行部分在一个线程中运行,绘图部分在另一个线程中运行,并且两个线程与 QSemaphore 通信
qcustom 绘图的 2-fps 是有限的。但应该有一个解决方案,因为 NI LABVIEW 可以毫无延迟地绘制多达 2k 的数据
3-在usb协议中设计一个新的虚拟串行设备。现在,我正在使用 ft232rl 串口转 USB 转换器。
4-更改编程语言。C# 或 java 中实时绘图的情况和类支持是什么?(我知道这就像一个孩子说的,但这是用其他语言体验的借口)
我的串口设备发送数据功能(它是用于实验的 foo 设备,没有严重的编码)简单地说:
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;
}
而 qcustom 绘图设置功能是:
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;
}