いやぁ1月~3月までずっとスキーしてました。パソコンやマイコンなんてほっておいてました。カービングは奥が深いよ!みんな冬は外へ出ましょう!ほっときすぎたせいで、Mac Mini起動してないのに壊れるとか…どゆこと?。では、完全に忘れていた98とUSBマウス・キーボードの続きですw。

前までにUSB Host ShieldのセットアップとUSB HostLibrary 2.0のセットアップ・サンプルコードの動作まで終了しました。


カスタムレポートパーサー作成の準備

USBHIDBootKbdAndMouse.inoをベースにして改造していきます。キーボード、マウスのデータの処理は用意されたレポートパーサーというクラスで行っています。

キーボードはKeyboardReportParserというクラスを継承して作ったサブクラスにカスタムの処理を拡張して利用します。以前利用したライブラリにあったサンプルでは押されたキーをASCIIで表示したりシフトなどのキーの押す離すを表示したりする簡易なものとなっています。以下の部分です。

マウスレポートパーサーも同様にMouseReportParserを継承して作られています。MouseReportParserでマウスイベントを発生させ継承したサブクラス(MouseRptParser)で情報の表示を行っています。宣言と実装部は以下です

この2つのサブクラスがinoにあると、とても見にくいので.hファイルに別途記述していくようにします。僕はめんどいので.cppファイルを作らずに.hファイルに実装も記述していきます。


98用キーボードレポートパーサーの作成

とりあえず全コードをGithubに上げます。

ライブラリのサンプルでも使われているKeyboardReportParserクラスが使いやすく98のキー処理もこのクラスを継承して作っています。98特有の処理、不足している処理は継承して作ったサブクラス(KbdRptParser.hのKbdRptParser)に実装していきます

大まかに下の機能を追加しました。

  • USBキーボードから98キーボードへスキャンコード変換
  • 98本体とキーボードのコマンドやり取り
  • キーリピートの処理
  • CAPS,NumLock,カナのLED制御
  • PC-98の特殊起動(セットアップメニューなど)処理

全部説明すると大変なので、コードを見ていただくとおおむねわかると思うのですがkeyconst.hでスキャンコード変換テーブル、特殊起動時のコマンド定義などを行っています。

コマンドのやり取り、LEDの制御、キーリピート処理は常時監視処理が必要なためloopにてtask()を処理することで実現しています。おおむねPS/2キーボードの変換器を作るときと変わりはないのですが、PS/2のスキャンコードとUSBのそれは違いますし、キーリピートもキーボード側ではなく変換器で実現していますのでコードが修正してあります。

CAPS,NumLock,カナのLEDも変換器側でつけてあり制御しています。NumLockについては変換器側でテンキー部のキーコードを変換しています。LEDは抵抗(10kΩ程度)をかませて定義されているのピンで接続しています。


PC-98の特殊起動の実現

セットアップメニューなどの特殊モードでの起動は、以前PS2キーボード変換器制作時に解説した通り、起動直後でコマンドを送らないとなりません。ESP32ではUSB Host Shieldの初期化をしキーボードを認識するまでには時間がかかりすぎてUSBキーボードからは起動することができないため、変換器にボタンを設置してそれを押して起動することで実現しています。

上の定義はkeyconst.hの抜粋ですが6つの起動モードを定義してあります。右辺値が起動時に必要なコマンドとなります。6つのボタンを変換機に組み込みますが、ピン数節約のためボタンアレイ(分圧回路)を接続し1pinのみで制御しています。ESP32販売元のEspressifの以下の資料を参考にしています。

(抜粋)


98用マウスレポートパーサーの作成

マウスレポートパーサーはスクロール機能やボタンを多く持つマウス、複合デバイスでの特殊なマウスなど色々なパターンがあり、ライブラリ標準のMouseReportParserだと、機能不足な面もありましたので、色々なHIDデバイスのレポートパーサーの継承元であるHIDReportParserを継承して98用に作ってみました。

