2013-07-09 327 views
15

我讀的串行數據是這樣的:PySerial非阻塞讀循環

connected = False 
port = 'COM4' 
baud = 9600 

ser = serial.Serial(port, baud, timeout=0) 

while not connected: 
    #serin = ser.read() 
    connected = True 

    while True: 
     print("test") 
     reading = ser.readline().decode() 

的問題是,它可以防止任何從執行包括瓶PY Web框架別的。添加sleep()將無濟於事。

更改「而真正的」」來‘而ser.readline():’不打印‘測試’,這是奇怪的,因爲它在Python 2.7工作的任何想法可能是錯誤的

理想?我應該能夠讀取串行數據,只有當它的可用數據被每1000毫秒發送

+3

難道你創建一個線程,並添加該代碼讀它? –

+1

串行通訊正在阻止...您應該使用線程 –

+0

您可以用示例發佈答案嗎? – DominicM

回答

28

把它放在一個單獨的線程,例如:。

import threading 
import serial 

connected = False 
port = 'COM4' 
baud = 9600 

serial_port = serial.Serial(port, baud, timeout=0) 

def handle_data(data): 
    print(data) 

def read_from_port(ser): 
    while not connected: 
     #serin = ser.read() 
     connected = True 

     while True: 
      print("test") 
      reading = ser.readline().decode() 
      handle_data(reading) 

thread = threading.Thread(target=read_from_port, args=(serial_port,)) 
thread.start() 

http://docs.python.org/3/library/threading

21

使用單獨的線程是完全沒有必要的。只是這樣做你的無限while循環,而不是(在Python 3.2.3測試):

while (True): 
    if (ser.inWaiting()>0): #if incoming bytes are waiting to be read from the serial input buffer 
     data_str = ser.read(ser.inWaiting()).decode('ascii') #read the bytes and convert from binary array to ASCII 
     print(data_str, end='') #print the incoming string without putting a new-line ('\n') automatically after every print() 
    #Put the rest of your code you want here 

這樣,你只能閱讀和打印,如果事情是存在的。你說,「理想情況下,我應該只能在串行數據可用時才能讀取。」這正是上面的代碼所做的。如果沒有可讀的內容,它跳轉到while循環中的其餘代碼。完全無阻塞。

(這個答案最初發布&這裏調試:Python 3 non-blocking read with pySerial (Cannot get pySerial's "in_waiting" property to work)

pySerial文檔:http://pyserial.readthedocs.io/en/latest/pyserial_api.html

+1

謝謝!這個解決方案讓我今天走出困境。我真的覺得這應該是在這種情況下被接受的答案。 –

+2

而不是while(True)我建議使用while(ser.isOpen()) – Johnny

+1

PySerial版本> 3,您需要使用ser.is_open – Johnny