Sunday, December 22, 2013

USB Keyboard on Raspberry Pi

Targus Numeric Keypad

For the lala-pi "room security system" project I am building, I needed a way for an intruder to enter in a security code to disable the security system.  A full keyboard is a bit too bulky.  Luckily, small USB numeric "Ten Key" keypads are common, and fairly cheap.  I am sure their primary market is for accountants, but I purchased one to accompany my small laptop keyboard, some years ago.

Targus keypad model

I connected the keypad to the Raspberry Pi, and immediately noticed the first roadblock.  The keypad sends key presses to the system console, not to the SSH session I use to manage the Pi.  As this Pi will be headless, I needed to find a way to capture input from the keypad.

Fortunately for me, there is already a Python project called "evdev" that:
"provides bindings to the generic input event interface in Linux. The evdev interface serves the purpose of passing events generated in the kernel directly to userspace through character devices that are typically located in /dev/input/"
Score!

This solution would work equally well with a keypad or a full-sized keyboard.  The only difficult problem was determining which /dev/input/ device to use.  This particular keypad appeared as "/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd".  Your's may appear differently.

Here is the first bit of code I used to test the keypad, which worked quite well:
#!/usr/bin/env python

import string
import os
import sys
import time

# pip install evdev
from evdev import InputDevice
from select import select

# look for a /dev/input/by-id/usb...kbd or something similar
DEVICE = "/dev/input/by-id/usb-ORTEK_USB_Keyboard_Hub-event-kbd"

dev = InputDevice(DEVICE)

while True:

    # wait for keypad command
    r, w, x = select([dev], [], [])

    # read keypad        
    for event in dev.read():
        if event.type==1 and event.value==1:
            if event.code in keys:
                print "KEY CODE: " + event.code
                # do something with this key press
                # ...

In the final lala-pi keypad code, I included code to demonize the process, key-code to key-name mappings, syslog for logging, and ZeroMQ messaging.  If you are interested in the full lala-pi source code (still a work in progress), I setup a GitHub lala-pi repo.
# git clone https://github.com/oeey/lala-pi.git

For reference, this is the keycode to key name mapping I use:
# keymapping determined by trial and error
keys = {
 79: "1",
 80: "2",
 81: "3",
 75: "4",
 76: "5",
 77: "6",
 71: "7",
 72: "8",
 73: "9",
 82: "0",
 83: ".",
 28: "ENTER",
 78: "+",
 74: "-",
 14: "BS",
 55: "*",
 98: "/",
 # Numlock keys:
 111: "N.",
 110: "N0",
 107: "N1",
 108: "N2",
 109: "N3",
 105: "N4",
 # notice the missing N5
 106: "N6",
 102: "N7",
 103: "N8",
 104: "N9",
}

More to come...   see label: lala-pi

4 comments:

Felipe Bueno said...

Hi, Kenneth.

Your post saved me a lot of work.

Thank you :)

Felipe

Kenneth Burgener said...

Felipe, I am glad you found it useful. :-)

snoopydog12 said...

Wonderful! Pain relieved! Thanks so much for posting this.

Stephen Harris said...

Thank you! This saved me a lot of time :D