CH9328とは
UARTを入力として受け取り USB HIDキーボードとして振舞うICのようです。
本来の用途としてはKVMスイッチなどでキーボードのエミュレーションを行うための物のようです。
今回はこのCH9328を搭載したモジュールボードを購入したので少し試食してみました。
自作キーボードとUSBデバイス
USB接続式の自作キーボードを設計するときに悩みの種となるのがUSBです。
まずUSBデバイス機能を搭載したマイコン、またはV-USBなどのソフトウェアエミュレーションに対応しているマイコンを用意する必要があります。
USBのプログラミングは煩雑で、メモリやCPUを結構消費します。
そして次の問題がVID/PIDです。作成したキーボードを個人で使う場合はそこまで問題となりませんが、販売するとなると正式には独自のVIP/PIDを取得しそれを利用するのが通常の流れです。
しかし、正規の方法でVIP/PIDを手に入れるためにはUSB-IFに申請し、結構多くのお金を納める必要があります。
同人ハードウェアなどの場合そこまでコストはかけられない、という事で、いくつかのベンダーがPIDのサブライセンスを行っているので、その仕組みに乗っかるなどしてPIDを取得している人もいるようです。
このあたりの事情は以下の記事が詳しいです。
CH9328とUSBのVID/PID
さて、今回扱うCH9328ですが、これはWCH社が販売しているICで、このICにはWHC社のVIDである0x1A86と、このIC固有の値であるPID 0xE026がデフォルト値として設定されています。 (この値は書き換えツールで変更できるようです)
この値をそのまま使う場合はWCH社のVID/PIDをそのまま使うことが出来ます(多分ライセンスとしてもこれでもないないはず、、USB Serial ICなどとやっていることは同じ)
Arduinoから使ってみる
ArduinoにはまさにCH9328を利用するためのライブラリである「CH9328-Keyboard」があります。
インストール出来たらHelloWorldのサンプルプログラムをArduino UNOに書き込んでさっそく実行してみます。
Arduino UNOで利用する際の罠
CH9328-Keyboardの内部で SERIAL_TX_ONLY という定数を使っていますが、どうもこれはESP8266などでのみ利用できる定数のようでArduino UNOではこのせいでコンパイルが実行できません。
インスール下ライブラリのCH9328Keyboard.cppの該当部分を削ることでコンパイルできるようになりました。
変更前 _Serial->begin(baud, SERIAL_8N1, SERIAL_TX_ONLY); 変更後 _Serial->begin(baud, SERIAL_8N1);
サンプルプログラムの実行
CH9328モジュールとArduino UNOはVCC,GND, TX, RXをそれぞれ接続します。
また動作モードを変更するジャンパのIO1,IO2をHIGHに設定します(このモジュールではジャンパをつけるとHIGHになるようです)
電力はCH9328モジュールからArduino UNOに送るのでArduino UNOはUSB接続する必要はありません。
Win+r押下の後 notepad + Enter を押下、その後Helloの文言が打ち込まれるというキーストロークのシミュレーションが行われ下記画像のようにメモ帳にメッセージが表示されました。
オリジナルキーボードの作成
ここまでくれば後は簡単です。
3キー搭載のマクロパッドを作ってみます。
自分のIDにちなんで「i」「n」「a」の3キーの存在するキーボードという事にします。
全く洗練されていませんがソースコードです。
#include <CH9328Keyboard.h> #define PINRST 10 #define BAUDRATE 9600 //Default is 9600. void setup() { Keyboard.begin(&Serial, PINRST, BAUDRATE); delay(1000); Keyboard.releaseAll(); pinMode(10, INPUT_PULLUP); pinMode(11, INPUT_PULLUP); pinMode(12, INPUT_PULLUP); } unsigned int trigger_b1 = 0; unsigned int trigger_b2 = 0; unsigned int trigger_b3 = 0; void loop() { int b1 = !digitalRead(10); int b2 = !digitalRead(11); int b3 = !digitalRead(12); if(b1){ if(trigger_b1){ Keyboard.press('i'); } trigger_b1 ++; }else{ Keyboard.release('i'); trigger_b1 = 0; } if(b2){ if(trigger_b2){ Keyboard.press('n'); } trigger_b2 ++; }else{ Keyboard.release('n'); trigger_b2 = 0; } if(b3){ if(trigger_b3){ Keyboard.press('a'); } trigger_b3 ++; }else{ Keyboard.release('a'); trigger_b3 = 0; } }
配線は Arduino UNOの10, 11, 12番ピンをタクトスイッチの片方にそれぞれ繋ぎ、タクトスイッチのもう片方はGNDに接続するだけです。
全体像はこんな感じです。
CH9328についてもう少し・・
値段やデータシートはLCSCが参考になります。
モジュールは600円程しましたが、IC単品だと$1.5程度で買えそうです。AliExpressだともっと安いものも見つかると思います。 データシートは中国語の物しか見つかりませんでした。
しかし基本動作はシリアルから来たコードをHIDキーボードのコードに変換するだけなので、中国語が読めなくてもそこまで困ることはなさそうです。加えてCH9328-Keyboardライブラリがあるので、そもそも仕様を意識する必要もあまりありません。
AliExpressでCH9328で調べると様々なモジュールが販売されています。
私が今回利用したのは以下ですが、ほかにも様々なモジュールが存在します。
よく似た型番の別のICや、ジャンパの設定が出来ないもの、水晶発振子が搭載されたもの、など様々な変種が存在するので、目的に応じて適切なものを購入してください。
(同じCH9328でも内部バージョンの違うものがあるようで、古いものは水晶発振子が外付けで必要のようです)
まとめ
CH9328を使うとUSB HID周りの煩わしい問題をすべて肩代わりしてくれるので、非常に簡単にUSBキーボードを自作できることがわかりました。
CH9328と低機能・低価格のマイコンを組み合わせる事で、部品は増えてしまいますが、多機能マイコン1つで作るよりも、安く、わかりやすい自作キーボードを設計することが出来ます。
チップの値段も安いので、新たな自作キーボードの材料として検討してみてはいかがでしょう?
最後に動作の様子の動画を貼っておきます。
これなーんだ? pic.twitter.com/sb27yW4loj
— ina_ani@1歳11ヶ月児のパパ (@ina_ani) 2022年4月5日