QT:从串口连续读取数据的问题

Posted

技术标签:

【中文标题】QT:从串口连续读取数据的问题【英文标题】:QT: problems with the continuous reading of data from the serial port 【发布时间】:2020-08-06 08:31:45 【问题描述】:

我正在使用 QT 从串口读取数据,在主窗口中我编写了以下代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QTextStream>
#include<QSerialPort>
#include<QSerialPortInfo>
#include<QtDebug>
#include<QThread>
QSerialPort *serial;
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
     ui(new Ui::MainWindow),
      m_standardOutput(stdout)

     ui->setupUi(this);
    serial= new QSerialPort(this);
    serial->setPortName("COM3");
    serial->setBaudRate(QSerialPort::Baud115200);
    serial->setDataBits(QSerialPort::Data8);
    serial->setParity(QSerialPort::NoParity);
    serial->setStopBits(QSerialPort::OneStop);
    serial->setFlowControl(QSerialPort::NoFlowControl);
    serial->open(QIODevice::ReadOnly);



    connect(serial, &QSerialPort::readyRead, this, &MainWindow::ReaderH);

    float HUM;
     HUM=H;



MainWindow::~MainWindow()

    delete ui;


void MainWindow::ReaderH()


        quint64 X=20;
    serial->waitForReadyRead();
    m_readData=serial->QSerialPort::read(X);
    //if (!m_timer.isActive())
      //     m_timer.start(5000);
     inter2=QString(m_readData);
    QStringList firstlist2= inter2.split(";");
    m_readData3=firstlist2.takeFirst();
    H=m_readData3.toFloat();
     qDebug() <<"Data:"<<m_readData<< " \r\n";
    //QThread::sleep(11);



程序在几秒钟内正确读取数据,过了一会儿读取开始出现异相,如下所示:

数据:“60.904655;25.779804$”

数据:“60.970406;25.816269$”

数据:“60.988335;25.798037$”

数据:“60”。

数据:“883736;25.7”

数据:“61570$”

数据:“60”。

数据:“91063”

数据:“7;25.779804$”

数据:“60”。

数据:“934544;25。”

数据:“798037$”

数据:“60”

数据:“.871784;25.798037$”

我不明白如何解决这个问题。 感谢您的宝贵时间。

【问题讨论】:

您似乎假设将保留消息边界。事实并非如此。来自/来自串行端口连接的数据只不过是一个字节流——由你来解析传入的数据并重组消息。 【参考方案1】:

从串口读取时,需要自己将“流”切割成“消息”。为了稳健,您不应该对数据的时间做出任何假设。

当接收到数据时,您应该将它们输入到“解码器”,即通常读取每个字节并找到数据包的“分隔符”的类。

解码器类通常有一个内部缓冲区,可能看起来像这样:

class Decoder : public QObject

    Q_OBJECT

signals: 
    void messsageReceived(QByteArray message);

public:    
    void decode(const QByteArray& bytes)
    
        for (char c : bytes)
        
            if (c == '$')
            
                emit messsageReceived(m_buffer);
                m_buffer.clear();
            
            else
            
                 m_buffer.append(c);
            
        
    

private:
    QByteArray m_buffer;
;

通常也不能保证您会在数据包的开头开始阅读。第一次读取可能发生在数据包的中间,这就是为什么大多数协议使用“开始”和“停止”序列的原因,或者如果您无法验证其一致性,则应该丢弃第一个数据包。在上面的sn-p中,第一个数据包没有被处理。

此外,串行端口不保证通过线路传输字节无误,因此如果数据是合理的,则必须具有验证机制,例如校验和(即 CRC)。如果某些数据已损坏,则应丢弃数据包,并且可能必须在更高级别设置一种机制,以便重新传输数据包(如果需要)。

【讨论】:

以上是关于QT:从串口连续读取数据的问题的主要内容,如果未能解决你的问题,请参考以下文章

QT如何将串口读取的temp中的数据赋值给一个字符数组distance[]

Qt监控Arduino开关状态(读取串口数据)

QT串口不工作

Qt串口数据显示

JAVA开启三个线程,去读取数组中的数据不能重复

Qt 串行端口错误 - 未读取数据