我正在尝试从arduino(使用Qt类QSerialPort)收集实时数据并将其实时绘制到图形(使用QCustomPlot类)。我是使用串行设备的新手,因此我不确定在QSerialPort类中使用哪个函数来收集数据。以下是我目前设置序列的代码:
QSerialPort serial;
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
serial.setPortName("com4");
serial.setBaudRate(QSerialPort::Baud9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);
serial.open(QIODevice::ReadWrite);
setupRealtimeDataDemo(ui->customPlot);
}
...这是我的实时老虎机数据代码......
void MainWindow::realtimeDataSlot()
{
// calculate two new data points:
#if QT_VERSION < QT_VERSION_CHECK(4, 7, 0)
double key = 0;
#else
double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;
#endif
static double lastPointKey = 0;
if (key-lastPointKey > 0.01) // at most add point every 10 ms
{
double value0 = qSin(key); //sin(key*1.6+cos(key*1.7)*2)*10 + sin(key*1.2+0.56)*20 + 26;
double value1 = qCos(key); //sin(key*1.3+cos(key*1.2)*1.2)*7 + sin(key*0.9+0.26)*24 + 26;
// add data to lines:
ui->customPlot->graph(0)->addData(key, value0);
ui->customPlot->graph(1)->addData(key, value1);
// set data of dots:
ui->customPlot->graph(2)->clearData();
ui->customPlot->graph(2)->addData(key, value0);
ui->customPlot->graph(3)->clearData();
ui->customPlot->graph(3)->addData(key, value1);
// remove data of lines that's outside visible range:
ui->customPlot->graph(0)->removeDataBefore(key-8);
ui->customPlot->graph(1)->removeDataBefore(key-8);
// rescale value (vertical) axis to fit the current data:
ui->customPlot->graph(0)->rescaleValueAxis();
ui->customPlot->graph(1)->rescaleValueAxis(true);
lastPointKey = key;
}
// make key axis range scroll with the data (at a constant range size of 8):
ui->customPlot->xAxis->setRange(key+0.25, 8, Qt::AlignRight);
ui->customPlot->replot();
// calculate frames per second:
static double lastFpsKey;
static int frameCount;
++frameCount;
if (key-lastFpsKey > 2) // average fps over 2 seconds
{
ui->statusBar->showMessage(
QString("%1 FPS, Total Data points: %2")
.arg(frameCount/(key-lastFpsKey), 0, 'f', 0)
.arg(ui->customPlot->graph(0)->data()->count()+ui->customPlot->graph(1)->data()->count())
, 0);
lastFpsKey = key;
frameCount = 0;
}
}
有关如何实时获取数据和/或更好实施的任何帮助将不胜感激。谢谢:))
答案 0 :(得分:0)
您可以将readyRead
的{{1}}信号连接到一个插槽,以便在新数据到达时读取数据:
QSerialPort
在connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
中,您可以调用readData
将所有可用数据读取到readAll()
并将数组传递给另一个函数进行绘图:
QByteArray
答案 1 :(得分:0)
我wrote a full demo application显示如何从序列中读取数据。
对于某些设备(例如Arduino),在open()
成功后调用setDataTerminalReady(true);
是必要的。因此,对于那些遇到Terminal Example问题的人,请记住将void MainWindow::openSerialPort()
破解为:
void MainWindow::openSerialPort()
{
SettingsDialog::Settings p = settings->settings();
serial->setPortName(p.name);
serial->setBaudRate(p.baudRate);
serial->setDataBits(p.dataBits);
serial->setParity(p.parity);
serial->setStopBits(p.stopBits);
serial->setFlowControl(p.flowControl);
if (serial->open(QIODevice::ReadWrite)) {
console->setEnabled(true);
console->setLocalEchoEnabled(p.localEchoEnabled);
ui->actionConnect->setEnabled(false);
ui->actionDisconnect->setEnabled(true);
ui->actionConfigure->setEnabled(false);
ui->statusBar->showMessage(tr("Connected to %1 : %2, %3, %4, %5, %6")
.arg(p.name).arg(p.stringBaudRate).arg(p.stringDataBits)
.arg(p.stringParity).arg(p.stringStopBits).arg(p.stringFlowControl));
// HACK
serial->setDataTerminalReady(true);
} else {
QMessageBox::critical(this, tr("Error"), serial->errorString());
ui->statusBar->showMessage(tr("Open error"));
}
}