前置き
私は 自作USBキーボードを、今までに幾つか作ってきた。
私が愛用しているのは Microchip PIC16F1454/1455/1459。
これらには USBデバイス機能が実装されているので
USBキーボード, USBマウス, などのUSBデバイスを作ることができる。
「 Microchip Libraries for Applications (MLA) 」
を入手し、その中の HID_keyboard のライブラリ群とサンプルを PIC16F1454/1455/1459 用に移植して使っている。
今回、ここは深く触れない。
で、自作USBキーボードを作るとは、
・ボタン①を押すと、Ctrl-v を発行する
・ボタン②を押すと、abYZ という文字を発行する
などの自分が欲しい/特殊なキーボードが作れるわけで...
押しボタンではなく フットペダルで実現する人も居るようですね。
マイコンプログラム
PICであれ、ATmegaであれ、、、どの USBマイコンでも、USB-HIDプロトコルに従って KeyCodeを送出すれば キーが押されたことになる訳だ。
USB-HIDパケット(キーボード)は 8byteデータで、下記の構成である。
unsigned char hid_report[8] ;
hid_report[0] = 0; // modifirers bit
// 0x80:右Win, 0x40:右Alt, 0x20:右Shift, 0x10:右Ctrl
// 0x08:左Win, 0x04:左Alt, 0x02:左Shift, 0x01:左Ctrl
hid_report[1] = 0; // 0x00 (reserved)
hid_report[2] = kCode; // 押されたキーのデータ
hid_report[3] = 0; // 同時に押されたキーのデータ(1)
hid_report[4] = 0; // 同時に押されたキーのデータ(2)
hid_report[5] = 0; // 同時に押されたキーのデータ(3)
hid_report[6] = 0; // 同時に押されたキーのデータ(4)
hid_report[7] = 0; // 同時に押されたキーのデータ(5)
// データ(8byte)の送信
lastINTransmission = HIDTxPacket(HID_EP, (BYTE*)hid_report, 8);
送出パケットの例
キーが押されたことにするには、次のような 8byte群を 順次送出すればいい。
例1) Ctrl-v を送出する
{ 0x01, 0x00, 0x19, 0x00, 0x00, 0x00, 0x00, 0x00 }; // CTRL v
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // (release)
の2パケットを順次送出する
例2) abYZ という文字を送出する
{ 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00 }; // a
{ 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 }; // b
{ 0x02, 0x00, 0x1C, 0x00, 0x00, 0x00, 0x00, 0x00 }; // shift y
{ 0x02, 0x00, 0x1D, 0x00, 0x00, 0x00, 0x00, 0x00 }; // shift z
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // (release)
の5パケットを順次送出する
と、ここまでは良く知られた仕様ですので、実際に実装された方も多いでしょう。
漢字文字を送出したい
前記のように、ASCII文字は送出できるのだが、では漢字文字はどうすればいいのか?
[~読みがな~] + [変換] と出力すれば入力できるのか?
でも、何回 [変換] 押せばいいのだろうか?
無理があるな。
ここでネット探してたら、この記事を見つけた。
Windows MS-IME限定なようだが、この記事の操作を試してみる。
- レジストリ定義
HKEY_CURRENT_USER\Control Panel\Input Method に
EnableHexNumpad を (REG_SZ)1 で定義
2. テンキーから、以下のキーを押下する
1) ALTキーを押したまま
2) テンキーの + (プラス) を1回押す
3) テンキーの 数字(0~9) と フルキーの英字(a~f)を押し Unicodeの16進数4桁を入力する
(例えば、6 1 1 b と入力する)
4) ALTキーを離す
(例なら、「愛」が入力されたことになる)
※ここで CapsLock や NumLock の状態は関係ない
HIDパケットで 漢字文字を送出してみる
前記の通り、キーボードを叩いたことにすればいいのではないだろうか?
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // ALT.押す
{ 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Num +
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 16進 4桁
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 6 1 1 b 「愛」
{ 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x59, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // ALT.離す (終了)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // (release)
この12パケットを順次送出すると「愛」が入力されたことになる。[成功]
※ここで CapsLock や NumLock の状態は関係ない
では、複数文字は可能か?
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // ALT.押す
{ 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Num +
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 16進 4桁
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 2 6 0 5 「★」
{ 0x04, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x5D, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // ALT.離す (終了)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // (release)
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // ALT.押す
{ 0x04, 0x00, 0x57, 0x00, 0x00, 0x00, 0x00, 0x00 }; // Num +
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x5A, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 16進 4桁
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // 2 6 0 6 「☆」
{ 0x04, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x62, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x5E, 0x00, 0x00, 0x00, 0x00, 0x00 };
{ 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // ALT.離す (終了)
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // (release)
の 24パケットを順次送出すると「★☆」が入力されたことになる。[成功]
以上から、この手順を使えば 漢字複数文字(日本語文章)や ASCII混在の文章だって自動入力できちゃう訳だ。
注意
ただし、Windows の MS-IME 環境での話。
私の自作キーボードで動作確認できたのは Windows7(x86/x64), Windows10(x64), Windows11(x64) です。
以上