Note: 2/14/20

 

This blog has been updated for the recent SDK changes.  The sample project and these instructions have been updated to utilize the CMAKE build process and the repository has been updated to support connecting to the Azure IoT Hub/IoT Central using a Device Provisioning Service (DPS).

 

Note: 6/9/2020

The GitHub projects have been updated to support the VS Code development environment.  Note that when you first open the project in VS Code the CMake file generation will fail.  If you open the CMakeLists.txt file, add a space and save the file, then CMake will regenerate the build files and the process will succeed.  If anyone knows how to fix this issue, please add a comment and I'll get it corrected.

 

Introduction

 

Welcome to part 3 of the Avnet Azure Sphere Starter-Kit (Out of Box Demo).  In this follow-up blog, we'll walk through connecting the example Azure Sphere application to an IoT Central Application that we’ll create from scratch.

 

The Starter Kit is available for order here.

 

We've put together three different blogs to showcase the Avnet Azure Sphere Starter Kit and how it can be used for your next IoT project . . .

  • Blog #1: Simple non-connected demo
  • Blog #2: Hands-on connected demo using a generic IoT Hub and Time Series Insights
    • Must complete blog 1 demo before moving on to blog 2
    • Configures IoT Hub and Time Series Insights Azure resources
    • Manipulate the device twin
    • Visualize data using Time Series Insights
  • Blog #3: Hands-on, connected demo using IoT Central (this blog)
    • Must complete blog 1 before moving on to part 3
    • Walks the user though configuring a IoT Central Application to create a custom visualization and device control application
  • Advanced Blog: Hands-on, connected demo using IoT Central
    • Must complete blog 1 before moving on to the Advanced Blog
    • Adds OLED functionality to the Starter Kit
    • Walks through using a real-time Bare-Metal M4 application to read the on-board light sensor
    • Uses a IoT Central Template to quickly stand up a new IoT Central Application

Azure IoT Central

IoT Central is a Software-as-a-Service (SaaS) offering from Microsoft.  Microsoft has made it easy to connect IoT devices and display telemetry data from connected devices.  Additionally, there are some cloud to device (C2D) controls available.  IoT Central Applications are created on-line without any coding necessary; configuration is all driven from the web interface.  This document will walk the user through each step required to create an IoT Central application that interacts with Avnet’s Azure Sphere Reference Design Project.

I’ll make the assumption that you’ve completed the simplified non-connected example.  If not, please go back and complete that demohere. For the IoT Central demo the following prerequisites must be met.

 

  • Visual Studio 2019 and the Azure Sphere SDK are installed and confirmed working
  • You were able to run the non-connected example without any issues (link)
  • Your device is connected to a Wi-Fi access point and has access to the internet

 

IoT Central Application Features

Our application will have the following features

  • Display X, Y and Z axis g-force (gravitational force equivalent data label named GForce) measurements from the built in LSM6DSO accelerometer in a graph
  • Display X, Y and Z axis angular rate measurements from the built in LSM6DSO gyroscope
  • Display pressure reading from the built in LPS22HH device
  • Display event data generated when user buttons A or B are pressed
  • Allow the user to toggle the User RGB Red, Green, and Blue LEDs from the application
  • Allow the user to toggle the WLAN and APP LEDs from the application
  • Display the current firmware version running on the Starter Kit
  • Display the current connected Starter Kit Wi-Fi SSID
  • Display the Wi-Fi AP bssid
  • Display the current Wi-Fi frequency
  • Remotely halt the application using a direct method call

Implementation Steps

This blog will walk the reader through the following implementation steps

  • Create a custom IoT Central application
  • Create a device template
    • Create interfaces in the template
      • Sensor interface
      • Button interface
      • Wi-Fi information interface
      • LED interface
      • Command interface
    • Create views to visualize our data
      • LED remote control view
      • Device data view
  • Update our application to connect to IoT Central
  • Exercise the device

 

Create a IoT Central custom application

The first step is to create the application.  Follow this link to create a new custom IoT Central Application. 

 

