簡體   English   中英

QSerialPort-等待發件人的整個數據

[英]QSerialPort - wating for whole data from sender

我正在使用串行設備。 QSerialPort在單獨的線程中。 線程是通過以下方式創建的:

QThread* serialthread = new QThread;
Serial*  serial = new Serial();
serial->moveToThread(serialthread);

當數據可用時,將在我的線程工作程序中發出此信號:

    void Serial::process()
    {
        serialport = new QSerialPort();
        connect(this->serialport,SIGNAL(readyRead()),this,SLOT(readyToRead()));
    }
    void Serial::readyToRead()
    {
        emit SIG_dataAvailable(this->read());
    }

這是讀取數據並檢查數據是否正確的功能-串行設備上的第二個字節表示剩余的數據包有多長時間...

QByteArray Serial::read() const
{
    QByteArray receivedData;
    int length;
    receivedData = serialport->readAll();
    length = receivedData[1];
    if(length != receivedData.length() - 1)
    {
        qDebug() << "protocol error.";
        return NULL;
    }
    return receivedData;
}

我的問題是在緩沖區中來自串行設備的數據完成之前,發出了QSerialPort :: readyRead信號。 任何想法如何解決這個問題?

是絕對沒有保證,你會立刻得到完整的數據。 您可以通過某些方式解決此問題。

1)如果您有固定尺寸的包裹,可以執行以下操作:

void foo::onSerialRead()
{
    //! Is there whole datagram appears?
    if (m_serial->bytesAvailable() < ::package_size) {
        //! If not, waiting for other bytes
        return;
    }

    //! Read fixed size datagram.
    QByteArray package = m_serial->read(::package_size);
    //! And notify about it.
    emit packageReady(package);
}

2)如果您的包裹尺寸可能有所不同。 然后,您必須在包中包含“ hader”。 此標頭應至少包含“開始”字節和數據大小(在您的情況下為第二個字節)。 標頭應固定大小。 然后,您可以執行以下操作:

void foo::onSerialRead()
{
    static QByteArray package;
    static bool isHeaderRead = false;
    static quint8 startByte = 0;
    static quint8 dataSize = 0;

    //! Is there whole header appears?
    if (m_serial->bytesAvailable() < ::header_size) {
        //! If not, waiting for other bytes
        return;
    }

    if (!isHeaderRead) {
    //! Read fixed size header.
        package.append(m_serial->read(::header_size));
        QDataStream out(&package);

        out >> startByte;

    //! Check is it actually beginning of our package?
        if (Q_UNLIKELY(startByte != ::protocol_start_byte)) {
            return;
        }
        out >> dataSize;
        isHeaderRead = true;
    }

    //! Check is there whole package available?
    if (Q_LIKELY(dataSize > m_serial->bytesAvailable())) {
        //! If not, waiting for other bytes.
        return;
    }
    //! Read rest.
    package.append(m_serial->read(dataSize));
    //! And notify about it.
    emit packageReady(package);
    package.clear();
    isHeaderRead = false;
}

而且,將QSerial放入不同的線程絕對沒有意義。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM