April 2016

Volume 31 Number 4

[Internet of Things]

Develop an Azure-Connected IoT Solution in Visual Studio with C++

By Marc Goodner | April 2016

The Internet of Things (IoT) is everywhere nowadays. The IoT is many things, but it can most simply be understood as sensor data that’s collected to the cloud for further processing. This manifests itself in many different types of devices deployed to collect that sensor data; rich cloud services for ingesting that data at scale; Big Data analytics and machine learning for processing and acting on that data; and rich reporting and client-side apps for gaining insights from this data.

So how do you get started with IoT? You need a device, a cloud and the tools to write and deploy your software solution to each.

In this article I’m going to walk you through connecting a device to Azure IoT using C++ project templates in Visual Studio, which cover the most common devices. You’ll learn how to stand up an Azure IoT Hub to ingest your device data, and learn about the related services that can act on that data. Azure IoT services offer a huge degree of flexibility, both because they’re agnostic to the programming language you use on the device itself and because, through the Azure IoT device Client SDKs, they support an ever-growing number of languages and devices. In this article I’m going to focus on C++ because of the broad range of device support it offers—from the smallest, most power-efficient microcontrollers to devices that run full OSes such as Linux or Windows IoT—and because of the control it affords developers over lower-level device functionality. Even if you’re not a C++ developer you’ll learn enough to be able to deploy a simple application to a network-connected device and get data to Azure.

The scenario for this article is a simple one—collecting light-sensor data from a device into Azure. The goal isn’t to complete an end-to-end solution, but to focus on the fundamentals—how to collect data and verify it’s getting to the cloud. I’ll show how this data can be used within other Azure services and how you can deploy those services within your Azure subscription. For more information on the IoT, visit aka.ms/iotmsdnb16, where you’ll also find links to tools discussed in this article, additional documentation, many more samples and a complete end-to-end IoT application called Connect the Dots, which you can easily deploy into your Azure subscription and to which you can connect your devices.

First, I’ll set up the Azure IoT Hub, then write some code in Visual Studio to send test data to the Azure back end. Then I’ll do the same with real data from a variety of devices, and conclude with a discussion of Azure services you can use with the sensor data you collect.

Azure IoT Suite and Azure IoT Hub

For the cloud part of the IoT solution, Azure offers several services, including Azure IoT Hub and a bundle called Azure IoT Suite that reduces the up-front work and provides scalability in the longer term. Azure IoT Hub is the connection point for devices and is optimized to support the ingestion of large amounts of data, an essential capability given that deployments of millions of devices sending continual updates are not uncommon. You can choose a free edition that supports up to 8,000 messages per day (ideal for prototyping or personal projects), or either of two paid editions, one for smaller projects that accepts up to 400,000 messages a day and one scaled for larger implementations that supports up to 6 million messages a day. Depending on the scale of the IoT solution you’re building, you can deploy as many IoT hubs as you need to support the message volume your solution requires. IoT Hub also provides capabilities for device management and provisioning tailored to the needs of IoT deployments, as well as a range of open source SDKs for developing the device connectivity and the service management parts of your solution. 

Azure IoT Suite offers a growing collection of full end-to-end IoT solutions, preconfigured to simplify the development process. These include solutions for common IoT projects such as predictive maintenance, using sensor data from machines to anticipate problems before they occur. Azure IoT Suite solutions comprise a set of preconfigured Azure IoT services, including Azure IoT Hub, that can be provisioned into your Azure subscription so you can quickly deploy an IoT solution and then customize it to fit the unique needs of your project.

Whether you go with an Azure IoT Suite preconfigured solution or deploy your own set of Azure services, you’ll be using the same Azure IoT SDKs to develop the device side of your application. In the sample that follows, I’ll manually set up some simple services behind an Azure IoT Hub instance to illustrate a simple IoT end-to-end solution.

Connecting to Azure IoT Hub

The first step is to set up your Azure IoT Hub. If you don’t have an Azure subscription, you can create a free trial subscription. When that’s done, log into the Azure Portal and select New | Internet of Things | Azure IoT Hub, complete the options and select New. Select your pricing tier (you can deploy only one instance of the free tier of IoT Hub per subscription), complete the additional prompts and select Create (see Figure 1).

Creating a New Azure IoT Hub
Figure 1 Creating a New Azure IoT Hub

