Windows SDK

The U Grok It SDK for Windows enables easy integration of RFID functionality into a Windows 7, Windows 8 or Windows 10 app (currently Intel platforms only).

The SDK is built with Microsoft Visual Studio 2017. it can also be used with Visual Studio 2015 and Visual Studio 2013, provided you include the Visual Studio 2015 runtime DLLs, which are included in the SDK.

Downloading and Installation

The contents of UGrokItWindowsSdk.zip are:

  • dll (folder)
    The dll folder contains four sub-folders, one for each build configuration. Each folder contains 2 DLLs (UGrokItApi.dll and UgiInternal.dll) that together comprise the U Grok It SDK.
    • Release and Debug
      32-bit Release and Debug DLLs. These work on most 64-bit machines also, since most 64-bit machines will run 32-bit code.
    • Release_x64 and Debug_x64
      64-bit Release and Debug DLLs.
  • html (folder)
    The HTML documentation
  • ApiDemo folder
    This folder contains the ApiDemo sample application.
Download the SDKs
iOS, Android, Cordova, Xamarin
The ApiDemo sample app

The APIDemo application demonstrates use of the API. To open ApiDemo, go into the ApiDemo folder in the SDK and open the ApiDemo.csproj file.

Stand-alone version of ApiDemo

For testing compatibility with Windows devices that do not have Visual Studio installed, it is useful to have a stand-alone version of ApiDemo. This can be downloaded here (built with SDK 1.16.13) This ZIP file has sub-directories for various builds (Debug/Release, Win32/x64, VS2017/VS2013). Run the ApiDemo.exe file within any of these sub-directories.

Integrating the API into an existing app

To integrate the U Grok It API into an existing app in Visual Studio:

  • Unzip the SDK (creates a UGrokItWindowsSdk folder)
  • Copy the contents of the dll/Debug folder from the SDK into your application
  • Add a reference to UGrokItApi.dll and enable UgiInternal.dll to be found during execution
    There are several ways of doing this. The method described below works for both Debug and Release builds.
    • In Visual Studio, select your application and to PROJECT>Add Reference, then click Browse, and select UGrokItApi.dll from the dll/Debug folder and add it.
    • Edit the .csproj file in a text editor and change:
      <HintPath>dll\Debug\UGrokItApi.dll</HintPath>
      to:
      <HintPath>dll\$(Configuration)\UGrokItApi.dll</HintPath>
    • Select the project node and do PROJECT>Properties and add a Post-build event:
      copy $(ProjectDir)\dll\$(Configuration)\UgiInternal.dll $(ProjectDir)\bin\$(Configuration)
    • This copies UgiInternal.dll into the build directory where the .exe file is.
Accessing the API

The API is accessed through the Ugi singleton object in the UGrokItApi namespace.

using UGrokItApi;

The singleton object must be explicitly created with the CreateSingleton. This is usually done in your application object:

public App() : base() {
  Ugi.CreateSingleton();
}
Housekeeping

A production level app needs to do a few housekeeping functions:

  • Region Setting
    A new Grokker must be configured for the region of the world that it will operate in.
  • Firmware Update
    From time to time, we will release firmware updates for the Grokker.

Calling Ugi.CreateSingleton() as shown above will use standard UI built into the SDK for these functions.

If you want to customize this UI or if you want to be more restrictive about how and when firmware updates are done, you can pass your own configuration delegate object to Ugi.createSingleton(IUgiConfigurationDelegate configurationDelegate)

Opening and Closing a connection to the grokker

Communication with the grokker is done via the audio port. For an application that uses U Grok It functionality all the time, this can be done in your application object also:

public App() : base() {
  Ugi.CreateSingleton();
  Ugi.Singleton().OpenConnection();
}

For an application that only uses U Grok It occasionally, the connection can be opened and closed at the appropriate points.

OpenConnection returns immediately, it does not wait for a connection to the grokker to actually be established. If a grokker is connected, the connection takes 400-500ms (just under half a second) for the connection sequence. Your app can get notification of connection state changes vis the ConnectionStateChanged delegate:

  Ugi.Singleton().ConnectionStateChanged += ConnectionStateHandler;

The handler method looks like this:

  void ConnectionStateHandler(Ugi.ConnectionStates state) {
    if (state == Ugi.ConnectionStates.Connected) {
      // Connection was established...
    }
  }

Usually a state changed method is not needed, using the Inventory methods described below takes care of this.

Compatibility

By default, the SDK tries to recognize the headphone audio devices, and if it can't, the default audio devices are used. This works well on most Windows devices, but not with a few Windows 8 laptops. You can prevent the SDK from trying to use the headphone audio devices by creating the singleton like this:

UgiDefaultConfigurationUi c = new UgiDefaultConfigurationUi();
c.UseHeadphoneAudioDevice = false;
Ugi.CreateSingleton(c);
Inventory

Finding RFID tags is accomplished by running inventory. Once inventory is started, the grokker continually looks for RFID tags and reports them back to the iOS device.

Starting inventory returns a UgiInventory object that holds the results of the inventory. The application can either save the UgiInventory object or can use Ugi.Singleton ().ActiveInventory to get to it.

UgiInventory does some useful aggregation of the raw data from the grokker and reports back to your application via an InventoryDelegate object. Inventory can be run either with a configuration built from one of the pre-defined inventory types or with a custom UgiRfidConfiguration object.

