2016-03-04 267 views
0

我正在使用Qt的QSerialPort庫與RS232通信。我將ReadyRead信號連接到readData()插槽;QSerialPort分別讀取十六進制值

connect(comms,SIGNAL(readyRead()),this,SLOT(readData())); 

當我發送像「Hello World!」這樣的字符串時,我可以使用comms.readAll()和comms.bytesAvailable()返回12讀取所有數據。

但是,當我發送「Hello World!\ n \ r」時,它會顯示「Hello World!」。和「\ n \ r」部分sepereatly和comms.bytesAvailable()返回12,再2

而且越來越糟糕時我送十六進制字節一樣(不帶空格)

0x0F 0x00 0x43 0x11 0x00 0x04 0x11 0x00 0x02 0x70 

它讀取值正確,但一次只有1或2個字節。我嘗試了waitForRead(),但沒有幫助。

如何一次讀取所有傳入的字節,即使它不是標準的字母?

回答

1

嘗試從端口讀取,而字節可用:

if (f_port->bytesAvailable()) { // If there are bytes available 
    QByteArray f_data; // data container 
    f_data.clear(); 

    if (f_port->open(QIODevice::ReadWrite)) { // Try to open the port 
     while(f_port->bytesAvailable()) { // Reading loop 
      f_data.append(f_port->readAll()); 
     } 

     f_port->flush(); 
     f_port->close(); 
    } 
    qDebug() << f_data; // Check the result 
} 
+0

完美謝謝。 – user2431358

+0

我不認爲這將始終有效,因爲您需要在協議中有自己的方式來判斷是否讀取了整個消息。 。 。 (也許是用4個字節來聲明它的長度,或者其他答案中討論的一些技術)。 。 。 看看這在[財富客戶](http://doc.qt.io/qt-5/qtnetwork-fortuneclient-example.html)和[財富服務器](http:// doc。 qt.io/qt-5/qtnetwork-fortuneserver-example.html),我知道他們談論'QTcpSocket',但他們解決了我所說的問題。 。 。 – Mike

+1

我完全同意@Mike。嵌入方法來檢查協議中的數據一致性始終是正確的。但是,使用RS232時,您經常需要處理設備。你並不總是有機會改變協議。我個人使用簡單的字節校驗和,將校驗和作爲2個ASCII字符傳遞,代表塊中數據塊的十六進制數的總和。 – viddik13

0

很抱歉,您不能確定已讀取所有數據。

您必須收集某些中間緩衝區中的傳入數據並對其進行分析以查找符合協議定義的命令。也就是說,必須滿足一定的要求,如固定長度或特定的起始字節(例如0x02)或結束字節(\ r想到)或這些的組合。

0

這樣做的一種方法是使用獲取的字節累積緩衝區。 然後驗證它是否是一個正確的命令(由您決定什麼是正確的)並觸發您想要執行的命令。 你也應該有一個計時器來清除緩衝區中的垃圾。

讓我們從一個小的僞

static QByteArrray s_vBuffer; 
    readData() 
    { 
     s_vBuffer.append(....); 
     bool bValidCommand=VerifyCommand(s_vBuffer); 
     if(bValidCommand) 
     { 
      QByteArray vCommand=ExtractCommand(s_vBuffer);//also removing the part of the command 
      ExecuteCommand(vCommand);  
     } 
    else 
    { 
     //if timeout clear s_vBuffer 
    } 
} 

其他技術包括校驗,CRC等你command.etc年底看到