Next, make sure you have Visual Studio 2015 Community Edition or higher with the C++ tools installed and properly configured. You’ll need to have the extensions for Visual C++ for Linux Development, Visual C++ for IoT Development and Azure IoT Hub Connected Service installed, as well as the Windows IoT Core templates if you plan to target a Windows IoT device. You can find these extensions on the Visual Studio Gallery or install them from within Visual Studio from the Tools | Extensions and Updates menu. Likewise, the examples for Arduino and mbed use PlatformIO to enable the compilers for those boards, which you can get at platformio.org.

Now, create a project to connect to your IoT Hub. There are many samples in the Azure IoT SDK that cover this code, each focused on a specific protocol or device. The easiest way to get this code is to install the Azure IoT Hub Connected Service extension, which currently supports C# and C++ projects. I want to quickly prototype my code before involving a device so I’m going to do this on Windows. After installing the extension, create a new Win32 project under Visual C++.

In your project, right-click on References and choose Add Connected Service. In the dialog that comes up, choose Azure IoT Hub Connected Service and select Configure (see Figure 2).

Using the Azure IoT Hub Connected Service Extension
Figure 2 Using the Azure IoT Hub Connected Service Extension

Sign in with your Azure account and you’ll see your IoT Hub. Select it and choose Add. This brings up a list of existing devices if you’ve already added any devices to your IoT Hub; if not, it will be blank. Choose New Device and pick a name—let’s call it ThingOne. Wait for it to appear and select it. This pulls down a NuGet package with the libraries you need and generates a new file, azure_iot_hub.cpp and corresponding header azure_iot_hub.h, which contains helper functions that encapsulate best practices for sending data to the Azure IoT Hub with the necessary connection string for the device you chose. Of course, you’ll need to modify this generated code to handle the messages you want to send and receive. For now, we’ll send the default message. Add the new header reference to your console application code and place a call to the send_device_to_cloud_message function in main. Your code should look like this:

#include "stdafx.h"
#include "azure_iot_hub.h"
int main()
{
  send_device_to_cloud_message();
  return 0;
}

Next, use the IoT Hub Explorer to verify your messages are going to your IoT Hub. This is a cross-platform CLI tool based on Node.js, so if it isn’t installed on your system you should install it now. Get the tool via npm:

npm install -g iothub-explorer@latest

Next, in your command prompt, start the IoT Hub Explorer to see data sent from your device into Azure IoT Hub. The necessary command with connection string and device name is in the comments of the azure_iot_hub.cpp file. To find this string on your own in the Azure Portal, select your IoT Hub, then choose the key icon on the Essentials bar and look in the Shared Access Policies panel that appears.

iothub-explorer [<connection-string>} monitor-events ThingOne

You’ll see a message that says events from your device are being monitored. Now switch back to Visual Studio and start debugging by hitting F5. You should see an event received in the console, “Hello Cloud.”

You may want to pause here to examine the generated code handling the connection to Azure. Within the send_device_to_cloud_message you’ll find an IoT client being created:

IOTHUB_CLIENT_HANDLE iothub_client_handle =
  IoTHubClient_CreateFromConnectionString(connection_string, AMQP_Protocol);

Note the AMQP_Protocol, which is the default, though other protocols like HTTP and MQTT can also be used here. You’ll also observe that error handling is provided around creating this client, and it is properly disposed. The message itself is sent just after successful creation of the client:

d::string message = "Hello, Cloud!";
IOTHUB_MESSAGE_HANDLE message_handle =
  IoTHubMessage_CreateFromByteArray((const unsigned char*)message.data(),
  message.size());

Again, you’ll see that error handling is provided, and a request is sent to the IoT Hub to confirm delivery of receipt. You can now make some minor modifications to send a message of your own.

When you move on to using actual sensors, you’re going to detect brightness using a photoresistor, also known as a Light Dependent Resistor or LDR, so let’s modify the code to send a message with a value appropriate for that scenario. In the header file azure_iot_hub.h, add an int as a parameter of the function call. When you’re done, the contents of the header should be as follows:

// Insert call to this function in your code:
void send_device_to_cloud_message(int);

In the function definition of send_device_to_cloud_message, change the value of message to use the sensor data rather than sending Hello World. Here’s an example of how you can do that in JSON format:

char msgText[1024];
sprintf_s(msgText, sizeof(msgText), "{\"ldrValue\":%d}", ldrValue);
std::string message = msgText;

For more complex JSON data, or other formats, you can use your favorite C++ library.

Now update your main function to pass some values as sensor data:

#include "stdafx.h"
#include "azure_iot_hub.h"
int main()
{
  int ldrValue = 500;  // value will be read from a sensor in later examples
  send_device_to_cloud_message(ldrValue);
  return 0;
}

With IoT Hub Explorer still running, watch the messages build and run your project. You’ll see a new event received, with JSON-­formatted data, { ldrValue: 500 }.

