GUST NOTCH? DIARY

Arduino Leonardo を Wii U のキーボードにする

  • 現状のまとめ
    • 標準の HID API ではなく、Arduino HID Project のライブラリにある BootKeyboard を使う
    • print, write メソッドではなく、press/release を使う。101レイアウトで Shift キーなどのモディファイアと組み合わせて実際にキーをたたくようにキーコードを送る
  • 課題
    • ボタンを押したらスケッチ中に埋め込んだ文字列を出力するようにしているが、数回ボタンを押すと入力ができなくなる。Arduinoをリセットすると復活する。



プチコンBIG が出て USB キーボードが使えるようになったので、キーボードに見えるデバイスを作ればデータを流し込むことができるだろう、ということで何が一番手っ取り早いかな?と考えて思いついたのが Arduino。Leonardo なら標準で HID デバイスになれる、というので、キーボードになった Arduino に横からシリアル通信でデータを流し込んでそのままキー出力してもらえばPCからのデータ送信ができるはず。PCのキーボード入力をそのまま渡すこともできるだろう、ということ目論見ました。
で、Leonardo を先日買ってきたわけです。サンプルコードを参考に、ボタンを押したら何か出るようにしてみたのですが……ダメでした。
買ってくる前に調べていた時点で、Leonardo は ATmega32u4 チップを使ったことによってシリアル通信専用のチップがいらなくなり、さらに HID デバイスとしてキーボードとマウスがサポートされた、というのは分かっていました。つまり一つのチップが全部やってるということになるので、これらを同時に使う場合は処理も遅くなる場合があるとのこと。期待するスピードを出せるかなぁ?という懸念もあったりしたのでダメで元々のつもりでした。
しかし、WindowsでもMacでも認識するのになんでかなぁ、と思っていたところに教えてもらったのがこちら。

なるほど、デバイスとしてはシリアルデバイス2つとHIDデバイス1つに見える、と。キーボードとマウスがその下にぶら下がってるわけですね。FreeBSDの反応やこのあたり仕様書をあたってみたところ、ポイントとなりそうな部分が見えてきました。

  1. 複数のUSBデバイスに見えるので、HIDが最初にないため
  2. HIDデバイスが複数ぶら下がっているため最初にキーボードとして見えない
  3. ブートインターフェースでないため

実はUNOでもシリアル通信を担っていた16U2のチップを書き換えればキーボードデバイスとして化けさせることができるらしいというのも調べていました。おそらくこちらなら最初の二つはクリアできるはず。そっちもトライしてみようかなぁ、と思って手元にあるUNOを調べたら初代のもの。こいつのファームアップデートには抵抗をつける必要があるのでした。家には半田ごてないし、ついでに10Kの抵抗もないし。
Arduino IDE のソースを見てみたら、HID.h と HID.cpp の中で HID インターフェースの下にキーボードとマウスのEndPointがあることになっていました。SubClassとプロトコルを指定しているところがあったので、ブートインターフェースにしてキーボードプロトコルだよ、というように書き換えてみたのですが、やはりそう簡単には問屋が卸さない。そりゃ、何かやり取りが発生するはずだしねぇ。
しょうがないので Leonardo でキーボード単機能になるようなものはないか?と思って調べていたところ見つけたのが最初に示したこちら。

なんとライブラリで提供されていて、標準ライブラリより高機能で、単体のHIDキーボードとマウスに分割できて、さらにブートプロトコルにも対応という、まさに至れり尽くせり。
早速試してみた結果、BootKeyboard を使ったらちゃんと認識されました!
しかし、print や write だと途中で出力が止まってしまったりする。なぜうまく動かないのかはわからないけど、まさにキーを叩くようにキーコードを送ってやれば期待した結果が得られるということが分かりました。
ただし、今のところ何度かボタンを押していると途中で入力できなくなるという状況。Arduinoのリセットボタンを押すとまた復活する。スケッチの書き方がまずいのか?キーボードとしてのお約束の振る舞いがあるのか?入力速度の問題ではない感じ。