5

For a new project, I need to read input from a USB barcode scanner (that registers as a keyboard) and perform some actions on the "typed" text whenever the Enter key was pressed.

The requirement is that this code run on a headless Raspberry Pi 3, and that it be started on boot, indefinitely waiting for input. I know how to wait for and process keyboard input in, for example, Python, but I have no idea how to do it in a background process (e.g., by starting the script in rc.local or via crontab).

Are there any techniques how to achieve this kind of requirement? It doesn't have to be in Python, but it has to run on Raspbian. Some code examples would be perfect, but links to tutorials/techniques/documentation are greatly appreciated, too.

4

I think this link is probably what you are looking for.

Briefly, if your device works similar to the one mentioned in the link above, there should be a file created as /dev/???? when you plug it in, which you could open in a python script and continuously read line by line using readline (assuming each scan prints the barcode followed by newline) and process it. You can launch the script as a background process by adding the following line near the end (but before the exit 0) of /etc/rc.local like so

python /home/pi/scripts/barscanner.py &

  • it is critical the process is started in the background using & as the OS will not finish the boot process until the /etc/rc.local script exits
  • needless to say if you are going to plug in the device after booting the Pi, your script will need to wait for the file /dev/???? to get created (you can use stat to check say every second) before attempting to read from it
  • Thanks, the solution given in the link works! Now I encountered another problem, but I'll open a new question for that. – TheWolf Sep 26 '16 at 11:54
  • @TheWolf I am working a similar project and would be interested in reading about any discussion preceding or trailing this EXCELLENT Q&A discussion. – gatorback Oct 30 '16 at 12:48
  • @gatorback My other question is here: raspberrypi.stackexchange.com/questions/55527/… It is only remotely related, though. – TheWolf Nov 15 '16 at 11:39
1

If one desires to process an inbound HID text string in Python, an alternative is to use EVDEV:

import evdev
from evdev import InputDevice, categorize, ecodes  
dev = InputDevice('/dev/input/event1')

# Modify as needed
scancodes = {
    # 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', 57: u' ', 100: u'RALT'
}

capscodes = {
    0: None, 1: u'ESC', 2: u'!', 3: u'@', 4: u'#', 5: u'$', 6: u'%', 7: u'^', 8: u'&', 9: u'*',
    10: u'(', 11: u')', 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',  57: u' ', 100: u'RALT'
}
#setup vars
x = ''
caps = False

#grab provides exclusive access to the device
dev.grab()

#loop
for event in dev.read_loop():
    if event.type == ecodes.EV_KEY:
        data = categorize(event)  # Save the event temporarily to introspect it
        if data.scancode == 42:
            if data.keystate == 1:
                caps = True
            if data.keystate == 0:
                caps = False
        if data.keystate == 1:  # Down events only
            if caps:
                key_lookup = u'{}'.format(capscodes.get(data.scancode)) or u'UNKNOWN:[{}]'.format(data.scancode)  # Lookup or return UNKNOWN:XX
            else:
                key_lookup = u'{}'.format(scancodes.get(data.scancode)) or u'UNKNOWN:[{}]'.format(data.scancode)  # Lookup or return UNKNOWN:XX
            if (data.scancode != 42) and (data.scancode != 28):
                x += key_lookup  
            if(data.scancode == 28):
                print x          # Print it all out!
                x = ''[enter link description here][1]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.