You should see a screen similar to the one shown below:

  • Create a name for your application.  Note that this name must be unique across all of Azure since your application name will also be used for the URL.  If you provide a name that’s already taken, you’ll get an error message stating the issue.
  • Select the “Custom Application” option.  The other option is "Custom Application (legacy)"  The new IoT Central is much different, these instructions will not work with the legacy implementation.
  • Select the “Trial” option for a free 7-day trial.  You can also select the Pay-As-You-Go option; you’ll need an Azure account with a balance or a pay-as-you-go account associated credit card if you choose this option.  When the 7-day trial expires, you'll have the opportunity to convert your application to a paid account.
  • Fill in your contact information
  • Select your country/region
  • Click the “Create” Button

Your application will be provisioned on Azure and you’ll be taken to the main page of your application. 

Here you’ll see the landing page.  The first thing we need to do is to create a “Device Template,” so click on the Device templates tile.

 

Create a device template

A device template is where we’ll define all the information and interactions for our device.

  • Select the "IoT device" tile
    • Note that all the current certified IoT Plug and Play devices are also available from this page.  We're working to add our Starter Kit to this list.  If you select a Plug and Play device, then a default device template is created that already contains all the details for the Plug and Play device.
  • Click on the "Next: Customize" button at the bottom of the page

  • Select "Next: Review"


  • Click on the "Create" button to create and empty template

  • Name your template.  I selected "Avnet Starter Kit OOB Template"

 

  • Next you have the option of creating a custom template or importing a capability model (Optional)
    • If you like you can import my capability model by downloading the json file from here.
      • After you download the file, click on the "Import capability model" tile and select the file
      • I recommend you browse the rest of this section to understand how to add new data items to the application
      • You can skip to the section titled "Create Custom Views"
  • Click on the "Custom" tile

  • Next we'll create a custom interface
    • The interface is where we'll define all the telemetry data that our application is sending up
    • Best practice is to group like things into separate interfaces.  For example we'll create the following interfaces . . .
      • Sensors
      • Buttons
      • Wi-Fi information
      • Information
      • LEDs
      • Commands
  • Click on the "+ Add interface" link

  • Select the "Custom" tile

  • Rename the interface by selecting "Edit identity"
  • Type the new interface name into the "Display Name" field such as "S.K. Sensors"
  • Click on the "Save" button

 

Next we'll add all the sensor capabilities for our application

  • Click on the "+ Add capability" link to bring up the Capabilities interface

This is where we will define the sensor properties for this interface.  In this interface we can configure telemetry, device twins and remote method calls.  For the sensors we'll configure telemetry items.

For the first example we're going to add the X Axis g-Force telemetry item.  To do this we just need to fill out the form.

  • Display Name: The name of the telemetry item to add, enter "Acceleration X Axis"
  • Name: This is the “key” string of the {“key”: value} key pair telemetry data.  The sample Azure Sphere application uses “gX” for the X g-force component, so we enter “gX” in this field.
    • Note that the interface automatically transferred the "Display Name" string to this field for you.  You can change it if you need to.
    • Make sure you match the case of the "key"
  • Telemetry | Command | Property: Select "Telemetry"
    • Telemetry is used for, you guessed it telemetry data from the device
    • Command is used for commands or direct methods to the device
    • Property is used for Device Twin Properties
  • Semantic type: This is used to pre-select the data representation.  For example Acceleration, Pressure . . .
    • If you don't select a "Semantic" type you can enter custom units
    • Select "None"
  • Schema: Select "Double"
  • Units: Our data is in milli-g so ideally we would select “mg,” but this is not an option.  Select "None"
  • Display Unit: Type in "mg"
  • Comment: Add any comment you wish
  • Description: Any description you wish

 

We just defined a Telemetry item!  Your screen should look similar to mine . . .

At this point we can click the "Save" icon to save our work.

 

  • On your own, using the "+ Add capability" link add the following telemetry items

 

Display NameNameCapability TypeSemantic typeSchemaUnitDisplay unitCommentDescription

Acceleration X Axis

