【问题标题】:How do I collect real time data of an external serial device in Qt Creator?如何在 Qt Creator 中收集外部串行设备的实时数据?
【发布时间】:2014-06-18 22:17:54
【问题描述】:

我正在尝试从 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;
  }
}

任何有关如何实时获取数据和/或更好实施的帮助将不胜感激。谢谢:)

【问题讨论】:

    标签: c++ qt serial-port real-time qt-creator


    【解决方案1】:

    您可以将QSerialPortreadyRead 信号连接到插槽,以便在新数据到达时读取数据:

    connect(serial, SIGNAL(readyRead()), this, SLOT(readData()));
    

    readData 中,您可以调用readAll() 将所有可用数据读取到QByteArray 并将数组传递给另一个函数进行绘图:

    void MainWindow::readData()
    {
        QByteArray data = serial->readAll();
    
        plotMyData(data);
    }
    

    【讨论】:

      【解决方案2】:

      wrote a full demo application 显示如何从串口读取数据。

      • main.cpp 指定打开有效连接所需的设置,在本例中为 Arduino 设备;
      • serialportreader.h 实现了负责读取数据并将其打印到控制台的类。

      对于某些设备(如 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"));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2016-01-03
        • 1970-01-01
        • 2019-08-26
        • 1970-01-01
        • 2011-04-20
        • 1970-01-01
        • 2015-04-24
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多