「PIC18F14K50 + USB + PC + HID Mouse (MLA v2015-08-10)」の続き。
あまりにも簡単に動いたので、少しだけコードを眺めてみた。
まあ、PICをやり始めてから見よう見まねでCをやりだした私には、「チンプンカンプン」という表現がぴったりの状態だ。
それでもmain()からはじまるくらいの事はわかるのでたどってみる。
すると、USBの接続待ちとか認識待ちのための処理なんだろうなと思われるコードを除けば、それ以外にずっと繰り返し実行しているのは
SYSTEM_Tasks();
なので、これを眺めてみる。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
void APP_DeviceMouseTasks(void) { bool currentButtonState; /* Get the current button state */ currentButtonState = BUTTON_IsPressed(BUTTON_USB_DEVICE_HID_MOUSE); /* If the button state has changed since the last time we checked it, then * we enable/disable movement mode. */ if(mouse.lastButtonState != currentButtonState) { mouse.lastButtonState = currentButtonState; if(currentButtonState == false) { mouse.movementMode = !mouse.movementMode; mouse.inputReport[0].idleRateSofCount = 0; mouse.sentStop = false; } } }//end ProcessIO |
ざっくりと、ボタンが押されたかどうかをチェックして、トグルでマウスを動かすか止めるかを設定しているらしいことがわかる。
mouse.movementMode = !mouse.movementMode;
このmouse.—–というのは何だろな。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
typedef struct { bool sentStop; bool lastButtonState; uint8_t vectorPosition; uint16_t movementCount; bool movementMode; struct { USB_HANDLE handle; uint8_t idleRate; uint8_t idleRateSofCount; } inputReport[1]; } MOUSE; static MOUSE mouse; |
「構造体」というものらしい。
いろいろ検索した結果、http://www9.plala.or.jp/sgwr-t/c/sec15.htmlやhttp://www9.plala.or.jp/sgwr-t/c/sec16.htmlで教わった限りでは、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
struct seiseki { int no; char name[20]; double average; }; struct seiseki seito1 = { 5, "KASAHARA", 83.5 }; typedef struct { int no; char name[20]; double average; } SEISEKI; SEISEKI seito1 = { 5, "KASAHARA", 83.5 }; |
のどちらも同じことらしく、型名が長くならないように下のように書くらしい。
いずれにしてもこのmouse.ではじまる構造体の要素の値をいろいろ変えればマウスの操作ができるということだろう。
この近辺に実際に実行する行が見つからないのは、たぶん割り込みをかけて定期的に割り込みルーチンから実行しているんだろう。
そちらは後回しにして、値をいろいろ変えて遊んでみることはできる。
例えば、元の行をコメントアウトして、xVector[]とmouseReport.buttons.button2の値を以下のように変更すると、
1 2 3 4 5 6 7 8 |
//static const uint8_t xVector[]={ -1, 0, 1, 0}; static const uint8_t xVector[]={ -3, 0, 3, 0}; static const uint8_t yVector[]={ 0, -1, 0, 1}; mouseReport.buttons.button1 = 0; //mouseReport.buttons.button2 = 0; mouseReport.buttons.button2 = 1; mouseReport.buttons.button3 = 0; |
元々は正方形だった動く範囲が横長の長方形になり、マウスの右ボタンが押された状態になる。
マウスから手を離していてもマウスの任意のボタンを押しっぱなしに出来るというのは、アプリケーションによっては使い道がある。
例えば、動画の編集で使う「MPEGEnc MPEG Smart Render 4」などは、サムネイル上で右クリックしたまますると早送り状態が継続し、左右のマウスの位置で送る速度が変えられる仕様だ。
これが、ものによっては結構長い間右ボタンを押し続けたままのこともあるので、代わりにPICにやらせたら楽ができて便利かもしれない。
上の動画、マウスには触れてないけどPICで右ボタンを押し続けてるので、モニター上では動画が早送りされている。
最近テレビ番組の質がすっかり落ちて、早送りで観れば十分なケースがほとんどなので、これはいいかも。
気になる場面を通過したときにタクトスイッチを押せば早送りが停止する。
app_device_mouse.c の172行目あたりを
//static const uint8_t xVector[]={ -1, 0, 1, 0};
static const uint8_t xVector[]={ 0, 0, 0, 0};
//static const uint8_t yVector[]={ 0, -1, 0, 1};
static const uint8_t yVector[]={ 0, 0, 0, 0
と書き変えれば矩形を描く動作をしなくなり、353行目あたりを
mouseReport.buttons.button1 = 0;
//mouseReport.buttons.button2 = 0;
mouseReport.buttons.button2 = 1;
mouseReport.buttons.button3 = 0;
と書き変えればマウスの右ボタンが押された状態になる。
変更点はたったこれだけだ。