gXTelemetryNoneDoubleNonemg
Acceleration Y AxisgYTelemetryNoneDoubleNonemg
Acceleration Z AxisgZTelemetryNoneDoubleNonemg
Angular Rate X AxisaXTelemetryNoneDoubleNonemdps
Angular Rate Y AxisaYTelemetryNoneDoubleNonemdps
Angular Rate Z AxisaZTelemetryNoneDoubleNonemdps
PressurepressureTelemetryPressureDoubleNonehPa

 

  • Save your work by clicking on the "Save" link at the top of the form

 

I've rolled up all my Telemetry items, but your screen should look similar to the graphic below . . .

 

Add Button Interface

 

  • Add a new interface by clicking on the top level of the Template then "+ Add interface"

  • Using the same steps we used for creating the "Sensors" interface above, create the "Buttons" interface
    • Rename the interface "Buttons"
    • Add the following capabilities

 

The example application will send up button press events as telemetry.  Using the information in the table below, populate your "Buttons" interface with the button press events.

 

Display NameNameCapability TypeSemantic typeSchemaUnitDisplay unitCommentDescription

Button A Pressed

buttonATelemetryEvent

Integer

Button B PressedbuttonBTelemetryEventInteger

 

You should have the hang of this task by now.  Use the tables below to build our the rest or our interfaces

Add Wi-Fi Information interface

The example application will send up Wi-Fi information as properties (device twin reported properties).  Using the information in the table below, populate your "Wi-Fi Information" interface

Display name
NameCapability TypeSemantic typeSchemaWritableUnitDisplay UnitCommentDescription
SSIDssidPropertyNoneStringOffNone
FrequencyfreqPropertyNoneIntegerOffNoneMHz
BSSIDbssidPropertyNoneStringOffNone

 

Add Information interface

The example application will send up the application version string as a property (device twin reported properties).  Using the information in the table below, populate your "Information" interface

Display name
NameCapability TypeSemantic typeSchemaWritableUnitDisplay UnitCommentDescription
Application Version StringversionStringPropertyNoneStringOffNone

 

Add LED interface

The example application will operate using device twins to control the on-board LEDs.  Using the information in the table below, populate your "LEDs" interface

Display name
NameCapability TypeSemantic typeSchemaWritableUnitDisplay UnitCommentDescription
RGB LED (Red)userLedRedPropertyNoneBooleanOnNone
RGB LED (Green)userLedGreenPropertyNoneBooleanOnNone
RGB LED (Blue)userLedBluePropertyNoneBooleanOnNone
Application LEDappLedPropertyNoneBooleanOnNone
Wi-Fi LEDwifiLedPropertyNoneBooleanOnNone

 

Add Commands interface

The example application implements a direct method to stop the application from the cloud.  Using the information in the table below, populate your "Commands" interface

Display NameNameCapability TypeSemantic typeCommandCommentDescriptionRequestResponse

Halt Application

haltApplicationCommand

Synchronous

OffOff

 

That's it for the interfaces.  If you just filled all that in, good for you!  I learn by doing, and entering in all this information is tedious, but it helps me remember how to do things.  Important review all your inputs carefully.  Once you "Publish" your interfaces it's difficult to change them.  We don't need to "Publish" the interfaces yet, but you may want to review all the information while it's all fresh in your mind.

Create custom views

Views are collections of items from your template interfaces.  You can design views using your interfaces depending on what you want to present to the user.  For this example we'll create two simple views . . .

1. LED Remote Control

This view will contain controls that allow us to change the LEDs on the board.

2. Device Data

This view will graph the acceleration, angular rate and pressure data.  We'll also add some status data and a link to run the "Halt Application" direct method

LED Remote Control View

  • You should still be on your device template screen, if not click on the "Device templates" link in the left most pane of the IoT Central Application
  • Click on "Views"
  • Click on the "Editing device and cloud data" tile

  • The view form opens
  • Change your form name to "LED Remote Control"
  • Select "2 column layout"
  • Expand the "Properties" item
    • Note that you see all the interface items of type "Property" (device twin)
  • There are two ways to get items from the list into the view
    • Click the box next to each item you want to add and click the "Add section" button at the bottom of the interface (should that be "Add selection?")
    • Click and drag each item over with your mouse
  • Update your view to look like mine
  • Click on the "Save" link at the top of the interface

