10
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ラズパイにつないだテンキーボードをタクトスイッチ代わりにpythonで使えるようにする(メモ)

Last updated at Posted at 2018-09-29

#USBテンキーボード
リモートコンソールで実行したpythonプログラムと、ラズパイに物理接続したUSBテンキーボードを連携させて、テンキーを押すとラズパイでプログラムが実行される実験のメモ。

キー入力はpythonで**input()**を使えばできるが、実行しているコンソールの入力を受け付けるので、物理的に接続しているキーデバイスからの入力はできない。

タクトスイッチのように、物理接続のキーボード入力を解釈してなにがしかのコマンドを実行するプログラムを作りたかったので、それを可能にするpythonライブラリevdevを使って、実験したメモ。

#evdev

冒頭にある記述の通りの機能を持つ。

This package 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/.

This package also comes with bindings to uinput, the userspace input subsystem. Uinput allows userspace programs to create and handle input devices that can inject events directly into the input subsystem.

#USBテンキーボード

特にこれというものではなく、値段とメーカーから以下を購入した。使用する機種により、pythonプラグラムでUSBデバイス名は変わるし、キーマップも変わる可能性がある。

エレコム テンキーボード TK-TCM011BK

#デバイスの確認

入力デバイスは**/dev/input/by-id/**をlistすれば分かる。

ls /dev/input/by-id/

表示されたusb-SINO_WEALTH_ELECOM_10KEYBOARD-event-kbdを、pythonプログラム内で指定する。

usb-SINO_WEALTH_ELECOM_10KEYBOARD-event-kbd

#pythonプラグラム

##参考文献

以下の情報を参考にして、プログラムを作成した。というか、ほぼパクりました。。。

##ライブラリ

以下のライブラリをラズパイにインストールした。python2.7の場合はpip3ではなくpipを使う。

pip3 install evdev

##プログラム1

参考文献をほぼパクり、ENTERキーでプログラムを終了するようにした。キーマップは修正している。

キーマップはkeymap.pyに記載しておく。

keymap.py
# 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: ".",
 96: "ENTER",
 78: "+",
 74: "-",
 14: "BS",
 15: "TAB",
 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",
}

keymap.pyをインポートして、プログラム本体を記述する。

kbtest.py
#coding: utf-8
from evdev import InputDevice
from select import select

from keymap import keys

# look for a /dev/input/by-id/usb...kbd or something similar
DEVICE = "/dev/input/by-id/usb-SINO_WEALTH_ELECOM_10KEYBOARD-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     : ", keys[event.code])
                    #print("KEY CODE: ", event.code)

                    # do something with this key press
                    # ...
                    if(event.code == 96): #"ENTER"
                        print("終了します")
                        exit()
                    else:
                        pass

            

##プログラム2

openjtalkがインストールされ、ラズパイにスピーカを接続している前提。押したキーをラズパイが読み上げる。ENTERで終了する。

kbtalk.py
#coding: utf-8
from evdev import InputDevice
from select import select

import subprocess

def jtalk(t):
    open_jtalk=['open_jtalk']
    mech=['-x','/var/lib/mecab/dic/open-jtalk/naist-jdic']
    htsvoice=['-m','/usr/share/hts-voice/mei/mei_normal.htsvoice']
    speed=['-r','1.0']
    outwav=['-ow','open_jtalk.wav']
    cmd=open_jtalk+mech+htsvoice+speed+outwav
    c = subprocess.Popen(cmd,stdin=subprocess.PIPE)
    c.stdin.write(t)
    c.stdin.close()
    c.wait()
    aplay = ['aplay','-q','open_jtalk.wav']
    wr = subprocess.Popen(aplay)

from keymap import keys

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

dev = InputDevice(DEVICE)

if __name__ == '__main__':

    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     : ", keys[event.code])
                    #print("KEY CODE: ", event.code)

                    text = str(keys[event.code])
                    jtalk(text.encode('utf-8'))

                    # do something with this key press
                    # ...
                    if(event.code == 96): #"ENTER"
                        text = "終了します"
                        jtalk(text.encode('utf-8'))
                        exit()
                    else:
                        pass

event.code別にプログラムを準備することで、物理接続のテンキーボードをタクトスイッチ代わりに使えるようになる。

10
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
10
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?