IMEの日本語入力の状態がオンなのかオフなのかわからなくなり、日本語入力したいのに英字になったり、英字入力したいのに日本語になったりして困ってたので、ATOM Matrixと組み合わせてLEDをゲーミングPCのように光らせるやつを作ってみました。
プログラムは GitHub のページからどうぞ。
ここでは使い方の説明やカスタマイズについて書いていきます。
実はこんな製品が市販されている
iIME-USBという製品がAmazonで販売されています。買った方が早い!って人はこうゆう製品を買ってみるのもいいと思います。私が今回作るきっかけになったのも、この製品のニュースを見たからです。
すでに先人が通った道だった
IMEがオンになったら光るやつ、を調べてみると、すでに何人もの人が同じようなものを作っていました。そうそう、みんな困ってるんだよ、IME。シャポコさんのImeTo232Cは最初のバージョンで使用したものでした。Ime2232CはシリアルポートのDTS, RTS信号を出力する仕様なのですが、これはM5Stack製品とは相性が悪く、書き込みモードになってしまったりリセットしてしまうことがありました。そこで今回はPC側のソフトも新しく作ることにした次第です。
システム構成
Windows上でIMEの状態を監視してシリアルポートに出力するプログラムと、シリアルポートからデータを受け取ってLEDを光らせる親機、親機からデータを受信してLEDを光らせる子機の3つで構成されています。
Windows側
シャポコさんのプログラムはC++で書かれていましたが、Windowsの開発環境がなかったので、今回は新たにPythonで作成することにしました。pyinstallerを使ってPythonのプログラムを実行形式のexeファイルにしています。
仕組みとしては、IMEがオンになったらJA+(CR)+(LF)を送信しているだけです。IMEがオフならEN、終了時はLEDを消すためにSLを送信しています。これだけの単純なプログラムです。
M5Stack親機側
親機はUSBポートに直接させる、AtomS3Uを使いました。子機を使わなくても親機だけでも使用できます。親機のPort AにRGB LEDテープライトを接続することも可能です。親機ではシリアルポートからデータが送られてくるのを待機していて、データが来たらその内容に従ってLEDを光らせます。
RGB LEDの点灯にはFastLEDライブラリを使用しました。正直あまり使い方を理解できてませんが、とても簡単に虹色に光らせることができました。
uint8_t hue = beat8(GAMING_SPEED, 255);
fill_rainbow(ledsIn, INLED_NUM, hue, DELTA_HUE);
FastLED.show();
たったこれだけでゲーミングPCです。すごい!
そしてもう一つ特徴的な機能が、ESPNOWによるデータ通信です。ESPNOWというのはEspressifが開発した通信方式で、機器同士が直接通信を行います。Wi-Fiでデータを送信するのにアクセスポイントを経由しないので、面倒なSSIDの設定なども不要です。ブロードキャストアドレスに送信して受信することもできますが、今回は子機のMACアドレスを指定して送信する方式をとりました。子機のMACアドレスを調べるのは面倒ですが、家中のLANデバイスに無意味なパケットを処理させるのもあれなので。
M5Stack子機側
子機はシリアルポートの代わりにESPNOWからデータを受信します。プログラムはほとんどが親機と子機で共通になっているので、コンパイル時に IS_MASTER をtrueにするかfalseにするかだけです。
Windows側アプリの使い方
当初ビルド済みのexeファイルを配布する予定でしたが、VirusTotalでチェックしたらいくつかマルウェアが検出されました。おそらく同じpyinstallerを使ったマルウェアのせいで巻き添えを食らってるだけだと思いますが、よくわからずにウイルスが入ってるって騒ぎだす人がいそうなので公開はやめます。いろいろとライブラリのインストールが必要で大変だと思いますが、がんばってビルドしてみてください。
ime2serialwrite.exe は実行するとすぐにタスクトレイの中で最小化しています。右クリックするとメニューが表示されますが、基本的にあまり使うことはないと思います。
【接続】
シリアルポートに接続します。意図的に切断したときや、起動時に接続失敗したときなどに使います。
【切断】
シリアルポートから切断します。Arduino IDEの方で一時的に接続したい場合などに使います。
【スタートアップ】
スタートアップフォルダが開きます。ここにショートカットを作成しておくと、Windowsの起動時に自動起動するようになります。やめる場合は削除するだけです。
【終了】
プログラムを終了します。正確には、LEDをオフにする命令を出してから終了します。
M5Stack親機/子機の使い方
ボタンを短押しすると明るさが変更できます。明るすぎる場合とかはボタンを押せば調整できます。
ボタンを1秒間押して離すと強制的にゲーミングモードになります。これは動作チェック用です。
カスタマイズ
LEDのスピードや明るさ、IMEがオフの時の色などは以下のパラメーターで調整できます。
// LEDの光らせ方の設定
const uint8_t GAMING_SPEED = 600; // スピード
const uint8_t DELTA_HUE = 3; // 色の密度
const uint8_t IME_ON_BRIGHT = 128; // IMEがONのときの明るさ max 255
const uint8_t IME_OFF_BRIGHT = 10; // IMEがOFFのときの明るさ max 255
const CRGB IME_OFF_COLOR = CRGB::Blue; // IMEがOFFのときの色
親機・子機の切り替えは IS_MASTER で行います。それぞれのデバイスでコンパイルする前に書き換えてください。子機を使用する場合はUSE_ESPNOWをtrueにして、SLAVE_MAC_ADDRESS_1に子機のMACアドレスを書きます。
// 親機と子機の設定(子機がない場合は子機の設定は不要)
#define IS_MASTER true // 親機の場合はtrue、子機の場合はfalse
const bool USE_ESPNOW = false; // 子機と同期させる場合true
const uint8_t SLAVE_MAC_ADDRESS_1[] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; // 子機のMACアドレス
LED関係の設定は以下のパラメーターで変更します。たとえばATOM MatrixのLEDを使いたい場合は、USE_INTERNALをtrueにして、INLED_NUMを25にします。25はLEDの数です。Matrix以外はLEDが1個しかないので1にします。
const bool USE_INTERNAL = true; // 本体LEDを有効にする
const size_t INLED_NUM = 1; // 本体LEDの数
const bool USE_EXTERNAL = false;// 外部LED(Port A)を有効にする
const size_t EXLED_NUM = 30; // 外部LEDの数
const int GPIO_INLED = 35; // 本体LEDのGPIOポート(ATOM=27、ATOMS3=35)
const int GPIO_EXLED = 2; // 外部LED(Port A黄)のGPIOポート(ATOM=26、ATOMS3=2)
外部にLEDを接続する場合はUSE_EXTERNALをtrueにして、LEDの数をEXLED_NUMに指定します。
GPIO_INLED / GPIO_EXLED はGPIOポートです。本体裏面のシールを見ながら、自分のデバイスと同じ値を指定してください。
外部のLEDの配線方法
今回は簡単に配線できるようにPort AのGrove端子を使いました。信号線は黄色を想定しているので、変更する場合は適宜修正してください。
黒 –> GND
赤 –> 5V
黄 –> DATA
白 –>
ちなみにLEDは結構電流を食うようで、LEDテープライトを付けた状態でUSBポートに差すとハングアップしたり、シリアルポートが切断されてしまうことが多々ありました。消費電力が大きい場合はLEDの電源を別に取った方がいいかもしれません。
使ってみた感想
IMEの状態がわかるようになって、少し誤入力が減った気がします。しかし常に虹色に光っているので落ち着かず、なんだか精神的に不安定になりそうです。実用面を考えるともう少し落ち着いた光り方の方がよかったかもしれません。