Device Data View

  • Create a new view by selecting the "Visualizing the device" tile

  • Build out the view to look like mine, or create your own
  • Hints
    • Try selecting multiple telemetry items (check boxes), then the "Add tile" link
    • Try dragging single items from the list to the view (Pressure)
    • You can resize tiles from the menu on the tile, or by dragging the corners
    • You can change properties of each tile by clicking on the gear icon on the tile (tile title for example)

  • One you're happy with your view, click on the "Save" link at the top of the interface

 

Publish your Device Template

The interfaces and views that we created will not be available to devices until we "Publish" the changes.  Once you're happy with everything, I recommend one more review of your interface items, click on the "Publish" link in the top right corner of the interface.

 

Configure DPS for our Application

The next thing we need to do is to configure the IoT Central application so that devices from our Azure Sphere Tenant are allowed to connect to our application. IoT Central uses a Device Provisioning Service (DPS) to provision devices. Remember in blog #2 we had to prove to the DPS that we owned the Azure Sphere Tenant, we need to complete a similar exercise here for the IoT Central application.

 

Download the public tenant CA certificate

 

If you completed blog #2, then you already have this certificate. If not, follow the instructions below.

 

  • Go back to your “Azure Sphere Developer Command Prompt” application
    • Start --> Azure Sphere --> Azure Sphere Developer Command Prompt
    • Make sure you’re logged into your tenant:
      • azsphere login
    • Copy and paste in the command:
      • azsphere ca download --output CAcertificate.cer
      • Note the output file must have the .cer extension

 

Upload the public tenant CA certificate to Azure IoT Central and generate a verification code

 

In your new IoT Central application

  • Select the Administration --> Device connection
  • Select the “Manage primary certificate” link under the “Certificates (X.509)” section
  • Select the Primary folder icon and browse to the tenant CA certificate you downloaded from your tenant.
    • Make sure the view filter is set to All files (*) if you don’t see your certificate.

 

Your certificate is uploaded and a notification is displayed stating that the certificate “Needs verification.”

 

  • The “Subject” and “Thumbprint” fields are automatically filled out from the details included from your certificate
  • Click on the icon to generate the “verification code
  • A “verification code is generated and displayed

 

Return to the Azure Sphere Developer Command Prompt application

  • Copy and paste the following command into the application, don’t execute the command yet, we need to get the validation code first
    • azsphere ca download-proof --output ValidationCertification.cer --verificationcode <code>

Back in your IoT Central Application

    • Copy the verification code, there’s a copy link to the right of the box

  • Back in the command window, replace the <code> text with your verification code and execute the command
  • Execute the command

The Azure Sphere Security Service generates the validation certificate and includes the verification code inside the certificate. Since AS3 generated this certificate using the private key, and we provided the public key to DPS, DPS can decrypt the validation certificate and confirm/verify that the validation code is correct.

 

  • Back in your IoT Central application, click on the Verify button at the bottom of the form
  • Upload the new Verification Certificate by browsing to the file you just downloaded from the tenant
  • The Primary Certificate window will update and show the status as Verified

 

That completes this task.  Now any devices from our tenant that try to connect to our IoT Central application with the proper DPS scope ID will automatically be provisioned to our application.

 

Bonus Material on IoT Central and digital device twins

When we looked at device twins in the IoT Hub example, we kept it simple.  Desired and Reported properties were represented a simple key: value pairs.  For example . . .

 

Device twins for the IoT Hub example

The format for digital twins is flexible.  As long as the data is valid JSON and all applications that use the digital twin data understand the format, it can be whatever you want.  IoT Central implements digital twins in a way to allow the application to provide user feedback when making changes from the settings tab.  The settings tab will display a status update under the slider to help the user see that the change was requested and that the change was acknowledged by the IoT device.  If you look at the device application code, you'll see that the only difference between the IoT Hub application and the IoT Central application is how we handle device twin messages.

 

