我正在读取这样的串行数据:
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()
问题在于它阻止了其他任何东西的执行,包括bottle py web框架。添加 sleep()
不会有帮助。
将 "while True""更改为 "while ser.readline():"不会打印 "test",这很奇怪,因为它在 Python 2.7 中有效。有什么想法可能是错误的吗?
理想情况下,我应该只有在可用时才能读取串行数据。每 1000 毫秒发送一次数据。
最佳答案
完全没有必要使用单独的线程。只需按照下面的示例进行无限 while 循环即可。
我在我的 eRCaGuy_PyTerm 串行终端程序 here (search the code for inWaiting()
or in_waiting
) 中使用了这种技术。
注意事项:
要检查你的 python3 版本,运行这个:
python3 --version
当我第一次编写和测试这个答案时,我的输出是
Python 3.2.3
。要检查你的 pyserial 库(
serial
模块)版本,运行这个——我第一次学习这个 here :python3 -c 'import serial; \ print("serial.__version__ = {}".format(serial.__version__))'
这只是导入
serial
模块并打印其serial.__version__
属性。 截至 2022 年 10 月,我的输出是:serial.__version__ = 3.5
。如果您的 pyserial 版本是 3.0 或更高版本,请在下面的代码中使用 property
in_waiting
。如果您的 pyserial 版本是 < 3.0,请在下面的代码中使用 functioninWaiting()
。在此处查看官方 pyserial 文档:https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.in_waiting。
非阻塞、单线程串行读取示例
import serial
import time # Optional (required if using time.sleep() below)
ser = serial.Serial(port='COM4', baudrate=9600)
while (True):
# Check if incoming bytes are waiting to be read from the serial input
# buffer.
# NB: for PySerial v3.0 or later, use property `in_waiting` instead of
# function `inWaiting()` below!
if (ser.inWaiting() > 0):
# read the bytes and convert from binary array to ASCII
data_str = ser.read(ser.inWaiting()).decode('ascii')
# print the incoming string without putting a new-line
# ('\n') automatically after every print()
print(data_str, end='')
# Put the rest of your code you want here
# Optional, but recommended: sleep 10 ms (0.01 sec) once per loop to let
# other threads on your PC run during this time.
time.sleep(0.01)
这样你只有在有东西的时候才能阅读和打印。你说,“理想情况下,我应该只有在可用时才能读取串行数据。”这正是上面的代码所做的。如果没有可读取的内容,它会跳到 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
更新:
- 2018 年 12 月 27 日:添加了关于
in_waiting
与inWaiting()
的评论。感谢@FurkanTürkal 在下面的评论中指出这一点。请参阅此处的文档:https://pyserial.readthedocs.io/en/latest/pyserial_api.html#serial.Serial.in_waiting。 - 2018 年 10 月 27 日:添加 sleep 以让其他线程运行。
- 文档:https://docs.python.org/3/library/time.html#time.sleep
- 感谢 @RufusV2 在评论中提出这一点。
多线程注意事项:
尽管读取串行数据,如上所示,不需要需要使用多个线程,但以非阻塞方式读取键盘输入需要。因此,为了完成非阻塞键盘输入读取,我写了这个答案:How to read keyboard input?。
引用资料:
- 官方pySerial
serial.Serial()
类API - https://pyserial.readthedocs.io/en/latest/pyserial_api.html
关于python - PySerial 非阻塞读取循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17553543/