USB HID barcode readers in embedded Linux

Jul 28

Nowadays many devices such as barcode scanners, NFC readers etc. come with USB interfaces and can emulate a USB HID keyboard. This is great for interactive applications that read barcodes from STDIN, but for an embedded device (such as the Raspberry Pi) with background processes reading the barcodes this can be a nightmare.

Even though Linux exposes the device under /dev/input and as /dev/hidrawX when you read from those devices what you get is a lot more complicated than simply the contents of the barcode and hence it makes programming a lot more complex.

Virtual Consoles and inittab to the rescue!

Provided that your embedded Linux supports virtual consoles, you can write your application to simply read barcodes etc. from STDIN, test it in an interactive terminal and once it works set up inittab to run your application on a virtual console automatically every time your device starts! Your application will be receiving the decoded barcodes on STDIN or from /dev/tty and whoala!


  • Comment out the existing getty on tty2 from inittab and
  • Add a line to run your application on the second virtual console (tty2) automatically
    1. #2:23:respawn:/sbin/getty 38400 tty2
    2. 2:23:respawn:/bin/openvt -c 2 -f -s -w -- /path/to/your/application

    This will run your application on tty2 automatically when your embedded device starts, switch to that virtual console and send all the input from all USB HID keyboards to the STDIN of your application. Yes! You can have multiple HID USB keyboard emulating devices attached and they will all work.

    Known drawbacks

    • If your HID device(s) somehow manages to send Ctrl+C your application will receive EOF and probably terminate, but init will simply restart it again right away.
    • If your application reads lines you will need to program your HID device to append CR to the end of any barcode scanned or other input generated.

    You can read up on the openvt command using “man openvt”, but shortly the options do the following:

    • -c 2, select tty2, second virtual console
    • -f, force even if something else is attached to tty2 already
    • -s, switch to tty2 every time this command starts – this is vital as an inactive virtual console receives nothing
    • -w, wait for the process to complete before respawning it again
    • –, end of openvt options

Not unto the swift…

The race is not to the swift or the battle to the strong, nor does food come to the wise or wealth to the brilliant or favor to the learned; but time and chance happen to them all.
— Ecclesiates 9:11 (NIV)