Building Connected Things with Windows 10 IoT and Microsoft Azure

Lab 05: Sending Device-to-Cloud (D2C) Messages

In this lab, you will send messages from the Thingy you have built to the cloud.

Table of Contents

Bill of Materials

What you will need:

  1. The ThingLabs Thingy™ created in the ‘ThingLabs Thingy’ lab.
  2. The Visual Studio Project for the Thingy created in the ‘ThingLabs Thingy’ lab.

Add the Azure IoT SDK to Your Project

In a previous lab, you built the ThingLabs Thingy™ for Windows 10 IoT Core. Now it’s time to add the I to your IoT solution. In this lab, you will send messages from the Thingy to the Microsoft Azure IoT Hub you created in the previous lab. There is an Azure IoT SDK for C# that enables all of the connection and communications with your Azure IoT Hub. The SDK is available as a NuGet package that you can easily add to your project.

  1. Open the Thingy project.
  2. Click on the Project menu and select Manage NuGet Packages.
  3. Use the search field to search for Microsoft.Azure.Devices.Client.
  4. Click on the Install button to install the package.

IoTNightlight Project

Define the Azure IoT SDK Components

To use the Azure IoT SDK you will modify the StartupTask.cs file in the Thingy project. You will add the definitions for the SDK components, such as DeviceClient (the client-side agent), the Message, and the connection string for your specific device.

  1. Open the StartupTask.cs file.
  2. Add the following to the using statements where you have added the other using statements (e.g. using GrovePi;).
using System.Threading.Tasks;
using Microsoft.Azure.Devices.Client;

Next, define a variable to represent the DeviceClient.

  1. Locate the section in the StartupTask.cs file indicated with the comment /**** Constants and Variables ****/
  2. Add the following variable definition:
// Define the Azure IoT SDK DeviceClient instance
private DeviceClient deviceClient;
// Create a timer to control the rate of sending messages to Azure.
private ThreadPoolTimer messageTimer;

The last step of the previous lab was to copy the device-specific connection string for that device. If the connection string is still in your copy buffer, simply paste it into the IOT_HUB_CONN_STRING field in Step 2 below. If the connection string is no longer in your copy buffer, you can get the device-specific connection string again by selecting it in the DeviceExplorer Devices list by right-clicking and selecting Copy connection string for selected device.

Get the device-specific connection string

  1. In the same section of the StartupTask.cs file (indicated with the comment /**** Constants and Variables ****/) and add the code below, making changes as indicated here:
  2. Use the device-specific connection string as the value of IOT_HUB_CONN_STRING.
  3. Use the name of the device you created in Azure IoT Hub as the IOT_HUB_DEVICE.
  4. Use any string value you’d like as the IOT_HUB_DEVICE_LOCATION.
// Use the device specific connection string here
private const string IOT_HUB_CONN_STRING = "YOUR DEVICE SPECIFIC CONNECTION STRING GOES HERE";
// Use the name of your Azure IoT device here - this should be the same as the name in the connections string
private const string IOT_HUB_DEVICE = "YOUR DEVICE NAME GOES HERE";
// Provide a short description of the location of the device, such as 'Home Office' or 'Garage'
private const string IOT_HUB_DEVICE_LOCATION = "YOUR DEVICE LOCATION GOES HERE";

Send Ambient Light Measurements Once per Second

The Thingy enables you to collect multiple sensor measurements (ambient light, sound, and LED state which is controlled by a button press).

  1. In the Run(IBackgroundTaskInstance taskInstance) locate the code that creates the deferral instance (it should be the first line of code in that method).
  2. Immediately after the creation of the deferral object, add the following (the deferral code is added here for reference):
// Get the deferral instance
deferral = taskInstance.GetDeferral();

// Instantiate the Azure device client
deviceClient = DeviceClient.CreateFromConnectionString(IOT_HUB_CONN_STRING);
  1. Still in the Run(IBackgroundTaskInstance taskInstance) method, add the following code after the timer = ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick, TimeSpan.FromMilliseconds(200)); code.
// Send messages to Azure IoT Hub every one-second
// Start a timer to send messages to Azure once per second
messageTimer = ThreadPoolTimer.CreatePeriodicTimer(MessageTimer_Tick, TimeSpan.FromSeconds(1));