Congratulations! You now have an IoT cloud and some code ready to wire up to a device with sensors connected to it.

Devices and Sensors

For the actual sensors in this application, I’m going to use the Grove system from Seeed Studios. Grove offers a wide range of sensors with a common connector that interfaces with expansion boards connected to your device, avoiding the need for breadboards and soldering as you develop your prototype IoT solution. You can, of course, use any sensor you like, or none at all if you want to simulate sensor data within your device code. The specific Grove device I’m showing in the code samples here is a light sensor, in part for simplicity because it produces an analog output, so I don’t need to find and install a specific library, a process that can vary platform to platform. In all of the examples, the sensor is plugged into the connector labeled A0 on the Grove expansion board. If you don’t want to use a shield and are good with a breadboard, simply connect an LDR to the power and an analog input pin on your board.

For the device part of the solution, I’m going to cover three alternatives: Raspberry Pi, Arduino and mbed. There are many factors to take into account when choosing a device for your IoT project, and these three options cover a range of different scenarios. For smaller deployments, a variety of off-the-shelf devices can simplify the development process. However, for large deployments, these choices aren’t as cost-effective. (For a deployment of tens of thousands of devices, reducing hardware costs, even by as little as a dollar or two, can make a big difference.) If you’re just getting started learning about the IoT, simplicity of development probably trumps minimizing such costs, but for prototyping you’ll probably want to consider it. Basic setup of the devices isn’t covered here, but you’ll find pointers to materials online at aka.ms/iotmsdnb16. Figure 3 shows the devices and sensor discussed in this section.

From the Left, a Raspberry Pi 2 with a Grove Hat and Light Sensor Attached, an Arduino Yun, a Grove Base Shield, and the FRDM 64 mbed Board at Bottom
Figure 3 From the Left, a Raspberry Pi 2 with a Grove Hat and Light Sensor Attached, an Arduino Yun, a Grove Base Shield, and the FRDM 64 mbed Board at Bottom

At the time of this writing, the Azure IoT Hub Connected Service extension can only pull down the binary libraries for use on Windows. Microsoft is working to enable this for targeting other platforms, as well. That said, the code the extension generates does work across platforms. In the steps that follow, you’ll reuse the code generated earlier for handling messages to the Azure IoT Hub. Each device section is intended to stand on its own, so you can skip sections for devices you’re not interested in.

Raspberry Pi The Raspberry Pi is a single-board computer with an ARM processor and a GPU. It can run various flavors of Linux and the Raspberry Pi 2 also supports Windows 10 IoT. Raspberry Pi offers lots of flexibility—it’s a full computer and includes networking, USB, GPIO and HDMI (though it doesn’t support analog sensors), and thanks to a vibrant maker community, example projects abound and help is available online. That flexibility does come at a cost, though—a higher power draw compared to alternatives and limited options to customize. So if you’re prototyping a device that won’t have access to hardwired power or will be deployed in large numbers, you might want to start with another board.

For this article, I’m going to use a Raspberry Pi in conjunction with an expansion board for Grove connectors from Dexter Industries, which also adds analog support, and a light sensor connected to A0. I’m also going to use the recently launched new project system support for Linux (part of the Visual C++ for Linux Development extension), which lets you build and debug code on remote Linux machines. Go to File | New Project. Under Visual C++ | Cross Platform, select Console Application (Linux). This opens a help file that explains the new capabilities of this project type and tells how to add your remote Linux machine to the project. The instructions also cover acquisition of the Azure IoT libraries for Linux and some tips for setting up the Grove shield.

Copy the generated files from the first project into this project. Open the cpp file in the solution named after your project and add the reference to azure_iot_hub.h.  Now update the code in main to read the sensor data from the device continuously, as shown in Figure 4.

Figure 4 Reading Sensor Data Using a Raspberry Pi

#include "azure_iot_hub.h"
#include <unistd.h>
#include "grovepi.h"
int main()
{
  int ldrValue;
  while(1) {
    ldrValue = analogRead(0);
    send_device_to_cloud_message(ldrValue);
    sleep(5);
  }
  return 0;
}

Now you can run your application from within Visual Studio. It will copy your sources to the Pi in the location you specified, build and run them. As with any other code in Visual Studio, you can set breakpoints. Once the code runs, you’ll see an event received by the IoT Hub Explorer as with the simulated data, { ldrValue: 1013 }.

This support for Linux isn’t tied to the Raspberry Pi; it also works with other Linux-based devices like the Intel Edison, the BeagleBone or any remote Linux machine.

