Qt串列埠通訊開發之QSerialPort模組Qt串列埠通訊接收資料不完整的解決方法
阿新 • • 發佈:2020-03-13
在使用串列埠接收資料時,當資料量大的時候會出現資料接收不完整的情況。
因為串列埠資料獲取函式readAll()由readyRead()訊號觸發,但readyRead()訊號在串列埠讀到起始標誌時立即傳送,並不保證一定是當前所發資料的起始部分。
因此串列埠通訊雙方在通訊前應制定好通訊協議,規定好資料的起始和結束標誌,串列埠當讀到完整的起始和結束標誌之後,才認定讀完一條完整的資料。
本例中用串列埠定時傳送當前時間,用"#"表示資料的結尾,定時時間為0毫秒,即能發多快就發多快。
傳送
void Widget::slotSendData() { QByteArray temp; temp.append(getCurrentTime()); temp.append("#"); serialPort->write(temp); }
接收
void Widget::slotReadData() { QByteArray temp = serialPort->readAll(); if(!temp.isEmpty()) { byteArray.append(temp); if(byteArray.contains("#")) { ui->textEditReceive->setText(byteArray.split('#').at(0)); byteArray = byteArray.right(byteArray.length()-byteArray.indexOf('#')-1); } } }
上面的原始碼在這裡下載
下面是一個通過串列埠傳輸圖片的例子
這裡假設波特率為9600,那麼一秒鐘就能傳輸9600/8=1200位元組。程式碼中將定時器設定為1秒,所以選擇的圖片應該小於1200位元組。
這裡為了演示如何完整接收資料,將圖片按照指定大小分段傳送,在每段之後緊接著傳送字串“###”。
程式碼如下所示:
void Widget::slotSendData() { matrix.rotate(90); QPixmap tempPixmap = pixmap.transformed(matrix); QBuffer buffer; tempPixmap.save(&buffer,"jpg"); ui->labelImage->setPixmap(tempPixmap); char *data=(char*)buffer.data().data(); int dataLength=buffer.data().length(); //列印圖片大小 qDebug()<<"Image Size:"<<dataLength; int standPacketSize=120; int packetSize=0; int packetNum=ceil(dataLength/120.0); if(dataLength>120) { for(int i=0;i<packetNum;i++) { if(standPacketSize*(i+1)<dataLength) { packetSize=standPacketSize; } else { packetSize=dataLength-standPacketSize*i; } serialPort->write(data,packetSize); data=data+packetSize; } } serialPort->write("###",3); }
執行效果如下圖所示:
上面的例項原始碼在這裡下載
本文主要介紹了QSerialPort模組Qt串列埠通訊接收資料不完整的解決方法,更多關於Qt串列埠通訊知識請檢視下面的相關連結