ATmega 32u4を使ったマウス応用同様、キーボードもレポート形式でデータを送信する事で複雑な制御が出来る。
ただ、マウス同様HID-Projectのライブラリそのままではレポート形式での送信が出来ないので、ライブラリに少し手を加える。
HID-Project\src\HID-APIs\KeyboardAPI.h を編集し、sSendReportの関数をpublicの所に追加する。
// Needs to be implemented in a lower level
virtual size_t removeAll(void) = 0;
virtual int send(void) = 0;
inline void sSendReport(void* data, int length) { HID().SendReport(HID_REPORTID_KEYBOARD, data, length); };
private:
virtual size_t set(KeyboardKeycode k, bool s) = 0;
inline size_t set(uint8_t k, bool s);
};
キーボードのレポートのデータ形式は下記の通り、キーは同時に6つまで+モディファイアキーを送信できる。
typedef union{
struct{
uint8_t modifiers;
uint8_t reserved;
KeyboardKeycode keycodes[6];
};
} HID_KeyboardReport_Data_t;
モディファイアは下記の通り。
値 | キー |
0x01 | 左Control |
0x02 | 左Shift |
0x04 | 左Alt |
0x08 | 左Win |
0x10 | 右Control |
0x20 | 右Shift |
0x40 | 右Alt |
0x80 | 右Win |
キーの定義は下記を参照。
https://github.com/NicoHood/HID/blob/master/src/KeyboardLayouts/ImprovedKeylayouts.h
HID_KeyboardReport_Data_t のデータ構造体に押しているキーの情報を設定し、レポート送信する。もう一度空のデータを送信する事で、押して離した動作となる。
以下は、スケッチ開始5秒後にWin + R キーを押して離した後(ファイル名を指定して実行のウィンドウが開く)、notepad.exeを入力して改行を押すサンプル。上手く動けばメモ帳が開く。
#include <HID-Project.h> //HID-Project by NicoHood
#define MOD_CTL 0x01
#define MOD_SHFT 0x02
#define MOD_ALT 0x04
#define MOD_WIN 0x08
void setup() {
delay(5000);
Keyboard.begin();
HID_KeyboardReport_Data_t report;
memset(&report, 0, sizeof(HID_KeyboardReport_Data_t));
report.keycodes[0] = KEY_R;
report.modifiers = MOD_WIN;
Keyboard.sSendReport(&report, sizeof(report)); //press
delay(50);
memset(&report, 0, sizeof(HID_KeyboardReport_Data_t));
Keyboard.sSendReport(&report, sizeof(report)); //release
delay(2000);
Keyboard.print("notepad.exe\n");
}
void loop() {
}