Windows 10 IoT Core on the Raspberry Pi 2 is another option. See windowsondevices.com for information on getting started. After the tools are installed, go to File | New Project, then look under Visual C++ Windows and select Blank App (Universal Windows). Add a reference to Windows IoT Extensions for the UWP to the project. At the time of writing, there are some additional steps required for UWP. Please see the comments in the generated file azure_iot_hub.cpp in case those are still required. In the application code of Main­Page.xaml.cpp, add the reference to the azure_iot_hub.h include file.

In the MainPage.xaml.h include file, add the following pri­vate declarations:

private:
  const int readPin = 4;
  Windows::Devices::Gpio::GpioPin ^pin_;

This code illustrates how to read directly from a GPIO pin using the UWP APIs. Please see aka.ms/iotmsdnb16 for updates regarding using the Grove Pi shield with C++. Update the function definition and implementation to pass the sensor values as a JSON object as in the earlier example.

Next, you’ll update the implementation of MainPage in MainPage.xaml.cpp, as follows:

MainPage::MainPage()
{
  int ldrValue;
  auto gpio = GpioController::GetDefault();
  pin_ = gpio->OpenPin(readPin);
  pinValue = (int) pin_->Read();
  send_device_to_cloud_message(ldrValue);
}

Make sure the Azure IoT Hub is listening for your device, then build and deploy. You’ll see the JSON messages with the value from your light sensor stream by. Debugging works just as you’d expect because the target device is another Windows machine. There’s no special configuration required when your target is a Windows IoT device.

Arduino The Arduino is found in more maker projects than probably any other board out there. As a result of its widespread appeal, many other providers have added support for their boards to the Arduino IDE. Among sensor manufacturers, the level of support is similarly high, with libraries that can easily be incorporated into the Arduino IDE. The boards themselves have common connectors that provide a variety of digital and analog inputs and outputs in a common form factor for expansion shields to be added, such as the Grove base shield. That form factor has been adopted by many other board providers. There are many Arduino/Genuino boards to choose from, ranging from low-power MCUs to powerful ARM chips, and a rich ecosystem of third-party boards is available. As an open source hardware platform, all the schematics are available, making this an excellent platform for use in larger deployments.

Not all Arduinos have networking built in, though, so you’ll want to either choose one that does or use an expansion shield that adds networking to your device. Attach a Grove base shield and plug the light sensor into the port labeled A0.

Basic Arduino projects are called sketches and comprise a folder containing a file of the same name ending in .ino. This file is just a C++ file. The Arduino IDE hides a lot of complexity of its default Wiring API libraries. There are many guides online that cover basic Arduino setup and usage; visit Arduino.cc or aka.ms/iotmsdnb16 if you need pointers to those. If you want the fuller functionality of Visual Studio but want to stay within the Arduino ecosystem and use the .ino format, Visual Micro provides an extension that brings most of the board and library management functions from the Arduino IDE directly into Visual Studio.

To use C++ directly rather than the .ino sketch format, make sure you’ve installed the Visual C++ for IoT Development extension and create a new project. Then, from Visual C++ | Cross Platform, select Blank Application (IoT) project. This opens a help file that explains the new capabilities of this project type. Refer to those instructions for how to add and configure your board within the project.

Refer to the readme in the project on initializing PlatformIO for use with the Arduino and importing the required Azure IoT libraries. Copy the azure_iot_hub.h file from the first exercise into the lib folder and the azure_iot_hub.cpp into the src folder:

#include "azure_iot_hub.h"
int lightSensorPin = 0;
int ldrValue;
void loop()
{
  ldrValue = analogRead(lightSensorPin);
  send_device_to_cloud_message(ldrValue);
  delay(2000);
}

Now you can build and deploy your code to the board. Make sure the Azure IoT Hub Explorer is running so you can see the messages being sent from the board. Debugging is supported, as well. Set up for this varies, so please see the help file that’s included in the project.

mbed The ARM mbed platform is another excellent choice. This is an OS for ARM-based microcontrollers that provides a common framework for development and is supported by a wide range of prototyping boards supplied by the many ARM silicon vendors. These vendors all have their own path to production of custom designs. For deployments at scale, mbed is an excellent place to start. At Microsoft, we’ve been working with boards from Freescale, Marvel, STMicro and others. The range of choice here, however, can also make it a little hard to know where to start, but the excellent community online at mbed.org can help. Be aware that you won’t find as many maker-style projects online for mbed as for Raspberry Pi or Arduino. Every ARM vendor who produces an mbed board has getting started guidance; I highly recommend you start there.

