前提・実現したいこと
USBキーボードから送られてくるキーコードをArduinoで取得したいと考えています。
接続順は 【USBキーボード】 → 【USBホストシールド】 → 【Arduino Pro Micro】 → 【PC】の順で
現在は下記のブログの記事を参考に、キーボード入力をArduinoを経由させてPCへ出力する所まで作成することができました。
ですが、どの変数にキー情報が格納されているかがわからず、開発が行き詰まっています。
もし分かる方が居られましたら、何卒宜しくお願いいたします。
【参考とさせて頂いた記事及びコード】
Pro Microにmini USB Hostシールドを付けてUSBキーボードを接続する
現状の理解
間違っている可能性も高いのですが、
下記の関数sendReport()がキー情報をPCへ送る関数と予想しています。
・2はID(1がマウス用のIDらしいのでキーボード用のIDと予測)
・&KeyReportがキー情報(←このアドレスの値を取得できれば解決?)
・sizeofの出力結果は8
//HIDクラスを使ってレポートを送信する関数 void sendReport() { HID().SendReport(2, &keyReport ,sizeof(KeyReport)); }
試したこと及び現在の状況
&keyReportを、print関数で出力しようとしたり、変数に格納しようと試して見たもののエラーが発生。
内部がどのような値になっているのかや、どのようにすれば取得できるかがわからずにいます。
###質問者のプログラミング経験
VBA,GAS,UWSCと操作の自動化でしか取り扱いの経験がなく、
Arduino(C/C++)言語は初めてまだ日が浅いため、修練中の身です。
###参考とさせて頂いてるコード
Arduino
1#include "HID.h" 2 3#include <hidboot.h> 4#include <usbhub.h> 5#include <SPI.h> 6 7static const uint8_t _hidReportDescriptor[] PROGMEM = { 8 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 9 0x09, 0x06, // USAGE (Keyboard) 10 0xa1, 0x01, // COLLECTION (Application) 11 0x85, 0x02, // REPORT_ID (2) --- Mouse.cppがID==1。 12 13 0x05, 0x07, // USAGE_PAGE (usage = keyboard page) 14 // モデファイヤキー(修飾キー) 15 0x19, 0xe0, // USAGE_MINIMUM (左CTRLが0xe0) 16 0x29, 0xe7, // USAGE_MAXIMUM (右GUIが0xe7) 17 0x15, 0x00, // LOGICAL_MINIMUM (0) 18 0x25, 0x01, // LOGICAL_MAXIMUM (1) 19 0x95, 0x08, // REPORT_COUNT (8) 全部で8つ(左右4つずつ)。 20 0x75, 0x01, // REPORT_SIZE (1) 各修飾キーにつき1ビット 21 0x81, 0x02, // INPUT (Data,Var,Abs) 8ビット長のInputフィールド(変数)が1つ。 22 // 予約フィールド 23 0x95, 0x01, // REPORT_COUNT (1) 24 0x75, 0x08, // REPORT_SIZE (8) 1ビットが8つ。 25 0x81, 0x01, // INPUT (Cnst,Var,Abs) 26 // LED状態のアウトプット 27 0x95, 0x05, // REPORT_COUNT (5) 全部で5つ。 28 0x75, 0x01, // REPORT_SIZE (1) 各LEDにつき1ビット 29 0x05, 0x08, // USAGE_PAGE (LEDs) 30 0x19, 0x01, // USAGE_MINIMUM (1) (NumLock LEDが1) 31 0x29, 0x05, // USAGE_MAXIMUM (5) (KANA LEDが5) 32 0x91, 0x02, // OUTPUT (Data,Var,Abs) // LED report 33 // LEDレポートのパディング 34 0x95, 0x01, // REPORT_COUNT (1) 35 0x75, 0x03, // REPORT_SIZE (3) 残りの3ビットを埋める。 36 0x91, 0x01, // OUTPUT (Cnst,Var,Abs) // padding 37 // 押下情報のインプット 38 0x95, 0x06, // REPORT_COUNT (6) 全部で6つ。 39 0x75, 0x08, // REPORT_SIZE (8) おのおの8ビットで表現 40 0x15, 0x00, // LOGICAL_MINIMUM (0) キーコードの範囲は、 41 0x25, 0xdd, // LOGICAL_MAXIMUM (221) 0~221(0xdd)まで 42 43 0x05, 0x07, // USAGE_PAGE (Keyboard) 44 0x19, 0x00, // USAGE_MINIMUM (0はキーコードではない) 45 0x29, 0xdd, // USAGE_MAXIMUM (Keypad Hexadecimalまで) 46 0x81, 0x00, // INPUT (Data,Ary,Abs) 47 0xc0 // END_COLLECTION 48}; 49 50#define REPORT_KEYS 6 51typedef struct { 52 uint8_t modifiers; 53 uint8_t reserved; 54 uint8_t keys[REPORT_KEYS]; 55} KeyReport; 56 57KeyReport keyReport; 58 59void sendReport() { 60 HID().SendReport(2, &keyReport ,sizeof(KeyReport)); 61} 62 63void releaseAll() { 64 memset(&keyReport, 0, sizeof(KeyReport)); 65 sendReport(); 66} 67 68void report_press(uint8_t key, uint8_t mod) { 69 if (key != 0) { 70 bool already = false; 71 int empty_slot = -1; 72 for(int i = 0; i < REPORT_KEYS; i++) { 73 if (keyReport.keys[i] == key) 74 already = true; 75 if (keyReport.keys[i] == 0 && empty_slot < 0) 76 empty_slot = i; 77 } 78 if (empty_slot < 0) // error condition. 79 return; 80 if (!already) 81 keyReport.keys[empty_slot] = key; 82 } 83 keyReport.modifiers = mod; 84 sendReport(); 85} 86 87void report_release(uint8_t key, uint8_t mod) { 88 if (key != 0) { 89 for(int i = 0; i < REPORT_KEYS; i++) { 90 if (keyReport.keys[i] == key) { 91 keyReport.keys[i] = 0; 92 break; 93 } 94 } 95 } 96 keyReport.modifiers = mod; 97 sendReport(); 98} 99 100class KeyboardEvent : public KeyboardReportParser { 101 protected: 102 void OnControlKeysChanged(uint8_t before, uint8_t after); 103 void OnKeyPressed(uint8_t key) {}; 104 void OnKeyDown (uint8_t mod, uint8_t key) { report_press(key, mod); }; 105 void OnKeyUp (uint8_t mod, uint8_t key) { report_release(key, mod); }; 106}; 107 108void KeyboardEvent::OnControlKeysChanged(uint8_t before, uint8_t after) { 109 uint8_t change = before ^ after; 110 if (change != 0) { 111 if (change & after) 112 report_press(0, after); 113 else 114 report_release(0, after); 115 } 116} 117 118USB Usb; 119HIDBoot<USB_HID_PROTOCOL_KEYBOARD> HidKeyboard(&Usb); 120KeyboardEvent kbd; 121 122void error_blink(int period) { 123 for(;;) { 124 TXLED1; delay(period); TXLED0; delay(period); 125 RXLED1; delay(period); RXLED0; delay(period); 126 } 127} 128 129void setup() { 130 static HIDSubDescriptor node(_hidReportDescriptor, sizeof(_hidReportDescriptor)); 131 HID().AppendDescriptor(&node); 132 delay(200); 133 releaseAll(); 134 if (Usb.Init() == -1) 135 error_blink(400); 136 delay( 200 ); 137 HidKeyboard.SetReportParser(0, &kbd); 138} 139 140void loop() { 141 Usb.Task(); 142} 143
###追記
・12/20 一度変数に格納することでコンパイル成功、どのキーを押しても169と表示されるので、1byte×8個の表記にするにはどうすればいいか、どこに問題があるのか模索中。
Arduino
1Serial.println(&keyReport);//コンパイル時にエラー 2 3//↓一度変数に格納するとコンパイル成功 4 5uint8_t a =&keyReport; 6Serial.println(&keyReport);//169 の数値が固定でログに表示される。 7 8
回答1件
あなたの回答
tips
プレビュー