Pc98MouseReportParserがそれにあたります。マウス毎にデータ処理が必要になってくるので実際にはPc98MouseReportParserを継承したサブクラス(サンプルではBskBw120aMParserに当たります)を作り、それを使っていきます。
話は少しそれますが、別な特殊マウスを使いたいなど、Pc98MouseReportParserを継承して実際にサブクラスを作る場合、実際のデータを目で確かめなければならないと思います。その場合はPc98MouseReportParserの22行目付近のOUTPUT_MOUSE_DATA=trueにすれば、シリアルにデータが表示されますので、それをもとにデータを解析します。
また、ホイール部のスクロール情報など特殊な情報をデータとして受け取りたい場合はパーサーがセットされるデバイスのHIDBootでREPORTER PROTOCOLを有効にする必要があります。

HidComposite(&Usb,false);をHidComposite(&Usb,true);にしてあげればいいのですが、このサンプルでtrueに変えると受け取るデータの構造が変わりますのBskBw120aMParserでは処理できませんのでマウスは当然動かなくなります。OUTPUT_MOUSE_DATA=trueにすれば生データを見れますので、スクロール情報も見てみたい方はどうぞ…。

話を戻します。Pc98MouseReportParserは

  • USBマウスデータから98マウスデータへの変換・送信

これのみを担当しています。スクロールアップ、ダウンなどの定義の作りこみがまだ甘い(実装できるかな?)ですが、カーソルやボタンの押し離しは問題なくできます。

ライブラリ標準のMouseReportParserではデータをMOUSEINFO構造体にキャストして使っていますが、このクラスのMOUSEINFO_EX構造体は、あくまで箱として利用してParseMouseDataのオーバーロード関数で参照渡しされた引数MOUSEINFO_EX &pmiにセットしていく形としています。

そのうち他のマウスのサンプルも少し上げていきたいと思います。


その他の説明

inoファイルは基本的にloop()でUsb.Task();を処理します。KbdPrs.Task();は98側とキーボードデータのやり取りを常時行っています。最初はloop()で両方の処理を実施していたのですが、Usb.Task()が重い処理(特に初期化時)で回らなくなってキーボードのデータ処理が追い付いていないことが判明しました。というわけでESP32のデュアルコアを生かし、Core0(通常Wifiで利用)にてキーボードデータ処理をマルチタスクで実装しています。


ESP32との接続

ピンアサインはコード中に書いていますが

となっています。MiniDin側(98と接続する側、RST,RDY,RXD,RTY,XA,XB,YA,YB,LB,RB)はロジック電圧が5vですので、ロジック変換機をかませて3.3vにしてESP32と接続してください。直結すると破損しますよ?コネクタのピンアサインはPS/2変換器の時の記事を参考にしてください。

ボタンアレイは適当なボタンと抵抗を用意して上のボタンアレイ回路図どおりに接続してください。ボタンを押してみて正常に分岐されるのを確認してください。

LEDは10kΩ程度の抵抗を挟んで各々のpinに接続します。

USBホストアダプタは前記事の接続と一緒です

ESP32の開発ボードには5v->3.3vのレギュレータが載ってますのでESP32には5vを供給してOKですが、開発ボードでないESP32を使う場合は別途レギュレータや書き込み回路が必要となりますので、そちらは別サイトで確認してください。

結線が大変ですが、難しくはありませんので時間をかけて確認しながら進めます。読んでる人なら不要と思いますが、いずれ回路図(といってもただの結線図)を作る気持ちはありますw

全面にはCAPS,NumLock,カナのLEDをつけて、上には各種起動モードを割り当てたボタンを配置しています。USBには無線のドングルをさしてあります。書き足りないこともありますが、いつまでたっても記事化できないので・・・気づいたら追記します。

最後と言いましたが、Bluetooth(BLE)キーボード、マウスもやってみました。USBシールドを使わない分簡単で安くできます

投稿者 まる

Twitter : @dinagon Instagram : @d_dinagon フォロバします!!最近、ESP/Arduinoいじりすぎでアプリ開発が進んでない。歯医者なのに歯のことはあまり触れませんw

Amazon プライム対象