The graphics below show some of the digital twin details for my device.  There are three things I want to point out.

  1. The desired property object is not a simple key: value pair.
  2. The reported properties for the static items in our implementation ARE simple key: value pairs.  See the ssid, freq, bssid, and versionString keys.
  3. The reported properties for the slider controls on our settings tab are objects with three different elements
    1. Value: The value for this item, in the capture the value is false
    2. Status: This field communicates to IoT central what happened when the device tried to make the requested change.  In this case we report "completed."  I've never found any documentation on this implementation, but I have tried to send "failed" and the interface reported the a status of "Item could not sync" or something similar.
    3. DesiredVersion: This represents the requested version that the reported status is responding to .  Each desired property will include an associated message version, this version is captured and echoed back in the reported response.

 

 

Configure our application to connect to  the IoT Central Application

We're going to use a tool called "ShowIoTCentralConfig.exe" to pull all the bits we need to populate our app_manifest.json file.  This utility is included in the repo along with the Avnet example code.

  • Create a "real" device in IoT Central
    • The ShowIoTCentralConfig tool will use some information that we provide to identify our specific IoT Central instance.  One piece of information that we need is an ID from a "real" device.
    • Open your IoT Central Application
    • Select Devices --> <Your device group> --> "+" to add a new device

    • Leave everything at the defaults
    • Verify that "Simulated" is "Off"
    • Click on the "Create" link

Find all the required information for our Azure Sphere app_manifest.json file

  • There are 4 pieces of information we need to provide for our application to connect to our IoT Central application
    • DPS Scope ID (This is case sensitive)
    • DPS Global Endpoint FQDN (This is case sensitive!)
    • IoT Hub FQDN (This is case sensitive)
    • Azure Sphere Tenant GUID
  • We can find three of the four easily, however the IoT Hub FQDN is buried deep in the IoT Central implementation.  Remember that for our Azure Sphere application to be able to talk to any external server, we need to provide the FQDN or IP address in the app_manifest.json file. 
  • Open a command line window, or use the Azure Sphere Command Prompt Preview CLI
  • Change directories to your repo/Tools directory
  • Run the "ShowIoTCentralConfig.exe" utility
    • When asked if you're using a Work/School account answer "N"
      • Don't hit enter after typing "N!"
    • There is a known issue with this utility pulling data from the new non-legacy IoT Central applications using the Work/School account
    • Follow the instructions from the utility to provide the "ID scope" (this is the DPS Scope ID),  Primary Saas Key, and a "real" device ID

  • The graphic below shows my ShowIoTCentralConfig.exe execution
  • After supplying the requested information, the utility responds with the details I need for my app_manifest.json file

Modify the Azure Sphere source code

Now let’s go back to Visual Studio.  If it’s not open, go ahead and launch the Visual Studio application and open the “AzureSphereHacksterTTC” project.  Visual Studio keeps a list of recent projects, your project should be found in that list.

Remember in the simple non-connected application we discussed the three different build configurations:

  1. No cloud connectivity.  This is the simplest configuration.  The application runs and you can monitor sensor data from the Visual Studio debug window.
  2. IoT Hub connectivity.  This configuration requires an Azure IoT Hub and an IoT Hub connection string.  Once we have the Hub configured and the application connecting to the IoT Hub, we’ll walk through how to provision a Time Series Insights (TSI) application to visualize the sensor data and control GPIOs on the board from the cloud.
  3. IoT Central connectivity.  This configuration leverages Microsoft’s IoT Central SaaS product.  IoT Central provides a simple interface that allows users to visualize telemetry and to control connected devices.

For this example we’ll enable the IoT Central configuration.

  • Open the build_options.h file
  • On line #5 remove the “//” comment characters to enable the #define IOT_CENTRAL_APPLICATION configuration.
  • If you completed blog #2, make sure to comment out line #8 that defines the IOT_HUB_APPLICATION.  If both of these are enabled, you'll see a build error stating the issue.