For this article, I’m going to use the Freescale Freedom K64F board because it has built-in Ethernet, which makes it a snap to get connected to the Internet. This board also has headers matching the Arduino so you can use the same Grove base shield for connecting your sensors. Attach the light sensor to the plug labeled A0.

Again, as with the Raspberry Pi and Arduino, I’m going to use the microcontroller support in Visual Studio. Make sure you’ve installed the Visual C++ for IoT Development extension and create a new project. Select Visual C++ | Cross Platform | Blank Application (IoT). This opens a help file that explains the new capabilities of this project type. Refer to those instructions for how to add and configure your board within the project.

I’m going to use PlatformIO as my build tool for this project. PlatformIO is a flexible system that supports many different microcontroller platforms. Please refer to the readme in the project on initializing PlatformIO for use with an mbed target and importing the required Azure IoT libraries. Copy the azure_iot_hub.h file from the first exercise into the lib folder and the azure_iot_hub.cpp into the src folder.

Update your program code as shown in Figure 5.

Figure 5 Reading Sensor Data Using MBed

#include "azure_iot_hub.h"
#include "mbed.h"
AnalogIn lightSensorPin(A0);
float ldrSensorValue;
int ldrValue
int main()
{  while(1) {
    ldrSensorValue = lightSensorPin.read();
    ldrValue = (int) (ldrSensorValue * 1000);
    send_device_to_cloud_message(ldrValue);
    delay(2000);
  }
}

Now you can build and deploy your code to the board. Make sure the Azure IoT Hub Explorer is running so you can see the messages being sent from the board. Debugging is supported, as well. Setting this up varies so please see the help file that’s included in the project.

Using Your Sensor Data in Azure Services

Now that you’ve gotten the sensor data flowing from your device to Azure, you can use it with any available Azure service. This is where the reference implementations in the Azure IoT Suite or the Connect the Dots project can help you see the possibilities and how things are connected together.

As an example, you can process real-time information coming in via IoT Hubs and use it as input to other services. A common pattern here is anomaly detection and notification. To configure this type of alert, you’d create a Stream Analytics service that takes as its input your IoT Hub. Next, you’d define an output for this job, for example to Storage Blob or PowerBI, and then define a query that parses data coming from the input, looking for values above a certain threshold, for example. Any matches would then be sent to the defined output (see Figure 6).

The Simplest Stream Analytics Job Ever
Figure 6 The Simplest Stream Analytics Job Ever

You could use the Storage Blob as an input to a logic app that would then send an SMS alert, or in the case of PowerBI it could be used in a near-real-time dashboard of changing conditions. Machine learning services also provide rich opportunities to unlock value from the vast amounts of sensor data that can be collected, either in real-time hot paths or by analyzing historical data. These are just a few examples. With all of the Azure services available to further process and report on your data, you can realize any of your IoT needs.

One thing to note is that IoT Hubs can be used anywhere you can use Event Hubs. If you find a service you’re trying to use doesn’t have an IoT Hub option, you’ll need to get the Event Hub compatible name. Go to your IoT Hub in the Azure Portal and select Messaging. Under Device to Cloud settings, you’ll see the Event Hub compatible name and endpoint.

Taking full advantage of IoT data always involves the use of multiple services. Azure Resource Manager (ARM) templates can help you manage that complexity. These templates, written in JSON, define Azure services for deployment, including the ordering of deployment, location, values to use, and so forth, and they allow you to quickly deploy a full set of services to create an IoT cloud back end. These templates are used within the IoT Suite for deploying solutions into specific Azure subscriptions. Because the templates are simple JSON files, you can also keep track of them in your version control system for use in future deployments, say moving from prototype to production deployment.

Your Future with IoT

You have a role to play in building the Internet of Things. If you haven’t already started down this path, hopefully this article has piqued your interest. If you’ve been hacking Arduinos and Raspberry Pi devices for years already, perhaps you’ll find value in the new Visual Studio C++ capabilities introduced here. If you aren’t a C++ developer, you may find that these new capabilities make C++ far more approachable.

There is much more to Azure IoT than I’ve presented here. I covered the basics to get you started, and provided pointers for you to go further. Do give it a try. I look forward to seeing what you build.

Remember to visit aka.ms/iotmsdnb16 for additional resources and to keep learning.


Marc Goodner is a program manager focused on IoT tooling on the Visual Studio team and an active participant in Microsoft’s Garage Maker Community. He appreciates a fine single malt.

Thanks to the following Microsoft technical experts for reviewing this article: Olivier Bloch and Artur Laksberg


Discuss this article in the MSDN Magazine forum