Arduino でチルト付き 5 ボタンマウスを試す
ATmega32U4 を利用した Arduino の Mouse ライブラリでは左、中央、右ボタンのマウスとなっています。これにチルト機能、進むおよび戻るボタンを追加してみます。
既存の Input Report に FB(Forward Button)、BB(Back Button) を追加します[1]。
Input | D7 | D6 | D5 | D4 | D3 | D2 | D1 | D0 |
---|---|---|---|---|---|---|---|---|
1 | 0 | 0 | 0 | (FB) | (BB) | MB | RB | LB |
X, Y, Wheel はそのままになります。
Back ボタンが D3 に、Forward ボタンが D4 になるように以下を追加してボタン指定に使用します。また、チルト用の引数を追加します。
--- arduino-1.0.5 (2)/hardware/arduino/cores/arduino/USBAPI.h 2013-05-18 04:48:38.000000000 +0900 +++ arduino-1.0.5/hardware/arduino/cores/arduino/USBAPI.h 2013-09-05 18:02:41.530330129 +0900 @@ -52,6 +52,8 @@ #define MOUSE_RIGHT 2 #define MOUSE_MIDDLE 4 #define MOUSE_ALL (MOUSE_LEFT | MOUSE_RIGHT | MOUSE_MIDDLE) +#define MOUSE_BACK 8 +#define MOUSE_FORWARD 16 class Mouse_ { @@ -63,7 +65,7 @@ void begin(void); void end(void); void click(uint8_t b = MOUSE_LEFT); - void move(signed char x, signed char y, signed char wheel = 0); + void move(signed char x, signed char y, signed char wheel = 0, signed char pan = 0); void press(uint8_t b = MOUSE_LEFT); // press LEFT by default void release(uint8_t b = MOUSE_LEFT); // release LEFT by default bool isPressed(uint8_t b = MOUSE_LEFT); // check LEFT by default
以下でボタン数を増やします (USAGE_MAXIMUM を 3 から 5 に変更、REPORT_COUNT を 5 に変更、パッディングのサイズを 5 から 3 に変更)。さらに、チルト用の部分を追加します。
--- arduino-1.0.5 (2)/hardware/arduino/cores/arduino/HID.cpp 2013-05-18 04:48:38.000000000 +0900 +++ arduino-1.0.5/hardware/arduino/cores/arduino/HID.cpp 2013-09-05 20:20:40.945700558 +0900 @@ -55,14 +55,14 @@ 0x85, 0x01, // REPORT_ID (1) 0x05, 0x09, // USAGE_PAGE (Button) 0x19, 0x01, // USAGE_MINIMUM (Button 1) - 0x29, 0x03, // USAGE_MAXIMUM (Button 3) + 0x29, 0x05, // USAGE_MAXIMUM (Button 5) 0x15, 0x00, // LOGICAL_MINIMUM (0) 0x25, 0x01, // LOGICAL_MAXIMUM (1) - 0x95, 0x03, // REPORT_COUNT (3) + 0x95, 0x05, // REPORT_COUNT (5) 0x75, 0x01, // REPORT_SIZE (1) 0x81, 0x02, // INPUT (Data,Var,Abs) 0x95, 0x01, // REPORT_COUNT (1) - 0x75, 0x05, // REPORT_SIZE (5) + 0x75, 0x03, // REPORT_SIZE (3) 0x81, 0x03, // INPUT (Cnst,Var,Abs) 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 0x09, 0x30, // USAGE (X) @@ -73,6 +73,15 @@ 0x75, 0x08, // REPORT_SIZE (8) 0x95, 0x03, // REPORT_COUNT (3) 0x81, 0x06, // INPUT (Data,Var,Rel) + + 0x05, 0x0c, // USAGE_PAGE (Consumer Page) + 0x0a, 0x38, 0x02, // USAGE (AC Pan) + 0x15, 0x81, // LOGICAL_MINIMUM (-127) + 0x25, 0x7f, // LOGICAL_MAXIMUM (127) + 0x95, 0x01, // REPORT_COUNT (1) + 0x75, 0x08, // REPORT_SIZE (8) + 0x81, 0x06, // INPUT (Data,Var,Rel) + 0xc0, // END_COLLECTION 0xc0, // END_COLLECTION @@ -221,14 +230,15 @@ move(0,0,0); } -void Mouse_::move(signed char x, signed char y, signed char wheel) +void Mouse_::move(signed char x, signed char y, signed char wheel, signed char pan) { - u8 m[4]; + u8 m[5]; m[0] = _buttons; m[1] = x; m[2] = y; m[3] = wheel; - HID_SendReport(1,m,4); + m[4] = pan; + HID_SendReport(1,m,5); } void Mouse_::buttons(uint8_t b)
以下のようにして使用します。
#define PIN_BTN_LEFT 19 #define PIN_BTN_RIGHT 18 //#define PIN_BTN_MIDDLE 0 #define PIN_BTN_FORWARD 8 #define PIN_BTN_BACK 9 #define PIN_PAN_LEFT 10 #define PIN_PAN_RIGHT 11 void setup() { pinMode(PIN_BTN_LEFT, INPUT_PULLUP); // left pinMode(PIN_BTN_RIGHT, INPUT_PULLUP); // right pinMode(PIN_BTN_FORWARD, INPUT_PULLUP); // forward pinMode(PIN_BTN_BACK, INPUT_PULLUP); // back pinMode(PIN_PAN_LEFT, INPUT_PULLUP); // pan left pinMode(PIN_PAN_RIGHT, INPUT_PULLUP); // pan right Mouse.begin(); } void loop() { if (digitalRead(PIN_BTN_LEFT) == LOW) { Mouse.press(MOUSE_LEFT); } else { Mouse.release(MOUSE_LEFT); } if (digitalRead(PIN_BTN_RIGHT) == LOW) { Mouse.press(MOUSE_RIGHT); } else { Mouse.release(MOUSE_RIGHT); } if (digitalRead(PIN_BTN_FORWARD) == LOW) { Mouse.press(MOUSE_FORWARD); } else { Mouse.release(MOUSE_FORWARD); } if (digitalRead(PIN_BTN_BACK) == LOW) { Mouse.press(MOUSE_BACK); } else { Mouse.release(MOUSE_BACK); } if (digitalRead(PIN_PAN_LEFT) == LOW) { Mouse.move(0, 0, 0, -1); } if (digitalRead(PIN_PAN_RIGHT) == LOW) { Mouse.move(0, 0, 0, 1); } delay(5); }
[1] http://msdn.microsoft.com/en-us/windows/hardware/gg487477.aspx