![](/img/trans.png)
[英]Reading realtime data from serial port from Arduino into a python script
[英]Reading serial data in realtime in Python
我使用Python中的腳本通過串行端口以2Mbps從PIC單片機收集數據。
PIC工作在2Mbps的完美時序,FTDI usb串行端口也能在2Mbps下工作(均通過示波器驗證)
我發送消息(大約15個字符大小)大約每秒100-150倍,並增加數量(以檢查我是否有丟失的消息等)
在我的筆記本電腦上我有Xubuntu作為虛擬機運行,我可以通過Putty和我的腳本(python 2.7和pySerial)讀取串口
問題:
這是代碼(我省略了大部分代碼,但循環是相同的):
ser = serial.Serial('/dev/ttyUSB0', 2000000, timeout=2, xonxoff=False, rtscts=False, dsrdtr=False) #Tried with and without the last 3 parameters, and also at 1Mbps, same happens.
ser.flushInput()
ser.flushOutput()
While True:
data_raw = ser.readline()
print(data_raw)
任何人都知道為什么pySerial需要這么多時間從串口讀取直到行尾? 有幫助嗎?
我想實時擁有這個。
謝謝
您可以使用inWaiting()
來獲取輸入隊列中可用的字節數。
然后你可以使用read()
來讀取字節,類似於:
While True:
bytesToRead = ser.inWaiting()
ser.read(bytesToRead)
為什么不使用readline()
在這種情況下,從文檔:
Read a line which is terminated with end-of-line (eol) character (\n by default) or until timeout.
你正在等待每次讀數的超時,因為它等待eol。 串行輸入Q保持不變只需要很長時間才能到達緩沖區的“結束”,為了更好地理解它:你正在寫入輸入Q就像賽車一樣,讀起來就像一輛舊車:)
打開串口時,需要將超時設置為“無”:
ser = serial.Serial(**bco_port**, timeout=None, baudrate=115000, xonxoff=False, rtscts=False, dsrdtr=False)
這是一個阻塞命令,所以你要等到收到末尾有換行符(\\ n或\\ r \\ n)的數據:line = ser.readline()
獲得數據后,它將盡快返回。
從手冊 :
參數超時的可能值:... x set timeout to x seconds
和
readlines(sizehint = None,eol ='\\ n')讀取行列表,直到超時。 sizehint被忽略,僅用於與內置File對象的API兼容性。
請注意,此函數僅在超時時返回。
因此,您的readlines
最多每2秒返回一次。 如Tim建議的那樣使用read()
。
可以在這里找到一個非常好的解決方案:
這是一個類,用作pyserial對象的包裝器。 它允許您讀取沒有100%CPU的行。 它不包含任何超時邏輯。 如果發生超時,則
self.s.read(i)
返回一個空字符串,您可能希望拋出異常以指示超時。
據作者說,它也應該很快:
下面的代碼給我790 kB / sec,而用pyserial的readline方法替換代碼只給我170kB /秒。
class ReadLine:
def __init__(self, s):
self.buf = bytearray()
self.s = s
def readline(self):
i = self.buf.find(b"\n")
if i >= 0:
r = self.buf[:i+1]
self.buf = self.buf[i+1:]
return r
while True:
i = max(1, min(2048, self.s.in_waiting))
data = self.s.read(i)
i = data.find(b"\n")
if i >= 0:
r = self.buf + data[:i+1]
self.buf[0:] = data[i+1:]
return r
else:
self.buf.extend(data)
ser = serial.Serial('COM7', 9600)
rl = ReadLine(ser)
while True:
print(rl.readline())
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.