Open13

KMK Firmware(CircuitPython) でinternational キーコードが送られない件について

Raspberry Pi Pico に改造キーボードのマトリックスを接続して、一通りのキー入力は確認できたのですが、一部のキーが認識されません。
正確には、KMK Firmware 側では正常にキーコードを送っているようなのですが、Mac側には届いていないようです。
karabiner-element の EventViewer で見ると、当該キーだけ down/up のイベントが来ていないもよう。
確認したのはJP配列の以下のキーです。ほかにもあるでしょうが、割り振ったキーだけです。
キーコードはこのページの情報を参考にしました。

http://www2d.biglobe.ne.jp/~msyk/keyboard/layout/usbkeycode.html
  • ¥ | キー
  • International3 キーコード 0x89(137)
  • _ キー
    • International1 キーコード 0x87(135)
  • 無変換
    • International5 キーコード 0x8B(139)
  • 変換
    • International4 キーコード 0x8A(138)

ほかにもあるだろけど、まずはこれを解決したい。

まずは問題切り分けで Mac 側の確認をします。

USBの抜き差しや、設定のキーボードでレイアウトの変更

レイアウトの認識をさせようとすると、右Shitfキーのすぐ左のキーが押しても反応がないのでやむなく?キーを押すと、ANSIキーボードと判定される。JIS配列を選択し直しても、INT1, INT3 などは反応なし。

karabiner-element の EventViewer で見ると、そのキーを押したときだけイベントが飛んでこない。

Mac 側での問題ではなさそうです。

次は、KMK Firmware でのキーレイアウトの確認です。

  • キーに別のキーコードを割り当てる
    • KC.INT3KC.A に変更
      • 正しく a が入力される
  • ほかのキーに KC.INT3 を割り当ててみる
    • 入力されず、イベントも飛ばない

KMK Firmware のドキュメントを確認

https://github.com/KMKfw/kmk_firmware/blob/master/docs/international.md

シンプルなことしか書いていない

International extension adds keys for non US layouts. It can simply be added to the extensions list.

from kmk.extensions.international import International
keyboard.extensions.append(International())

一応ほかのLayoutやLEDモジュールをコメントアウトして、上記の通りのコードにしてみる。
変化なし

keyboard.debug_enabled = True

を追加して、ログを表示させてみる。

>>> 
soft reboot

Auto-reload is on. Simply save files over USB to run them or enter REPL to disable.
main.py output:
KMKInit(release=copied-from-git)
KMKKeyboard(debug_enabled=True diode_orientation=1 matrix_scanner=<class 'MatrixScanner'> unicode_mode=0 tap_time=300 _hid_helper=USBHID(REPORT_BYTES=9) keys_pressed=set() coordkeys_pressed={} hid_pending=False active_layers=[0] timeouts={} tapping=False tap_dance_counts={} tap_side_effects={})
MatrixChange(col=7 row=7 pressed=1)
KeyResolution(key=Key(code=135, has_modifiers=None))
KMKKeyboard(debug_enabled=True diode_orientation=1 matrix_scanner=<class 'MatrixScanner'> unicode_mode=0 tap_time=300 _hid_helper=USBHID(REPORT_BYTES=9) keys_pressed={Key(code=135, has_modifiers=None)} coordkeys_pressed={1799: Key(code=135, has_modifiers=None)} hid_pending=False active_layers=[0] timeouts={} tapping=False tap_dance_counts={} tap_side_effects={})
MatrixChange(col=7 row=7 pressed=0)
KeyResolution(key=Key(code=135, has_modifiers=None))
KMKKeyboard(debug_enabled=True diode_orientation=1 matrix_scanner=<class 'MatrixScanner'> unicode_mode=0 tap_time=300 _hid_helper=USBHID(REPORT_BYTES=9) keys_pressed=set() coordkeys_pressed={1799: None} hid_pending=False active_layers=[0] timeouts={} tapping=False tap_dance_counts={} tap_side_effects={})

