通过 QSerialPort 访问来自 Arduino 的串行数据时遇到问题

Posted

技术标签:

【中文标题】通过 QSerialPort 访问来自 Arduino 的串行数据时遇到问题【英文标题】:Having trouble with accessing serial data coming from an Arduino though QSerialPort 【发布时间】:2015-11-27 19:50:43 【问题描述】:

最近,我一直致力于通过串行连接(USB 电缆)将数据从 Arduino Micro 发送到我的计算机,我正在尝试使用 QSerialPort 访问它,以便我可以实时绘制数据图表。虽然大部分数据行是好的,但是当我使用 readLine() 或 readAll() 读取它们时,有些会被截断,导致数据丢失。这是一个问题,因为当我实时绘制两个变量时,它无法读取第二个变量,我的图表结果会受到影响。此外,丢失的数据会被添加到后面的数据行中,这会使一切变得更加混乱。需要说明的是,Arduino 发送数据正常,因为使用串行监视器显示所有数据行都是完整的。

这是从 Micro 读取数据并将其输出到文件的程序的主要部分(这也是获取数据错误,并且是一个更清晰的程序来发现错误的原因)。

#include "mainwindow.h"
#include <QApplication>
#include <QtCore/QCoreApplication>
#include <QtCore/QDebug>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QString>
#include <QMessageBox>
#include <QFile>

QT_USE_NAMESPACE

int main(int argc, char *argv[])

QApplication a(argc, argv);
QSerialPortInfo info("COM6");
    // Check info of the port
            qDebug() << "Name        : " << info.portName();
            qDebug() << "Manufacturer: " << info.manufacturer();
            qDebug() << "Busy: " << info.isBusy() << endl;

// Initialize Serial
QSerialPort serial;
serial.setPortName("COM6");
serial.open(QIODevice::ReadWrite);
serial.setBaudRate(QSerialPort::Baud9600);
serial.setDataBits(QSerialPort::Data8);
serial.setParity(QSerialPort::NoParity);
serial.setStopBits(QSerialPort::OneStop);
serial.setFlowControl(QSerialPort::NoFlowControl);

QFile file("C:\\Users\\Keenan\\Documents\\serialTest\\arduinoData.txt");//open file

if(!file.exists())
 
    qDebug()<<"File Doesn't Exist";
 
if (!file.open(QIODevice::WriteOnly|QIODevice::Text))
 
     QMessageBox::information(0, "error", file.errorString());
 ;

QTextStream stream(&file);


while (serial.isOpen())
 
  serial.waitForReadyRead(-1);
  QString data;
  data = serial.readAll();
  qDebug() << "Data has been found: " << data <<endl;
  stream << data << endl;
 

file.close();
qDebug() << "Done" << endl;
return a.exec();

这是每 2 秒发送一次的 Arduino 注释代码(我已将变量替换为常量值以使错误更清晰):

Serial.print("1");
Serial.print(",");
Serial.print("2");
Serial.print(",");
Serial.print("3");
Serial.print(",");
Serial.print("4");
Serial.print(",");
Serial.println("5");

当我运行程序时,这是我读入文本文件的内容:

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

1
,2,3,4,5

1
,2,3,4,5

1,
2,3,4,5

1,2,
3,4,5

1,2,3,
4,5

1,2,3,4
,5

1,2,3,4,5


1,2,3,4,5


1,2,3,4,5

1,2,3,4,5

1,2,3,4,5

如您所见,1,2,3,4,5 在结尾处搞砸了,但最终由于未知原因自行修复。 Arduino 的波特率为 9600,与我设置的相匹配。忽略这段代码的原始性,有谁知道它为什么会这样截断数据?几天来我一直在尝试不同的事情,我真的很想克服这个问题。提前致谢。

【问题讨论】:

这不是问题。 QSerialPort 按预期工作。在您的情况下,使用serial.readAll(),您可以收到1,2,3,4,5\r\n 甚至3,4,5\r\n1,2, @Meefte:问题是我需要它始终在一行中读取 1,2,3,4,5,而不是偶尔仅读取 1,2。如果我要使用数据绘制图表,当它没有给我完整的数据时,它会弄乱我的绘图程序。 【参考方案1】:

使用QSerialPort::readAll(),它只是读取串行端口上可用的任何内容,偶尔不会是整个输出字符串,我之前处理它的方式是将所有数据读入QString缓冲区,然后当行结束字符(\n\r)在缓冲区中时,使用 split('\n') 获取实际的数据行。

【讨论】:

酷,我会试试的。谢谢

以上是关于通过 QSerialPort 访问来自 Arduino 的串行数据时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章

使用 QSerialPort 通过串口发送数据

Windows 7 上的奇怪行为 QT QSerialPort 不会更改串行 com 端口的设置

从另一个线程向 QSerialPort 发送数据

使用 Linux 伪终端测试 QSerialPort

重新实现 QSerialPort canReadLine() 和 readLine() 方法

无法使用 socat 写入打开 QSerialPort