フット入力 > Winソフト(v0.1) > UDP通信 / エッジ(Push)検出 /スペースキー割当て


関連 http://qiita.com/7of9/items/c5e39a8c08ca7a6e5af6

動作環境
C++ Builder XE4

RPiソフト http://qiita.com/7of9/items/faae2a627443ff137c84
に対して、UDP通信をして入力情報を取得するWinソフトの実装.

Code v0.1

処理の主要部分。

Main.cpp

/*
v0.1 2016 Apr 24
    - recognize rising edge (push)
    - receive inputs through UDP
*/

static const int kNumInput = 6;

static bool sIns[kNumInput] = { 0 };

void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
    Timer1->Enabled = false;

    IdUDPClient1->Host = L"192.168.10.6";
    IdUDPClient1->Port = 7002;
    IdUDPClient1->Active = true;

    IdUDPClient1->Send("foot\r\n");

    Sleep(10);
    Application->ProcessMessages();

    AnsiString res = IdUDPClient1->ReceiveString(200);

    procInput(res);

    IdUDPClient1->Active = false;
    Timer1->Enabled = true;

}
//---------------------------------------------------------------------------

void __fastcall TForm1::procInput(String res)
{
    if(res.Length() == 0) {
        return;
    }

    std::unique_ptr<TStringList> line(new TStringList);

    line->CommaText = res;

    bool ins[kNumInput];
    try {
        for(int idx=0; idx < kNumInput; idx++) {
            ins[idx] = !( (bool)line->Strings[idx+1].ToInt() );
        }
    } catch (...) {
    }

    CheckBox1->Checked = ins[0];
    CheckBox2->Checked = ins[1];
    CheckBox3->Checked = ins[2];
    CheckBox4->Checked = ins[3];
    CheckBox5->Checked = ins[4];
    CheckBox6->Checked = ins[5];

    for(int idx=0; idx < kNumInput; idx++) {
        if (sIns[idx] == ins[idx]) {
            continue;
        }
        if (ins[idx]) {
            String msg = L"SW" + IntToStr(idx+1) + L" > pushed";
            Memo1->Lines->Add(msg);
        }
        sIns[idx] = ins[idx];
    }
}

Timer1: 300msecに設定。

300msecごとにUDP通信をして現在のキー状態を取得。
前回のキーの状態と比較して、falseからtrueに変化時(エッジ)でキーが押されたと判断する。

実行

順番に足で押してみた。

スペースキーを押す

procInput()の処理の一部を以下のようにした。
SW4を踏んだ時にSPACEキーを押したことになる。

        if (ins[idx]) {
            String msg = L"SW" + IntToStr(idx+1) + L" > pushed";
            Memo1->Lines->Add(msg);

            if (idx== 3) { // SW4
                keybd_event(VK_SPACE, 0, 0, 0);
            }
        }

これで動かしたところ、ブラウザ閲覧時にSW4を押してスクロールされるようになった。スペースキーを押したことになっている。

足で押してから実際にキー入力になるまでの応答性はよくない。500msec待つような感じだ。調整してよくなるだろうか?

Shift keydown/keyup

Shiftキーを押した、離したをSW1で実装。
notepadで大文字/小文字混じりの文章を入力することができた。

void __fastcall TForm1::procInput(String res)
{
    if(res.Length() == 0) {
        return;
    }

    std::unique_ptr<TStringList> line(new TStringList);

    line->CommaText = res;

    bool ins[kNumInput];
    try {
        for(int idx=0; idx < kNumInput; idx++) {
            ins[idx] = !( (bool)line->Strings[idx+1].ToInt() );
        }
    } catch (...) {
    }

    CheckBox1->Checked = ins[0];
    CheckBox2->Checked = ins[1];
    CheckBox3->Checked = ins[2];
    CheckBox4->Checked = ins[3];
    CheckBox5->Checked = ins[4];
    CheckBox6->Checked = ins[5];

    for(int idx=0; idx < kNumInput; idx++) {
        if (sIns[idx] == ins[idx]) {
            continue;
        }
        if (ins[idx]) {
            String msg = L"SW" + IntToStr(idx+1) + L" > pushed";
            Memo1->Lines->Add(msg);

            if (idx== 3) { // SW4
                keybd_event(VK_SPACE, 0, 0, 0);
            }

        }

        if (idx == 0) {
            if(ins[idx]) { // key down
                keybd_event(VK_SHIFT, 0, 0, 0);
            } else { // key up
                keybd_event(VK_SHIFT, 0, KEYEVENTF_KEYUP, 0);
            }
        }
        sIns[idx] = ins[idx];
    }
}