通过 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 的串行数据时遇到问题的主要内容,如果未能解决你的问题,请参考以下文章
Windows 7 上的奇怪行为 QT QSerialPort 不会更改串行 com 端口的设置