The application can tell the grokker to report all RFID tags it finds:

  Ugi.Singleton().StartInventory(this,    // delegate object
        UgiRfidConfiguration.ConfigWithInventoryType(
                        UgiRfidConfiguration.InventoryTypes.LocateDistance));

Or the application can pass a specific tag to find:

  UgiEpc epc = UgiEpc.FromString("35fffffff99c70a063405c48");
  Ugi.Singleton().StartInventory(this,    // delegate object
        UgiRfidConfiguration.ConfigWithInventoryType(
                        UgiRfidConfiguration.InventoryTypes.LocateDistance),
        epc);

Or the application can pass an array of tags to find:

  UgiEpc epc1 = UgiEpc.FromString("35fffffff99c70a063405c48");
  UgiEpc epc2 = UgiEpc.FromString("35fffffff956734504747454");
  Ugi.Singleton().StartInventory(this,    // delegate object
        UgiRfidConfiguration.ConfigWithInventoryType(
                        UgiRfidConfiguration.InventoryTypes.LocateDistance),
        new List() { epc1, epc2});

Inventory runs until the application stops it.

  Ugi.Singleton().ActiveInventory.StopInventory(() => {
    // code to run when inventory is completely stopped
  });
Inventory Delegate methods

The inventory code reports back to the application via the inventory delegate object. The delegate object must implement the IUgiInventoryDelegate protocol:

public class MainActivity : Activity, IUgiInventoryDelegate

Only a subset of the inventory delegate methods are discussed here.

New tag found

When a new tag is found, the delegate is notified via inventoryTagFound (the detailedPerReadData is nil unless the Grokker was told to return detailed per-read data).

  public void InventoryTagFound(UgiTag tag,
                                UgiDetailedPerReadData[] detailedPerReadData) {
    // tag was found for the first time
  }

The UgiTag object contains information about the tag including:

  • Its EPC code
  • The time the tag was first read, the time the tag was most recently read
  • The total number of times this tag has been read
  • A history of how many times this tags has been read in recent time intervals (the default being the number of reads per 500ms going back 10 seconds, but this is configurable)
Subsequent finds of previously found tag

When a tag is found again, the delegate is notified via inventoryTagSubsequentFinds (the detailedPerReadData is nil unless the Grokker was told to return detailed per-read data).

  public void InventoryTagSubsequentFinds(UgiTag tag, int count,
                  UgiDetailedPerReadData[] detailedPerReadData) {
    // tag found count more times
  }
Tag visibility changed

When a tag is first found, has not been seen for a while (by default 10 seconds, but configurable), or is seen again after not being seen for awhile, the delegate is notified via:

  public void InventoryTagChanged(UgiTag tag, bool firstFind) {
    if (firstFind) {
      // tag was found for the first time
    } else if (tag.IsVisible) {
      // tag was not visible, is now visible again
    } else {
      // tag is no longer visible
    }
  }

Usually the delegate either implements InventoryTagChanged, or implements InventoryTagFound (and sometimes InventoryTagSubsequentFinds).

Tag filtering

The delegate can filter which tags are kept track of via:

  public bool InventoryFilter(UgiEpc epc) {
    if (this tag should be ignored) {
      return true;
    } else {
      return false;
    }
  }

If this method returns true, the tag is ignored entirely; InventoryTagFound, InventoryTagSubsequentFinds and InventoryTagChanged are never called for it.

List of found tags

While inventory is running, the app can access the list of found tags via the tags property of the UgiInventory object. Usage is typically:

  foreach (UgiTag tag in Ugi.Singleton().ActiveInventory.Tags) {
    // do something with tag
  }
Tag Access (read, write, ...)

Methods in UgiInventory allow tag access for reading, writing and locking. All of these functions work similarly.

Tag programming (changing tag EPC)

While inventory is running, the app can program tags via:

  UgiEpc oldEpc = UgiEpc.FromString("35fffffff99c70a063405c48");
  UgiEpc newEpc = UgiEpc.FromString("35fffffff956734504747454");
    Ugi.Singleton().ActiveInventory.ProgramTag(oldEpc, newEpc
                    UgiInventory.NO_PASSWORD,
                    (UgiTag tag, UgiInventory.TagAccessReturnValues result) => {
      if (result == UgiInventory.TagAccessReturnValues.Ok) {
        // tag programmed successfully
      } else {
        // tag programming was unsuccessful
      }
    });

Sometime after the ProgramTag method is called, the completion will be with the success or failure of the programming.

Grokker Configuration
Inventory

The UgiRfidConfiguration object holds the configuration to be used during inventory. Several pre-defined types can be used, defined in the UgiInventoryTypes enum. Values that can be configured include:

  • Power level
    Initial, minimum and maximum power levels can be set. If a range is provided (minimum != maximum), then the power level is varied over this range.
  • Q value
    Initial, minimum and maximum Q values can be set. If a range is provided (minimum != maximum), then the Q value is dynamically adjusted based on the number of tags in range
  • Session
    The inventory session (0, 1, 2, or 3)
  • Power level and sensitivity for writing tags
    The power level and sensitivity used when writing data to tags
  • Sensitivity
    The reader sensitivity

For more detailed information about RFID and configuration, see RFID Configuration

SDK Internet Usage

The SDK uses the Internet in a few cases, see SDK Internet Usage for details.

Localization

The SDK contains user visible strings for updating firmware, setting region of the world, and UI building blocks. It is localized into Spanish, French and German. If you are interested in localizations to other languages, contact us.