2013-04-30 49 views
3

因此,較大項目的一部分需要使用樹莓派從串口接收長十六進制字符串。我想我已經全部工作了,但後來發現它正在丟失字符串中間的大量數據。丟失收到的串行字符串中的數據

def BUTTON_Clicked(self, widget, data= None): 

     ser = serial.Serial("/dev/ex_device", 115200, timeout=3) 

     RECEIVEDfile = open("RECIEVED.txt", "r+", 0) #unbuffered 


     #Commands sent out 
     ser.write("*n\r") 
     time.sleep(1) 
     ser.flush() 
     ser.write("*E") 
     ser.write("\r") 

     #Read back string rx'd 
     RECEIVED= ser.read() 


     RECEIVED= re.sub(r'[\W_]+', '', RECEIVED) #remove non-alphanumeric characters (caused by noise maybe?) 
     RECEIVEDfile.write(re.sub("(.{4})", "\\1\n", RECEIVED, 0, re.DOTALL)) #new line every 4 characters 


     RECEIVEDfile.close    
     ser.write("*i\r") 
     ser.close 

這是用來檢索數據的腳本,波特率和串行命令設置權限和運行腳本的「緩衝」(-u),但還沒有完整的字符串不會被保存。該字符串大約16384個字符長,但只有大約9520個字符(它變化)正在保存(不能提供用於分析的字符串)。任何人都知道我錯過了什麼?歡呼你可以給我的任何幫助。

+0

你在'刪除非字母數字字符'步驟中輸了什麼?可能值得使用相同的正則表達式來計算刪除的字符數,並查看它是否與缺失的數據匹配。 – mfitzp 2013-04-30 19:03:26

+0

是否有3秒的超時時間來獲取數據?你可以用timeout = None來試試嗎? – mfitzp 2013-04-30 19:08:33

+0

我完全刪除了解析,看看它是否是問題,但唉,沒有成功。 – CaramelElectron 2013-04-30 19:12:46

回答

2

很高興我的評論幫助!

將超時設置爲較低的數字,例如, 1秒。然後嘗試這樣的事情。它試圖讀取大塊,但很快超時並且不會長時間阻塞。無論讀到什麼都放入列表(rx_buf)中。然後永遠循環,只要你有待處理的字節讀取。真正的問題是什麼時候不知道更多的數據。

rx_buf = [ser.read(16384)] # Try reading a large chunk of data, blocking for timeout secs. 
while True: # Loop to read remaining data, to end of receive buffer. 
    pending = ser.inWaiting() 
    if pending: 
     rx_buf.append(ser.read(pending)) # Append read chunks to the list. 
    else: 
     break 

rx_data = ''.join(rx_buf) # Join the chunks, to get a string of serial data. 

我把塊放在列表中的原因是連接操作比字符串上的'+ ='更有效。

+0

作品的魅力,感謝您的全力幫助 – CaramelElectron 2013-04-30 19:56:43

+1

這也消除了我所經歷的「噪音」,一定是因爲緩衝器不快樂而造成的人爲因素 – CaramelElectron 2013-04-30 20:10:48

0

根據this question你需要閱讀從緩衝區中的塊中的數據(這裏單字節):

out = '' 
# Let's wait one second before reading output (let's give device time to answer). 
time.sleep(1) 
while ser.inWaiting() > 0: 
    out += ser.read(1) 

我懷疑什麼是你的情況下發生的是,你得到一個完整的「緩衝區'充滿數據,這取決於緩衝區的狀態可能會有所不同。

+0

你可能可以做'out + = ser.read(ser.inWaiting())'來獲得更大的塊?目前無法對其進行測試。 – mfitzp 2013-04-30 19:30:30