问题
I have a very basic parrot script written in Python that simply prompts for a user input and prints it back inside an infinite loop. The Raspberry Pi has a USB barcode scanner attached for the input.
while True:
barcode = raw_input("Scan barcode: ")
print "Barcode scanned: " + barcode
When you scan at a "normal" speed it works reliably and the command output looks like this:
Scan barcode: 9780465031467
Barcode scanned: 9780465031467
Scan barcode: 9780007505142
Barcode scanned: 9780007505142
But when you really hammer it with many scans in close succession it is possible to make it miss inputs and the command output looks like this:
Scan barcode: 9780141049113
Barcode scanned: 9780141049113
Scan barcode: 9780465031467
Barcode scanned: 9780465031467
Scan barcode: 9780007505142
9780571273188
Barcode scanned: 9780571273188
Notice how 9780007505142
was input but never printed back. It got lost in the confusion.
See a video demonstration of my test at: https://youtu.be/kdsfdKFhC1M
My question: Is this an inevitability of using a low powered device like a Pi? Will it always be true that a user with a barcode scanner will be able to out-run the hardware's ability to keep up?
回答1:
You should probably read from stdin
directly using code similar to the following:
import os
import sys
import select
stdin_fd = sys.stdin.fileno()
try:
while True:
sys.stdout.write("Scan barcode: ")
sys.stdout.flush()
r_list = [stdin_fd]
w_list = list()
x_list = list()
r_list, w_list, x_list = select.select(r_list, w_list, x_list)
if stdin_fd in r_list:
result = os.read(stdin_fd, 1024)
result = result.rstrip()
result = [line.rstrip() for line in result.split('\n')]
for line in result:
print "Barcode scanned: %s" % line
except KeyboardInterrupt:
print "Keyboard interrupt"
This code should handle the case that multiple lines are read at once. The read
buffer size is arbitrary and you might have to change it depending on how much data you need to handle.
回答2:
I know this is a little late, but after a closer look at the raw_input() docs I think it is pretty plain that raw_input is not designed to handle multi-line inputs. When it encounters a multi-line input it seems to only read the last line. (as demonstrated by your test). So my question is, how is raw_input getting a multi-line input in the first place? is the delay caused by the python program not being able to process the raw_input fast enough? Or is the delay inside the USB scanner/driver, and as a result it outputs two numbers instantaneously causing raw_input to process the last line without giving it an opportunity to process the first?
来源:https://stackoverflow.com/questions/40156905/python-on-raspberry-pi-user-input-inside-infinite-loop-misses-inputs-when-hit-wi