【问题标题】:Can QSerialPort read more than 512 bytes of data?QSerialPort 可以读取超过 512 字节的数据吗?
【发布时间】:2016-04-13 08:05:49
【问题描述】:

我想使用 QSerialPort 读取从设备传输的数据。设备每次传输 4000 个数据字节的帧。我尝试使用以下简单代码

QSerialPort *serialPort;
char receivedData[4000];
int numRead = 0;

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    /* Initialize serial port*/
    serialPort = new QSerialPort(this);
    QString portName = "COM6";
    qint32 baudRate = 460800;
    serialPort->setPortName(portName);
    serialPort->setBaudRate(baudRate);
    serialPort->setDataBits(QSerialPort::Data8);
    serialPort->setParity(QSerialPort::NoParity);
    serialPort->setStopBits(QSerialPort::OneStop);
    serialPort->setFlowControl(QSerialPort::NoFlowControl);
    serialPort->setReadBufferSize(4000);
    if (!serialPort->open(QIODevice::ReadOnly)) {
        qDebug() << "Cannot open comport";
    }
    connect(serialPort, SIGNAL(readyRead()), this, SLOT(serialReceived()));
}

void MainWindow::serialReceived()
{
    numRead = serialPort->read(receivedData, 4000);
    serialPort->flush();
}

问题是:它总是显示只读取了 512 个数据字节。如何读取整个 4000 字节数据帧? (当我使用 Matlab 读取这 4000 字节的帧时,它工作正常)

【问题讨论】:

  • this answer。您必须创建自己的缓冲区来读取数据,直到满足您期望的某个特定大小。您也可以使用QSerialPort::bytesAvailable 方法检查可用的字节数。
  • 嗨,我使用循环检查QSerialPort::bytesAvailable,它总是显示512字节。
  • 您是否在两次检查之间读取数据?
  • 你是对的。现在想起来,这不是正确的做法。但是我不知道应该把QSerialPort::bytesAvailable放在哪里,因为我不知道程序要等到readReady发出?
  • 您可以使用 Ilya 的建议,读取您自己的缓冲区中的所有数据,一旦该缓冲区达到 4000 字节或更多,就从您的缓冲区中删除前 4000 个字节并对这些数据进行处理。我认为可行的另一个选择是,如果您利用QSerialPorts 的内部缓冲区。当readyRead 发出时,检查bytesAvailable。如果小于 4000,则什么都不做,如果大于或等于 4000,则读取 4000 字节,直到可用的字节小于 4000。

标签: c++ qt serial-port


【解决方案1】:

没有限制,但您不一定会在单个块中接收所有数据。 您必须继续收听,直到获得等待的字节数(或超时)。

void MainWindow::serialReceived()
{
    receivedData.append(serialPort->readAll());
    if(receivedData.size() >= 4000) {
       // we're full
    }
}

【讨论】:

    【解决方案2】:

    您通常必须在循环中读取数据(以确保您得到所有​​数据),这是示例代码的 sn-p 这相当于您的 serialReceived() 函数,除了它使用 @987654321 发出数据@给正在听的人...

    void QSerialPortReader::handleReadyRead()
    {
        QByteArray newData;
    
        // Get the data
        while (mp_serialPort->bytesAvailable())
        {
            newData.append(mp_serialPort->readAll());
        }
        emit rxDataReady(newData);
    }
    

    编辑

    虽然我没有做任何最大尺寸检查...但是如果您需要它,添加它是微不足道的(即只需使用 read(..., spaceAvail) 而不是 readAll 然后递减 spaceAvail...

    【讨论】:

    • 嗨,我尝试了以下代码,但它只导致读取了 60 个字节。我不明白为什么?
      void MainWindow::serialReceived() &lt;br/&gt; { &lt;br/&gt; while (serialPort-&gt;bytesAvailable()) &lt;br/&gt; { &lt;br/&gt; readData.append(serialPort-&gt;readAll()); &lt;br/&gt; } &lt;br/&gt; }
    • 可用字节是否显示超过 60 个字节? (也许添加一个调试行)。 readReady 是否还会被多次调用?要检查的另一件事,不是 100% 确定这是否是一个问题,但看起来您正在同一个线程中运行所有这些。在你的 connect() 函数中使用Qt::QueuedConnection 可能更安全(它是可选的第 5 个参数)。在您的代码中,我不知道如果第二个 readReady 在第一个完成之前进入会发生什么。
    猜你喜欢
    • 2018-07-21
    • 2019-01-18
    • 2014-04-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多