值得一提的是,虽然我有CS的背景知识,但我编写的Python脚本的数量很可能可以根据懒惰的爪子上的脚趾数来计算。就是说,我开始玩PySerial从USB条码扫描器读取数据。我遇到的一个问题是超时。如果设置得太低,我会错过扫描。如果设置得太高,则处理器利用率会很高。当然,PySerial的文档中提到了这一点:
使用readline()时要小心。打开时请指定超时 串行端口,否则如果没有换行符,它将永远阻塞 收到字符。另请注意,readlines()仅适用于 暂停。 readlines()取决于是否存在超时并解释为 作为EOF(文件末尾)。如果未打开端口,则会引发异常 正确。
对。所以,这是我的简单代码:
#!/usr/bin/env python
import serial
ser = serial.Serial('/dev/ttyACM0', rtscts=True, dsrdtr=True, timeout=0.05)
ser.baudrate = 115200
while True:
s = ser.readline()
if s:
print(s)
如何在不冒丢失扫描风险的情况下正确读取串行设备?当然,只有很少的超时,因此赔率非常低,但是我想在我的企业中将其用于生产目的,所以让我们假设这是关键任务。解决这个问题的正确方法是什么(再次,假设我对Python的了解为零)?
谢谢大家!
编辑:可能的解决方案?
我想出了以下不使用超时的内容,只是一次读取一个字符,直到到达换行符为止。看来这对处理器利用率没有影响(这是我遇到的全部问题)。当然,我需要考虑来自不同扫描仪的其他换行符的可能性,但是有什么理由为什么这行不通?
#!/usr/bin/env python
import serial
ser = serial.Serial('/dev/ttyACM0', rtscts=True, dsrdtr=True)
ser.baudrate = 115200
string = ""
while 1:
char = ser.read(1)
string += char
if char == '\r':
print(string)
string = ""
答案 0 :(得分:1)
根据我对条形码扫描仪的了解,您可以对其进行配置,以使它们仅在通过串行发送特定的写入命令时才触发扫描,您可以利用它来发挥自己的优势。
ser = serial.Serial('/dev/ttyUSBx',timeout=y)
ser.write('<trigger scan>')
value = ser.readline()
ser.close()
对于连续读取,最好的方法是保持超时循环之类的字节读取
time_start = datetime.datetime.now()
time_end = time_start + datetime.timedelta(seconds=timeout)
output = []
while datetime.datetime.now() < time_end:
output.append(ser.read(100))
答案 1 :(得分:0)
我将超时设置为高值的经验与您的断言相反。高超时可确保 python 不会每 1/20,000 秒检查一次串行缓冲区。这就是串行缓冲区的意义所在,用于存储输入直到被读取。超时以千分之一秒为单位,因此 0.05 * 1/1000 = 1/20,000 或每秒 20,000 次检查。我将其设置为 10 秒以下。 (每分钟最少 6 次检查)当然,如果 python 更快地遇到新行,则 readline() 不会超时。
#!/usr/bin/env python
import serial
ser = serial.Serial('/dev/ttyACM0', rtscts=True, dsrdtr=True, timeout=10000)
ser.baudrate = 115200
while True:
s = ser.readline()
if s:
print(s)
但是,如果您的 UART 没有缓冲区并丢弃超过一个字符的任何内容,您可能会丢失输入。这取决于您的硬件和设置。如果条码适合缓冲区,您应该不会遇到任何问题。