问题
I am trying to code the following using python3 in a raspberry pi:
1) wait for a 14 digits bar code (barcode scanner connected through usb port and input received as keyboard data)
2) after a barcode is read, wait for serial communication (device connected to usb port and sends serial commands. could be one, or more....) the idea is that all commands received are going to be associated with the scanned barcode
3) the process of waiting for serial commands has to stop when a new barcode is read. THIS IS THE PART I HAVE NOT FIGURED OUT HOW TO DO IT
After some research, I decided to use the "readchar" library for the barcode scanner and the "serial" library for the serial communication received. Both of them work by themselves but the problem is when I try to detect both things at the same time.
In the following code, I managed to read a barcode and then wait for 5 lines of serial communication to finally repeat the process and read a barcode again. The program works as it is right now BUT the problem is that I don't know how many lines of serial communication I will receive so I need to somehow detect a new barcode while also waiting to receive the serial communication.
import readchar
import time
import serial
ser = serial.Serial(
port='/dev/ttyUSB0',
baudrate = 115200,
parity=serial.PARITY_NONE,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS,
timeout=1
)
print("Waiting for barcode...")
while 1:
inputStr = ""
while len(inputStr) != 14: #detect only 14 digit barcodes
inputStr += str(readchar.readchar())
inputStr = ''.join(e for e in inputStr if e.isalnum()) #had to add this to strip non alphanumeric characters
currentCode = inputStr
inputStr = ""
print(currentCode)
ser.flushInput()
time.sleep(.1)
# Wait for 5 lines of serial communication
# BUT it should break the while loop when a new barcode is read!
count = 0
while count < 5:
dataRead=ser.readline()
if len(dataRead) > 0:
print(dataRead)
count+=1
print("Waiting for barcode...")
If I add a condition to the while loop that reading the serial communication using (ser.readline()) so that if a character is read from the scanner (readchar.readchar()) then it messes thing up. It is like if readline and reacher can not be in the same while loop.
Doing some research I think I need to use Asynchronous IO, or threads or something like that, but I have no clue. Also I don't know if I could keep using the same libraries (serial and readchar). Please help
回答1:
I cannot be sure (I don't have your barcode reader and serial port device) but based on what you say I don't think you need threads, you just have to rely on the buffers to keep your data stored until you have time to read them.
Simply change the condition on your second while
loop to:
while serial.inWaiting() != 0:
This way you will make sure the RX buffer on your serial port will empty. This approach might or might not work depending on the speed and timing of your devices.
You could also try to add a short delay after the buffer is emptied:
import serial
import time
ser=serial.Serial(port="/dev/ttyUSB0",baudrate=115200, timeout=1.0)
time.sleep(1)
data=b""
timeout = time.time() + 1.0
while ser.inWaiting() or time.time()-timeout < 0.0: #keep reading until the RX buffer is empty and wait for 1 seconds to make sure no more data is coming
if ser.inWaiting() > 0:
data+=ser.read(ser.inWaiting())
timeout = time.time() + 1.0
else:
print("waiting...")
This keeps trying to read from the port for 1 second after the last byte is received, to make sure nothing else is coming. You might want to play with the duration of the delay depending, again, on the speed and timing of your devices.
Again, I don't have your devices, so I'm in no position to judge, but the way you read characters from the barcode/keyboard looks far from optimum. I doubt readchar
is the best approach. At the end of the day, your barcode reader is probably a serial port. You might want to dig into that and/or find a more efficient way to read several keyboard strokes in one go.
回答2:
I found this answer in another question:
How to read keyboard-input?
I have tried it and it works! I´ll also give a try to the method proposed by Marcos G.
来源:https://stackoverflow.com/questions/58615285/how-to-check-simultaneously-for-serial-input-and-input-from-keyboard-simultaneo