serial proyectos leer guardar datos conexion con comunicar adquisicion python python-3.x nonblocking pyserial

python - proyectos - PySerial sin bloqueo de lectura



leer datos de arduino con python (3)

Ponlo en un hilo aparte, por ejemplo:

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

Estoy leyendo datos en serie como este:

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

El problema es que impide que se ejecute cualquier otra cosa, incluido el framework web de bottle py. Agregar sleep() no ayudará.

Cambiar "while True" "a" while ser.readline (): "no imprime" test ", lo cual es extraño ya que funcionó en Python 2.7. ¿Alguna idea de qué podría estar mal?

Idealmente, debería poder leer datos en serie solo cuando estén disponibles. Los datos se envían cada 1.000 ms.


Usar un hilo separado es totalmente innecesario. Simplemente haga esto para su bucle infinito while (probado en Python 3.2.3):

import serial import time # Optional (if using time.sleep() below) 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 time.sleep(0.01) # Optional: sleep 10 ms (0.01 sec) once per loop to let other threads on your PC run during this time.

De esta manera solo leerás e imprimirás si hay algo allí. Usted dijo: "Idealmente, debería poder leer datos en serie solo cuando estén disponibles". Esto es exactamente lo que hace el código anterior. Si no hay nada disponible para leer, salta al resto de su código en el bucle while. Totalmente no bloqueante.

(Esta respuesta originalmente publicada y depurada aquí: Python 3 no bloquean la lectura con pySerial (No se puede hacer que la propiedad "in_waiting" de pySerial funcione) )

documentación de pySerial: http://pyserial.readthedocs.io/en/latest/pyserial_api.html

ACTUALIZAR:

Nota sobre multihilo:

Aunque la lectura de datos en serie, como se muestra arriba, no requiere el uso de múltiples subprocesos, la lectura de la entrada del teclado de manera no bloqueante. Por lo tanto, para lograr una lectura de entrada de teclado sin bloqueo, he escrito esta respuesta: .com/questions/5404068/how-to-read-keyboard-input/… .


Utilice un evento controlado por temporizador para probar y leer el puerto serie. Ejemplo no probado:

import threading class serialreading(): def __init__(self): self.active = True self.test() def test(self): n_in =comport.in_waiting() if n_in> 0: self.data = self.data + comport.read(size=n_in) if len(self.data) > 0: print(self.data) self.data="" if self.active: threading.Timer(1, test).start() # start new timer of 1 second def stop(self): self.active = False