[英]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.