2013-07-09 12 views
15

Sto leggendo i dati di serie in questo modo:pySerial non-blocking ciclo leggere

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

Il problema è che impedisce qualsiasi altra cosa di eseguire tra cui framework web bottiglia py. L'aggiunta di sleep() non sarà di aiuto.

Modifica "while True"" a "mentre ser.readline():" non stampare "test", che è strano dato che ha lavorato in Python 2.7 Tutte le idee che potrebbero essere sbagliato

Idealmente.? dovrei essere in grado di leggere i dati seriali solo quando è disponibili dati vengono inviati ogni 1.000 ms

+3

Non ti creare un thread e aggiungere questo leggere il codice ad esso? –

+1

la comunicazione seriale sta bloccando ... dovresti usare una discussione –

+0

Potresti postare una risposta con un esempio? – DominicM

risposta

28

metterlo in un thread separato, per esempio:..

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

L'utilizzo di un thread separato non è necessario. Basta fare questo per la vostra infinita ciclo while invece (testato in 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 

In questo modo è solo leggere e stampare se qualcosa c'è. Hai detto, "Idealmente dovrei essere in grado di leggere i dati seriali solo quando è disponibile." Questo è esattamente ciò che fa il codice sopra. Se non c'è nulla da leggere, salta al resto del codice nel ciclo while. Totalmente non bloccante.

(Questa risposta originariamente pubblicato & debug qui: Python 3 non-blocking read with pySerial (Cannot get pySerial's "in_waiting" property to work))

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

+1

Grazie! Questa soluzione mi ha fatto uscire da un punto difficile oggi. Sento davvero che questa dovrebbe essere la risposta accettata in questo caso. –

+2

Invece di while (True) suggerirei di usare while (ser.isOpen()) – Johnny

+1

per PySerial Version> 3 devi usare ser.is_open – Johnny

Problemi correlati