Throughout this lab you will use a feature in Visual Studio called light bulbs. Light bulbs are a new productivity feature in Visual Studio 2015. They are icons that appear in the Visual Studio editor and that you can click to perform quick actions including refactoring fixing errors. Light bulbs bring error-fixing and refactoring assistance into a single focal point, often right on the line where you are typing. As you write the code in this lab you will add calls to methods that don’t yet exist. The editor will indicate this to you by putting a red “squiggle” underline beneath the method call. When you hover over the offending code a light bulb will appear and you can expand it to see options for generating the missing method.

Use the Visual Studio light bulb feature to create the MessageTimer_Tick() event handler.

private void MessageTimer_Tick(ThreadPoolTimer timer)
{
    SendMessageToIoTHubAsync("ambientLight", actualAmbientLight);
}

Each time the MessageTimer ticks this event handler will invoke the SendMessageToIoTHubAsync() method. Use the Visual Studio light bulb feature to create the SendMessageToIoTHubAsync() method. Modify the method signature to mark it as an async method.

private async Task SendMessageToIoTHubAsync(string sensorType, int sensorState)
{
    try
    {
        var payload = "{" +
            "\"deviceId\":\"" + IOT_HUB_DEVICE + "\", " +
            "\"location\":\"" + IOT_HUB_DEVICE_LOCATION + "\", " +
            "\"sensorType\":\"" + sensorType + "\", " +
            "\"sensorState\":" + sensorState + ", " +
            "\"localTimestamp\":\"" + DateTime.Now.ToLocalTime() + "\"" +
            "}";

        var msg = new Message(Encoding.UTF8.GetBytes(payload));
        
        System.Diagnostics.Debug.WriteLine("\t{0}> Sending message: [{1}]", DateTime.Now.ToLocalTime(), payload);

        await deviceClient.SendEventAsync(msg);
    }
    catch (Exception ex)
    {
        System.Diagnostics.Debug.WriteLine("!!!! " + ex.Message);
    }
}

With this method, you construct a JSON message payload once every second for the ambient light measurement and send it to your Azure IoT Hub. The communication with the Azure IoT Hub is managed by the deviceClient object from the Microsoft.Azure.Devices.Client namespace.

Run the Application

Now you can run the application on your Raspberry Pi 2 and you will see the log of messages being sent to Azure IoT Hub at a rate of once per second.

Send Messages Based on Button Presses

For the ambient light measurement, you are sending a message once per second regardless of whether the light has changed. For the button, we’ll send a message based on an explicit state change (i.e. a button press event or release event).

  1. Locate the Timer_Tick method (the one from the previous lab that is used to collect sensor data).
  2. Modify the Timer_Tick method as follows:
private void Timer_Tick(ThreadPoolTimer timer)
{
    try {
        // ... code omitted for simplicity of this example
           
        // Check the button state
        if (button.CurrentState != buttonState)
        {
            // Capture the button state
            buttonState = button.CurrentState;
            // Change the state of the blue LED
            blueLed.ChangeState(buttonState);
            buzzer.ChangeState(buttonState);
            
            // Send a message to Azure indicating the state change
            SendMessageToIoTHubAsync("led", (int)buttonState);
        }
        
        // ... the rest of the method doesn't change and is omitted here       

If you want to compare your code with the master lab code, you can find it in the ThingLabs - Thingy4Windows Github repo here.

Run the Application and Get Pushy

Run your application again. Once you see the ambient light messages being sent, push the button a few times. You should see LED state messages go by. (You’ll also hear an annoying sound from the buzzer.)

Monitor the Messages Being Received by the Azure IoT Hub

Using the Device Explorer utility for Windows you installed in the previous lab, you can monitor the messages being received in Azure IoT Hub.

  1. Open the Data tab.
  2. Select the device from the drop-down list.
  3. Click Monitor to begin monitoring messages as they come into your Azure IoT Hub.

Conclusion & Next Steps

Congratulations! In this lab, you updated the Thingy application to send messages to Azure IoT Hub. The core concepts you’ve learned are:

  1. Using the Azure IoT SDK to connect to Azure and send device-to-cloud (D2C) messages.
  2. Sending messages as a continuous stream (e.g. once per second from a continuously measuring sensor).
  3. Sending messages based on events (e.g. exceeding measurement thresholds or explicit events like a button push).

At this point, nothing interesting is happening in the cloud with that data you are sending to Azure. It is simply being persisted for a default amount of time (1-day) and then being dropped. In the next lab, you will create a web application to visualize the data.

Go to ‘Lab 06: Storing and Displaying IoT Data’ ›