Quickstart: HID (XAML)

[This article is for Windows 8.x and Windows Phone 8.x developers writing Windows Runtime apps. If you’re developing for Windows 10, see the latest documentation]

This quickstart contains C# examples that demonstrate four common tasks acccomplished by most HID apps.

The target device for several of these examples is the SuperMUTT, a test device which you can order from JJG Technologies.

Prerequisites

  • You must be familiar with HTML, C#, and Windows.
  • You must have Microsoft Visual Studio 2013 installed.
  • You must be connected to a SuperMUTT device.

Connecting to a HID device

The following example demonstrates how a Windows Runtime app, built with XAML and C#, uses the HidDeviceClass.GetDeviceSelector method to create a selector for a specific HID device and then uses the HidDeviceClass.FromIdAsync method to open a connection to that device.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using Windows.Devices.Enumeration;
using Windows.Devices.HumanInterfaceDevice;
using Windows.Storage;
using Windows.Storage.Streams;

namespace HidSampleCS
{
    class Enumeration
    {
        // Enumerate HID devices
        private async void EnumerateHidDevices()
        {
            UInt32 vendorId = 0x045E;
            UInt32 productId = 0x078F;
            UInt32 usagePage = 0xFF00;
            UInt32 usageId = 0x0001;

            // Create a selector that gets a HID device using VID/PID and a 
            // VendorDefined usage
            string selector = HidDevice.GetDeviceSelector(usagePage, usageId, 
                              vendorId, productId);

            // Enumerate devices using the selector
            var devices = await DeviceInformation.FindAllAsync(selector);

            if (devices.Count > 0)
            {
                // Open the target HID device
                HidDevice device = await HidDevice.FromIdAsync(devices.ElementAt(0).Id, 
                                   FileAccessMode.ReadWrite);

                // At this point the device is available to communicate with
                // So we can send/receive HID reports from it or 
                // query it for control descriptions
            }
            else
            {
                // There were no HID devices that met the selector criteria
                this.NotifyUser("MUTT HID device not found");
            }
        }
    }
}

Retrieving data from a HID device

Apps retrieve data from a HID device using input reports. The following example demonstrates how an app used the HidInputReport.GetNumericControl method to retrieve a numeric value from a SuperMUTT device.

        private async Task GetNumericInputReportAsync()
        {
            var inputReport = await DeviceList.Current.CurrentDevice.GetInputReportAsync(SuperMutt.ReadWriteBuffer.ReportId);

            var inputReportControl = inputReport.GetNumericControl(SuperMutt.ReadWriteBuffer.NumericUsagePage, SuperMutt.ReadWriteBuffer.NumericUsageId);

            var data = inputReportControl.Value;

            rootPage.NotifyUser("Value read: " + data.ToString("X2", NumberFormatInfo.InvariantInfo), NotifyType.StatusMessage);
        }
[]

Sending data to a HID device

Apps send data to a HID device using output reports. The following example demonstrates how an app used the HidDevice.CreateOutputReport method to create an output report and the HidDevice.SendOutputReportAsync method to send that report to a device.

private async Task SendNumericOutputReportAsync(Byte valueToWrite)
        {
            var outputReport = DeviceList.Current.CurrentDevice.CreateOutputReport(SuperMutt.ReadWriteBuffer.ReportId);

            // Only grab the byte we need
            Byte[] bytesToModify = new Byte[1];

            WindowsRuntimeBufferExtensions.CopyTo(outputReport.Data, SuperMutt.ReadWriteBuffer.NumericDataByteIndex, bytesToModify, 0, bytesToModify.Length);

            Byte oldData = bytesToModify[0];    // Contains more information than just our 4 bits of data

            // Our data is supposed to be stored in the lower 4 bits of the byte
            Byte maskedOldData = (Byte)(oldData & (~SuperMutt.ReadWriteBuffer.NumericDataMask));
            Byte byteToWrite = (Byte)(maskedOldData | (valueToWrite & SuperMutt.ReadWriteBuffer.NumericDataMask));   // Make sure we will only overwrite the lower 4 bits

            WindowsRuntimeBufferExtensions.CopyTo(bytesToModify, 0, outputReport.Data, SuperMutt.ReadWriteBuffer.NumericDataByteIndex, bytesToModify.Length);

            uint bytesWritten = await DeviceList.Current.CurrentDevice.SendOutputReportAsync(outputReport);

            rootPage.NotifyUser("Bytes written:  " + bytesWritten.ToString() + "; Value Written: " + valueToWrite.ToString(), NotifyType.StatusMessage);
        }

Sending requests to a HID device

Apps send requests to a HID device using feature reports. For example, the SuperMUTT test device allows an app to toggle the blink pattern of its LED using a feature report. The following example demonstrates how an app used the HidDevice.CreateFeatureReport method to create a feature report and the HidDevice.SendFeatureReportAsync method to send that report to the device.

        async Task SetLedBlinkPatternAsync(Byte pattern)
        {
            var featureReport = DeviceList.Current.CurrentDevice.CreateFeatureReport(SuperMutt.GetSetLedPattern.ReportId);

            // Only grab the byte we need
            Byte[] bytesToModify = new Byte[1];

            WindowsRuntimeBufferExtensions.CopyTo(featureReport.Data, SuperMutt.GetSetLedPattern.DataByteIndex, bytesToModify, 0, bytesToModify.Length);

            bytesToModify[0] = pattern;

            WindowsRuntimeBufferExtensions.CopyTo(bytesToModify, 0, featureReport.Data, SuperMutt.GetSetLedPattern.DataByteIndex, bytesToModify.Length);

            await DeviceList.Current.CurrentDevice.SendFeatureReportAsync(featureReport);

            rootPage.NotifyUser("The Led blink pattern is set to " + pattern.ToString(), NotifyType.StatusMessage);
        }

Summary

Once you've tackled these concepts with your SuperMUTT device, you can begin adapting them to another HID peripheral.

Note

Windows Phone Store apps can access the Windows.Devices.HumanInterfaceDevice API if the manufacturer supported the HID protocol for specific devices and provided corresponding device-data to app developers. Refer to your manufacturer’s documentation for a list of supported HID devices as well as the data that you’ll need to implement device discovery.

Sample Windows Runtime app for HID

Windows.Devices.HumanInterfaceDevice