因此,较大项目的一部分需要使用raspberry pi从串行端口接收长十六进制字符串。我以为我已经完成了所有工作但后来发现它在字符串中间丢失了一大块数据。
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
这是用于检索数据的脚本,波特率和串行命令设置正确,脚本以“unbuffered”(-u)运行,但不保存完整的字符串。该字符串长约16384个字符,但只保存了大约9520个字符(它变化)(无法提供字符串进行分析)。谁知道我错过了什么?欢呼,你可以给我任何帮助。
答案 0 :(得分: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.
我将这些块放在列表中的原因是,连接操作比' + ='更有效。在字符串上。
答案 1 :(得分: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)
我怀疑你的情况发生的是你正在获得一个完整的'缓冲区'数据,这取决于缓冲区的状态可能会有所不同。