Windows 8.1 ストアアプリでHIDデバイスを制御する


気がついたら、Windows 8.1が正式リリースされ、誰でも使えるようになりましたね。更に、Windows 8.1ストアアプリも開発者ダッシュボードに審査申請できるようになりました。これで心置きなくWinodws 8.1で新たに加わった機能を使いこなしたストアアプリの開発&公開ができるようになったわけです。

さて、このブログではWindows 8.1で新たに加わったデバイスプロトコルAPIを使って周辺機器と連携するストアアプリの開発方法について色々と紹介しているわけですが、今回はUSB接続でHID(Human Interface Device)クラスでつながる周辺機器をストアアプリで制御する方法を解説します。

HIDクラスって皆さんご存知?Human Interface Deviceという名前の通り、元々はキーボードやマウス、ジョイスティックなど、ホストに各種情報を供給するデバイスのUSB接続向けのクラスです。しかしのこのHID、単にデバイスからデータをホスト側に送れるだけでなく、ホスト側からデバイス側にデータを送ることもでき、プロトコルも比較的シンプルなので、パッと見入力機器には見えないものもこのHIDクラスでつながっている機器が多いんです。手持ちのデバイスをUSBで接続したときに、デバイスマネージャーの”ヒューマンインターフェイスデバイス”というカテゴリに項目が増えたら、そのデバイスはHIDでつながっている証拠。

このポストでは、HIDデバイス連携で世界中の人がいろいろ試しているミサイルラウンチャー( http://www.dreamcheeky.com/thunder-missile-launcher )を例に解説します。HIDデバイスを制御するプログラムは、

  1. HIDデバイス情報を探す
  2. HIDデバイスを接続する
  3. HIDデバイスとデータを送受信する

という流れで書いていきます。

1.HIDデバイス情報を探す

制御したいHIDデバイスのVendor ID、Product ID、Usage Page、Usage Idをあらかじめ調べておき、それらの値を使って、DeviceInformationインスタンスを検索します。

    string selector = HidDevice.GetDeviceSelector(usagePage, usageId, vendorId, productId);
    var deviceInformations = await DeviceInformation.FindAllAsync(selector);
    DeviceInformation deviceInformation = null;
    if (deviceInformations.Count > 0)
    {
        deviceInformation = deviceInformations.First();
    }

ミサイルラウンチャーの場合、usagePage=0x01, usageId=0x10, vendorId=0x2123, productId=0x1010です。検索したdeviceInfomationで、HIDデバイスと接続します。

2.HIDデバイスを接続する

HidDeviceクラスのFromIdAsyncメソッドを使ってデバイスと接続します。

    var mlDevice = await HidDevice.FromIdAsync(deviceInformation.Id, Windows.Storage.FileAccessMode.ReadWrite);

これで接続完了。この時、アプリケーションのUIでは、周辺機器との接続可否がユーザーに問い合わせられます。この操作は失敗することもありうるので、実際のプログラムではnullチェックを行いましょう。

3.HIDデバイスとデータを送受信する

先ず、データ送信ですが

    byte[] message = {...};
    {
        var report = mlDevice.CreateOutputReport();
        report.Data = message.AsBuffer();
        try
        {
            await mlDevice.SendOutputReportAsync(report);
        }
        catch (Exception ex)
        {
            ...
        }
    }

の様に、HidDeviceオブジェクトのCreateOutputReport();をコールして取得したHidOutputReportオブジェクトのDataプロパティに送付したいデータのバッファを代入してで送信データをセットし、SendOutputReportAsync()メソッドをコールすることによってデバイス側にデータ送信します。ミサイルラウンチャーの場合、左旋回や右旋回、上下、発射は9バイトのデータ列でコマンドが定義されていて、そのデータ列をこの形式で送付することにより制御できます。実は既に丸々コードが https://github.com/lewisbenge/Win81-DreamCheeky-Thunder-MissleLauncher からコードが公開されているので、コマンドの詳細はこちらを参照してください。例えば、{ 0, 2, 16, 0, 0, 0, 0, 0, 0 }というバイト列を送信すれば、ミサイルが発射されます。

次にHIDデバイスからのデータ受信です。こちらは、HidDeviceのInputReportReceivedイベントにハンドラを登録しておいて、データが送られてくるのを待ちます。

    mlDevice.InputReportReceived += OnInputReportEvent;

ハンドラ、OnInputReportEvent では、

    async void OnInputReportEvent(HidDevice sender, HidInputReportReceivedEventArgs args)
    {
        HidInputReport inputReport = args.Report;

        var dataReader = DataReader.FromBuffer(inputReport.Data);
        var reportedData = dataReader.ReadBytes();

        ....

の様に、イベント引数からReportを取り出し、DataReaderを通じてデータを受信します。

以上、HIDデバイスに関するプログラミングの基本はこれでおしまい。きちんと既定のデータを送受信しあえば、デバイスを制御できます。

Package.appxmanifestでのCapability宣言

HIDデバイスへの接続は、Webカメラやマイク、位置情報などと同じ扱いです。なので、Package.appxmanifestにCapability宣言を追加しないと実際には接続はできません。Package.appxmanifestファイルをコードで開いて、以下の記述(太字の部分)を追加してください。

  <Capabilities>
    <Capability Name="internetClient" />
    <DeviceCapability Name="webcam" />
    <DeviceCapability Name="microphone" />
    <m2:DeviceCapability Name="humaninterfacedevice">
      <m2:Device Id="any">
        <m2:Function Type="usage:0001 0010" />
      </m2:Device>
    </m2:DeviceCapability>
  </Capabilities>

ベンダーID、プロダクトID、UsagePage、UsageIdの取得方法

最後に、制御したいHIDデバイスの4つのパラメータを調べる方法を紹介します。ちょっと手間ですが、試してみてください。

先ず、http://msdn.microsoft.com/ja-jp/windows/hardware/gg454513 から、Windows Driver Kit 8.1をダウンロード&インストールします。

次に、http://code.msdn.microsoft.com/windowshardware/HClient-HID-Sample-4ec99697/ から、HCLIENTサンプルをソリューション一式ダウンロードし、解凍して、Visual Studio 2013でソリューションを開きます。
ターゲットをWindows 8.1 に変えてビルドします。ReleaseでもDebugでもどちらでも構いません。

コマンドプロンプトを起動し、プロジェクトフォルダー直下の、Win8.1Debug、もしくは、Win8.1Releaseにカレントディレクトリを移動します。

hclient.exe 1

とhclient.exeコマンドを実行します。すると、接続されているすべてのHIDデバイスの4つのパラメータがリスト表示されます。

デバイスを抜いた状態、USBで刺した状態でhclientを実行して差分をとれば、お目当てのデバイスの情報が得られます。

 

 

取敢えずはこんな感じのコンソールを作って試してみてくださいね。

Comments (0)

Skip to main content