確かにキーコード 135 の UP/DOWN イベントを送ってはいるようだ。どこで消えているのだろう。

考えられるのは、

  • KMK Firmware の深いところでマスクされている
  • CircuitPython が送れていない
  • やっぱりMac側に問題がある

かなあ。

キーコードが0x80以上のがダメなのか?

日本語入力の切替ができないのはストレスなので、それぞれ適当なキーコードに割り振り直して、karabiner-element で 英数 かな キーに変換するようにした。私は現在は変換・無変換キーで日本語変換のオンオフをする派です。

さて、0x80(128)以上のキーコード送信に問題があるのかもという仮定を検証するために、簡単なコード送信のプログラムを実行してみる。

code.py
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode
import time

kbd = Keyboard(usb_hid.devices)

for keyCode in range(0x00, 0x10):
    kbd.press(keyCode)
    time.sleep(.05)
    kbd.release(keyCode)
    time.sleep(.05)

これで、結果がでる

type:down            HID usage:0x07,0x04  name:{"key_code":"a"}                                        misc:
type:down            HID usage:0x07,0x05  name:{"key_code":"b"}                                        misc:
type:down            HID usage:0x07,0x06  name:{"key_code":"c"}                                        misc:
type:down            HID usage:0x07,0x07  name:{"key_code":"d"}                                        misc:
type:down            HID usage:0x07,0x08  name:{"key_code":"e"}                                        misc:
type:down            HID usage:0x07,0x09  name:{"key_code":"f"}                                        misc:
type:down            HID usage:0x07,0x0a  name:{"key_code":"g"}                                        misc:
type:down            HID usage:0x07,0x0b  name:{"key_code":"h"}                                        misc:
type:down            HID usage:0x07,0x0c  name:{"key_code":"i"}                                        misc:
type:down            HID usage:0x07,0x0d  name:{"key_code":"j"}                                        misc:
type:down            HID usage:0x07,0x0e  name:{"key_code":"k"}                                        misc:
type:down            HID usage:0x07,0x0f  name:{"key_code":"l"}                                        misc:

0x00〜0x0f で実際に振られているのは 0x04:a 〜 0x0e:k なので、きちんと送信されている。
upイベントは省略しました。
同じように範囲を変えて調べた結果、0x01〜0x7f の範囲は正常送信されました。一方、0x80〜0xff の範囲では、以下の 0xe0〜0xe7 の修飾キーのイベントだけが確認できました。

type:down            HID usage:0x07,0xe0  name:{"key_code":"left_control"}                             misc:flags left_control
type:down            HID usage:0x07,0xe1  name:{"key_code":"left_shift"}                               misc:flags left_shift
type:down            HID usage:0x07,0xe2  name:{"key_code":"left_option"}                              misc:flags left_option
type:down            HID usage:0x07,0xe3  name:{"key_code":"left_command"}                             misc:flags left_command
type:down            HID usage:0x07,0xe4  name:{"key_code":"right_control"}                            misc:flags right_control
type:down            HID usage:0x07,0xe5  name:{"key_code":"right_shift"}                              misc:flags right_shift
type:down            HID usage:0x07,0xe6  name:{"key_code":"right_option"}                             misc:flags right_option
type:down            HID usage:0x07,0xe7  name:{"key_code":"right_command"}                            misc:flags right_command

これはCircuitPythonで直接送信した結果なので、やはりCircuitPythonでマスクされているのかな。

CircuitPython のソースを調べてみることにします。

Windows PC につないだらちゃんとキーコード送信されているようでした。ではMac側の問題か。振り出しに戻る

今のところ

  • Mac mini 2020 BigSur ×
  • MacbookPro 2020 BigSur ×
  • Window10 21H1 ◯

Macだとうまくいかないっぽいので、Github の Adafruit_CircuitPython_HID に issue だしてみた。

ログインするとコメントできます