Reputation: 21
UPDATED:
I've successfully been able to read a USB barcode scanner using Python. I want to be able to escape the fp.read()
if it is empty and check if the user has pushed the left LCD button
def read Barcode
lcd.backlight(lcd.GREEN)
hid = { 4: 'a', 5: 'b', 6: 'c', 7: 'd', 8: 'e', 9: 'f', 10: 'g', 11: 'h', 12: 'i', 13: 'j', 14: 'k', 15: 'l', 16: 'm', 17: 'n', 18: 'o', 19: 'p', 20: 'q', 21: 'r', 22: 's', 23: 't', 24: 'u', 25: 'v', 26: 'w', 27: 'x', 28: 'y', 29: 'z', 30: '1', 31: '2', 32: '3', 33: '4', 34: '5', 35: '6', 36: '7', 37: '8', 38: '9', 39: '0', 44: ' ', 45: '-', 46: '=', 47: '[', 48: ']', 49: '\\', 51: ';' , 52: '\'', 53: '~', 54: ',', 55: '.', 56: '/' }
hid2 = { 4: 'A', 5: 'B', 6: 'C', 7: 'D', 8: 'E', 9: 'F', 10: 'G', 11: 'H', 12: 'I', 13: 'J', 14: 'K', 15: 'L', 16: 'M', 17: 'N', 18: 'O', 19: 'P', 20: 'Q', 21: 'R', 22: 'S', 23: 'T', 24: 'U', 25: 'V', 26: 'W', 27: 'X', 28: 'Y', 29: 'Z', 30: '!', 31: '@', 32: '#', 33: '$', 34: '%', 35: '^', 36: '&', 37: '*', 38: '(', 39: ')', 44: ' ', 45: '_', 46: '+', 47: '{', 48: '}', 49: '|', 51: ':' , 52: '"', 53: '~', 54: '<', 55: '>', 56: '?' }
backPressed = False
lcd.clear()
lcd.message("accn: \nLocation: ")
lcd.setCursor(7, 1)
print("Scan Next Accn:")
while not backPressed:
fp = open('/dev/hidraw0', 'r')
accn = ""
shift = False
done = False
print("should loop")
r, w, e = select.select([ fp ], [], [], 0)
print("Should be a line here")
if fp in r:
print("Fp is in r")
while not done:
print("looping")
buffer = os.read(fp.fileno(), 8)
for c in buffer:
if ord(c) > 0:
if int(ord(c)) == 40:
done = True
fp.flush()
fp.close()
print("Done = True")
break;
if shift:
if int(ord(c)) == 2 :
shift = True
else:
accn += hid2[ int(ord(c)) ]
shift = False
else:
if int(ord(c)) == 2 :
shift = True
else:
accn += hid[ int(ord(c)) ]
print("accn: " + accn)
fileAccn(accn)
fp.close()
backPressed = lcd.buttonPressed(lcd.LEFT)
if(backPressed):
lcd.backlight(lcd.WHITE)
return
backPressed = lcd.buttonPressed(lcd.LEFT)
if(backPressed):
return
return
Since the barcode scanner doesn't send an EOF
Using fp.read()
without arguments wont return if it's empty. Any help is appreciated. I'm hesitant to use interrupts or timeouts because I don't want to end the function in the middle of scanning a barcode.
Thanks in advance.
Upvotes: 1
Views: 11852
Reputation: 21
I just wanted to update with a legit answer. I think this problem is best solved with evdev
.
Here is the function I have cobbled together.
Basically, when it's called it will read one event from the barcode scanner event = dev.read_one()
.
If there is no even it moves along.
When it hits a character, it will keep checking the contents of the even until it gets a return key event. At that point, the barcode is finished and it returns. To exit the loop, the user can press the back button lcd.LEFT
is pushed
A couple of notes, it might be a good idea to read every event before entering the function or at the start. I don't think this functions clears out all of the events and if events happen before the function is called (i.e. you scan a barcode) it could catch the last few characters.
#!/usr/bin/env python
from evdev import *
import signal, sys, time
keys = {
# Scancode: ASCIICode
0: None, 1: u'ESC', 2: u'1', 3: u'2', 4: u'3', 5: u'4', 6: u'5', 7: u'6', 8: u'7', 9: u'8',
10: u'9', 11: u'0', 12: u'-', 13: u'=', 14: u'BKSP', 15: u'TAB', 16: u'Q', 17: u'W', 18: u'E', 19: u'R',
20: u'T', 21: u'Y', 22: u'U', 23: u'I', 24: u'O', 25: u'P', 26: u'[', 27: u']', 28: u'CRLF', 29: u'LCTRL',
30: u'A', 31: u'S', 32: u'D', 33: u'F', 34: u'G', 35: u'H', 36: u'J', 37: u'K', 38: u'L', 39: u';',
40: u'"', 41: u'`', 42: u'LSHFT', 43: u'\\', 44: u'Z', 45: u'X', 46: u'C', 47: u'V', 48: u'B', 49: u'N',
50: u'M', 51: u',', 52: u'.', 53: u'/', 54: u'RSHFT', 56: u'LALT', 100: u'RALT'
}
dev = InputDevice('/dev/input/event0')
def scanBarcode():
barcode = ''
while True:
event = dev.read_one()
if event is None and barcode == '':
#There are blank events in between characters,
#so we don't want to break if we've started
#reading them
break #nothing of importance, start a new read.
try:
if event is not None:
if event.type == ecodes.EV_KEY:
data = categorize(event)
if data.keystate == 0 and data.scancode != 42: # Catch only keyup, and not Enter
if data.scancode == 28: #looking return key to be pressed
return barcode
else:
barcode += keys[data.scancode] # add the new char to the barcode
except AttributeError:
print "error parsing stream"
return 'SOMETHING WENT WRONG'
if lcd.buttonPressed(lcd.LEFT):
return
Upvotes: 1
Reputation: 656
Maybe the answer to this question could help. It suggests to use os.read()
with a specified number of bytes instead of the regular read
, as os.read()
will return when it has read anything.
Upvotes: 0