Updating the app_manifest.json file

Open the app_manifest.json file for this application. There are four items we need to include in order for our application to use DPS and connect to our IoT Central Application:

 

  • DPS Scope ID: See the output from the the "ShowIoTCentralConfig.exe" execution
  • AllowedConnections (2):
    • The DPS global device endpoint FQDN: See the output from the the "ShowIoTCentralConfig.exe" execution
    • The IoT Hub’s FQDN: See the output from the the "ShowIoTCentralConfig.exe" execution
  • DeviceAuthentication:
    • This is the GUID for your Azure Sphere Tenant. This is included so that this application will only work on devices claimed to our Azure Sphere Tenant. So if someone was able to get our application and side load it onto an Azure Sphere device, that device would not be able to connect to our Azure services, unless it’s in the same Azure Sphere Tenant.
    • From your "Azure Sphere Command Prompt Preview" CLI execute the command >azsphere tenant show-selected

My updated app_manifest.json file.  Note that each item is surrounded by ""s.

 

 

To review.  The modifications we made to the source code . . .

  • We enabled the IOT_CENTRAL_APPLICATION define in build_options.h
  • We added our DPS Scope ID to the "CmdArgs" line in the app_manifest.json file
  • We added our Global device endpoint string to the “AllowedConnection” entry in the app_manifest.json file
  • We added our hostname string to the “AllowedConnection” entry in the app_manifest.json file
  • We added our Azure Sphere Tenant GUID to the "DeviceAuthentication" entry in the app_manifest.jston file

We should be ready to build the IoT Hub configuration!

Build and run the application

To compile, link and load the application onto your Starter Kit, you just need to click on the “Remote GDB Debugger” button in the toolbar.

You’ll see the build process run and a popup box stating that Visual Studio is starting the application. If you look at the output window, you should see something similar to the text below.

Let's review this output . . .

AZURE_SPHERE_PROV_RESULT_OK

This output confirms that the DPS successfully provisioned our device into the IoT Central application (IoT Hub in the background)

Updating device twin:

This output is showing that the application is sending device twin updates.  You can see in the output that these updates are sent as JSON {key: value} pairs.

IOTHUB_CLIENT_CONNECTION_OK

This output shows that our device has connected to our IoT Central Application (IoT Hub).  If you don't see your device connect to the IoT Hub, please review the Troubleshooting Azure IoT Hub Connection Issues blog entry.

Sending telemetry:

This output shows the telemetry data we’re sending to Azure.  As with the device twin update message, we’re sending JSON key: value pairs. To send telemetry, you just need a valid JSON structure.  The IoT Hub will collect this data and simply pass it on to any services that subscribe to the IoT Hub. 

 

  Did you know?
  • Click Boards
    • There are over 650 different Click Boards available that can be used on the Avnet Starter Kit

 

IoT Central

Now that our application is running on the Avnet Starter Kit, let's open our IoT Central application.  The first thing we need to do is to find our device and associate it with our device group / template

  • Navigate to your IoT Central web site
  • Click on "Devices"
  • Click on "All Devices"
  • Select your device; your device is the one with the long ugly device name/ID.
    • Click on the selection box
    • Click on the Migrate link
    • Select your device group

Now you can open your device, see the data your board is sending and exercise the LEDs using your new LED Remote Control view.

Todo: Add more IoT Central content here

Review

 

That concludes the demo, what did we learn?

  • How to create a IoT Central application from scratch
  • How to configure our application to connect to the IoT Connect
  • How IoT Central uses JSON objects for device twin data
  • How to use IoT Central to view telemetry data
  • How to use IoT Central to change device settings

 

Avnet Azure Sphere Starter Kit

 

Remember that the Avnet Azure Sphere Starter can help you jump start your next IoT Project.  Azure Sphere is the easy button for IoT Security, and the Avnet Starter Kit makes it easy to connect hundreds of different sensors and I/O devices for your prototyping needs.  Prototype on your Starter Kit, then migrate your project to the Certified Azure Sphere Module in your final design.

 

Order your Starter Kit today: Link