2013-07-09 19 views
15

Czytam dane szeregowe tak:pyserial non-blocking przeczytać pętlę

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() 

Problemem jest to, że zapobiega on niczego innego z wykonywania w tym butelka py internetowej ram. Dodanie sleep() nie pomoże.

Zmiana „podczas gdy prawda”,”z«podczas ser.readline():»nie drukuje«test», co jest dziwne, ponieważ pracował w Pythonie 2.7 Wszelkie pomysły co może być nie tak

Idealnie.? Byłbym w stanie odczytać dane szeregowe tylko wtedy, gdy jest ona dostępna dane są wysyłane co 1.000 ms

+3

nie można utworzyć wątku i dodać do niego odczytać kodu? –

+1

komunikacja szeregowa jest blokowana ... powinieneś użyć wątku –

+0

Czy możesz podać odpowiedź z przykładem? – DominicM

Odpowiedz

28

Umieścić go w osobnym wątku, np..

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

Używanie oddzielnego wątku jest zupełnie niepotrzebne. Po prostu zrób to dla swojej nieskończonej pętli while zamiast (Testowany w Pythonie 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 

ten sposób można tylko przeczytać i wydrukować, jeśli coś tam jest. Powiedziałeś: "Idealnie powinienem móc czytać dane seryjne tylko wtedy, gdy są dostępne". Dokładnie to robi powyższy kod. Jeśli nic nie jest dostępne do odczytu, przechodzi do reszty kodu w pętli while. Całkowicie nieblokujące.

(Ta odpowiedź Cytat & debugowany tutaj: Python 3 non-blocking read with pySerial (Cannot get pySerial's "in_waiting" property to work))

pyserial dokumentacja: http://pyserial.readthedocs.io/en/latest/pyserial_api.html

+1

Dzięki! To rozwiązanie wyciągnęło mnie dzisiaj z trudnego miejsca. Naprawdę uważam, że powinna to być akceptowana odpowiedź w tym przypadku. –

+2

Zamiast while (True) sugerowałbym użycie while (ser.isOpen()) – Johnny

+1

dla PySerial Version> 3, musisz użyć ser.is_open – Johnny