Arduinoと2台の音ゲー用コントローラを用いた速記用キーボードの制作

こんにちは、不定期にArduinoおじさん1と化すWatsonです。最近は頻度不十分ながらバンカラ街に通っています。

前の記事で、音ゲー用コントローラ2台を使ってステノワードという速記用キーボードの入力をエミュレートすることを試みました。 keionkakimasen.hatenadiary.com しかし、この記事のスキームではPC側のキーボード配列を弄る必要があったことから、通常のキーボードとの両立ができなくなっていました。 この両立ができれば、文字入力のQoLが向上するとともに速記練習のハードルが下がると期待できます。 そこで、ステノワードのエミュレートをPCに接続したマイコンだけで完結させるという目標を立てて、Arduinoのスケッチを作りました。

ゲームパッドから文字入力への変換の流れは次の通りです。

データフロー図概略

  1. USBゲームパッドがハブ経由でUSB信号を送信
  2. ArduinoのUSBシールドでUSB信号を受け取る
  3. ArduinoでUSB信号を解析、各ボタン・スティックの入力を監視
  4. Arduinoで速記マシンのコードに変換
  5. 速記マシンのコードをシリアル通信でPCに送信
  6. PCソフト"Plover"で速記マシンのコードを対応する文字列に変換
  7. 対応する文字列を出力

(各要素内部の処理については不勉強ですので、指摘を歓迎しています)

コントローラの入力の受信・解析

USB Host Shieldというモジュールを使います。 このモジュールでゲームパッドの入力を解析するプログラムのライブラリが公開されているので、このライブラリを音ゲーコントローラー用、複数台用に改変してUSBゲームパッドの入力から各ボタン・スティックの状態を取り出します。

USBハブ(画像)にコントローラーのUSB端子を全て挿し込み2、シールドに接続します 。

USBハブ。画像のメス側にコントローラーの端子を、画像外のオス側をArduinoのUSB Host Shieldに接続する。
まずは、各ボタン・スティックの状態をArduinoの出力ピンに対応させました(画像)。
USB信号を解析。各ピンの出力がブレッドボード上のLEDの点灯に対応し、ゲームパッドの各ボタンの入力を表す。

各ボタン・スティックの状態を速記マシンの入力に変換

今回はPCへの出力では速記マシン(TX Bolt)の出力信号をエミュレートします。 このスキームで速記用デバイスと通常のキーボードが両立できるのは、速記マシンの信号に使われる各キーが通常のキーボードのキーとは異なる即ち通常のキーボードと干渉しないことによります。

直接文字列に変換しないのは、速記用配列の変換テーブルが膨大で、Arduinoフラッシュメモリに載り切らないからです。 MEGA 2560やDueといった大容量モデルではその限りでないですが、MEGAはキーボード入力のエミュレート、Dueは動作電圧の変換に課題が発生するため、今プロジェクトでは導入を見送りました。

5月13日追記

今月中にArduino UNOの新モデル「R4」が発売されるようです。 blog.arduino.cc 記憶容量がMEGA 2560 R3/Dueなみに大きなもの(SRAM32kB,フラッシュ256kB)になるなど各性能が向上しており期待が持てそうです。

Ploverで速記マシンのコードを対応する文字列に変換

速記マシンの信号から対応する文字列出力への変換には、速記用オープンソースソフトウェアPloverを用います。

Ploverにはステノワード用の配列が公開されています。 しかし、公式のライブラリに含まれないため、導入にひと手間必要です。 また、ソースコードにバグがあり、 キー対応表の読込時にエラーが生じる、(特別な操作をしないと)分かち書きが強制される、一部のワードが入力できない、などの問題が発生します。 そこで、これらも書き換えました

こうして、少し想定外の事態も発生しましたが、ゲームパッドの入力から一連の文字入力までの変換ができました。 一連のコードをGitHubに上げておきます。

手元画像。Arduinoとランプは画像左に設置。
パソコン画面。Ploverで受信したキーストロークを文字列に変換できている様子が確認できる。

装置の小型化

上でArduino MEGA 2560を使用したのは単に入出力ピンが多いことのみが理由であり、スケッチ自体は標準のArduinoフラッシュメモリにも載り切るサイズです。 そこで装置の小型化のため、各コントローラのモニタリング表示をディスプレイモジュール(今回はOLEDモジュール)で代替することでピン数を節約し、このUSB変換プログラムを標準のArduinoに移植します。 今回、標準のArduinoとしては、Arduino UNOではディスプレイモジュールを直接挿せる場所がないので、美観のためマイコンArduino Leonardoを使用します3。そして、ディスプレイモジュールを1--7番ピンに直接挿します。

完成

モニタリング表示をディスプレイモジュールに移植しました(写真)。

本体の写真。

こちらも、ソースコードGitHubに上げております。

入力例

(動画)

展望

今回の実装で見送ったこととして、キーボード出力までマイコンのみで完結させることが挙げられます。上にも書いた通りこれには新たな手間を要し、それに加え今回の「通常のキーボードと速記用キーボードの両立」という目標は現状でも充分に達成できているので、この対応は余裕のあるときに行いたいと思います。

P.S.

手元撮影のノウハウや機材の準備が足りなかったため、この記事の画像を作るのにスマホカメラをコントローラーの上に立てて撮影していました。それゆえに見づらい画角も少なからずあったと思われます。今後は適切な機材の使用、例えば三脚に固定しての撮影を検討しています。

今回の記事は通常のキーボードで書きました。さすがに数日の練習で文字入力を代替するのは無理よ

使用画像


  1. マイコンブランド"Arduino"の名の由来のバー"Bar di Re Arduino"の名の由来となったイタリア王アルドゥイーノ(在位1002--1014年)とは特に関係ない。
  2. 今回使用しているゲームパッドは電力供給のためにUSB端子を2口ずつ必要としている。そのため、このUSBハブは電力不足対策にセルフパワーモードで動作させている。
  3. UNOで0,1番ピンがPCとのシリアル通信に使用されるのに対し、Leonardoではこのシリアル通信をチップ内でバーチャルに行っている。このためLeonardoは0,1番ピンを自由に利用できる。