ベアメタルRaspberry Piでの日本語USBキーボードからのキー入力


Raspberry Pi用MicroPythonではUSBキーボードをサポートしていますが、実はこれまでは英語キーボードしかサポートしていませんでした。
私自身は、普段US配列のキーボードしか使わないので困らないのですが、日本国内ではJIS配列のキーボードを使われている方が多数派だと思います。

そこで、MicroPythonの前にまずは日本語配列のキーボードから文字(もちろん半角のみですが)を入力するベアメタルのコードを書いてみました。今回のコードは以下に置いてあります。

bare_matal_rpi_zero/usb_kbd_jp at master · boochow/bare_matal_rpi_zero

USBキーボードのドライバから受け取るキー入力の情報は、キー配列の種類に関係なくキー固有のコードです。
例えば、「2」のキーを押したときに得られるコードは、US配列でもJIS配列でも31です。
(シフトキーやコントロールキーなどのモディファイヤ情報は別に取得できます。)

「SHIFT+2」を押したとき、英語キーボードでは「@」、日本語キーボードでは「”」を入力したことになりますが、キーのコードはどちらもSHIFTと31なので、これをどの文字に変換するかはソフトウェアの責任になります。

この対応表は英語のキーボードだと沢山出回っています(たとえば下記)。

Keyboard scancodes: USB

日本語のキーボードについては、以下がよくまとまっています。

OADG109スキャンコード

USBキーボードのキーコード

英語と日本語の差分は以下にまとまっているようです。

Keyboard scancodes: Japanese keyboards

実際に実装してみると、以下のことが分かります。

・英語キーボードでは、スキャンコードは0~103までの範囲に納まっている(特殊キーを除く)。
・日本語キーボードでは、135(右SHIFTの隣、「\」および「_」)、137(Backspaceの隣、「¥」および「|」)という、英語キーボードでは使われないコードが使われている。(ちなみに136は「ひらがな/カタカナ」キー)
・104~134までの範囲のコードは使われておらず、135と137が飛び地のように使われている。

上のほうでリンクを紹介したKeyboard scancodes: USBを見ると、

・104~115:ファンクションキー(F13~F24)
・116~132:各種機能、マルチメディアなど
・133~134:テンキーパッドの「,」と「=」
・135~143:国際化対応
・144~152:多国語対応

みたいな割り当てになっています。
国際化対応のコードに日本語特有の「¥」や変換・無変換キーなどを割り当てた用に思われます。

実装は、基本的にキーボードから得たスキャンコードを上記に従って文字に変換するだけです。
ちょっと落とし穴だったのは、USBのライブラリ(csud)から得られるスキャンコードが、135(0x87)、137(0x89)ではなく0xff87、0xff89となっていたことです。
キーボードが返している値がそうなのか、ライブラリ内でsigned charからsigned shortに型変換しているのかは分かりませんが、いずれにせよ0xffでANDを取る必要がありました。

なお、手元に日本語配列のキーボードが無かったので、動作確認のため、最安クラスの製品を購入しました。

SKB-L1UBK【USBキーボード(ブラック)】標準日本語配列のスタンダードUSBキーボード。ブラック。 – サンワサプライ株式会社

電力の問題なのか、Raspberry Pi Zero Wに直結するとうまく動かないUSBキーボードもあるのですが、このキーボードに関しては問題なく動作しました。

コメント