April 2016

Volume 31 Number 4

[Modern Apps]

Writing UWP Apps for the Internet of Things

By Frank La

One of the most-used phrases in the technology industry today is “the Internet of Things,” often abbreviated as IoT. The IoT promises to turn every device into a smart device by connecting it to the cloud. From the cloud, a device can provide a control surface and raw data. Cameras can be controlled remotely. Data can be collected and analyzed for patterns and insight.

While there have been many articles in MSDN Magazine on how to collect and analyze data from these devices, there hasn’t yet been any discussion from hardware or wiring perspectives. However, jumping in with both feet into IoT might require developers to acquire new skills such as electronics design, electricity and, in some cases, soldering. Developers, by nature, are quite comfortable writing code but might not feel quite so comfortable with the circuits and electrons underpinning everything in the virtual world. Many software developers might find themselves wondering what to do with solderless breadboards, jumper cables and resistors. This column will explain their purpose.

Of course, programmable devices have existed for many years. Writing code for these devices, however, often required extensive knowledge of proprietary toolsets and expensive prototyping hardware. The Raspberry Pi 2 Model B can run Windows 10 IoT Core, a special version of Windows 10. Windows 10 IoT Core is a free download from the Windows Dev Center IoT Web site at dev.windows.com/iot. Now that Windows 10 IoT Core runs on the Raspberry Pi 2, Universal Windows Platform (UWP) developers can leverage their existing code and skills.

In this column, I’ll create a UWP app that runs on the Raspberry Pi 2 and will flash an LED light based on the data from a weather API. I’ll introduce IoT concepts, the Raspberry Pi 2 Model B hardware and how to control it from C# code.

Project: Monitoring for Frost

As spring brings back warm weather, many eagerly await the chance to start gardening again. However, early spring in many areas can also bring a few cold weather snaps. Frost can seriously damage plants, so as a gardener, I want to know if cold weather is in the forecast. For this, I’ll display a message on the screen if the forecast low goes below 38 degrees Fahrenheit (3.3 degrees Celsius). The app will also rapidly flash an LED as an extra warning.

In addition to the software normally needed to write UWP apps, I’ll need to have some additional hardware. Naturally, I’ll need to have a Raspberry Pi 2 Model B on which to deploy my solution. I’ll also need a MicroSD card, an LED light, a 220 Ohm resistor, solderless breadboard, jumper wires, USB mouse and keyboard, and an HDMI monitor.

Raspberry Pi 2 Model B The Raspberry Pi 2 Model B is the computer onto which I’ll deploy my UWP app. The Raspberry Pi 2 contains 40 pins (see Figure 1), some of which are General Purpose input/output (GPIO) pins. Using code, I’ll be able to manipulate or read the state of these pins. Each pin has one of two values: high or low—high for higher voltage and low for lower voltage. This lets me turn the LED light on or off.

Raspbery Pi 2 Model B Pinout Diagram
Figure 1 Raspbery Pi 2 Model B Pinout Diagram

MicroSD Card The MicroSD card acts at the Raspberry Pi 2 hard drive. This is where the device will find its boot files and OS. It’s also where the UWP app, once deployed, will reside. I could get away with SD cards as small as 4GB, but it’s recommended to have 8GB. Naturally, the project requirements determine the size of the card needed. If, for example, I needed to store large amounts of sensor data locally before uploading, then I’d need a larger SD card to support a larger local file store.

Solderless Breadboard and Jumper Wires In order to connect components to the Raspberry Pi 2, I’ll need to create a path for electrons to follow from the Raspberry Pi 2 through my components and back to the Raspberry Pi 2. This is known as a circuit. While I could use any number of ways to connect the parts together, the fastest and easiest way is the solderless breadboard. As the name implies, I won’t need to solder components together to create the circuit. I’ll use jumper wires to make the connections. The type of solderless breadboard I use for this project has 30 rows and 10 columns of sockets. Note that the columns have two groupings of five: “a through e” and “f through j.” Each hole is connected electrically to every other hole in its row and column group. The reason why will become apparent shortly.

LED Light and Resistor In this project, I’ll connect the LED light to the Raspberry Pi 2 board. The pins on the Raspberry Pi 2 operate at 5 volts. The LED light, however, will burn out at this voltage. The resister will reduce the extra energy to make the circuit safe for the LED light.

Ethernet Cable, USB Mouse and Keyboard, and HDMI Monitor The Raspberry Pi 2 Model B has four USB ports, an Ethernet jack and HDMI output, among other connectors. Once the UWP app is running on the device, I can interact with it very much the same way as if it were on a PC or tablet because I have a display and will be able to enter a ZIP code to pull down the forecast for a specific area.

Putting Windows onto the Raspberry Pi 2

To get started with Windows 10 IoT Core, I follow the directions at bit.ly/1O25Vxl. The first step is to download the Windows 10 IoT Core Tools at bit.ly/1GBq9XR. The Windows 10 IoT Core Tools contain utilities, Windows­IoTImageHelper and WindowsIoTWatcher, for working with IoT devices. WindowsIoTImageHelper provides a GUI to format an SD card with Windows IoT Core boot files. WindowsIoTWatcher is a utility that periodically scans the local network for Windows IoT Core devices. I’ll be using them shortly.

Connecting the Hardware

In order to start creating a solution for the IoT, I need to make a “thing” with which to work. This is the part of an IoT project that many developers find the most intimidating. Most developers are accustomed to moving bits via code, not necessarily wiring parts together for electrons to travel around. To keep this simple, I take the very basic blinking LED light project (bit.ly/1O25Vxl), but enhance it with real-time data from the Internet. The basic hardware supplies are the same: LED light, solderless breadboard, jumper cables and a 220 Ohm resistor.

The Raspberry Pi 2 Model B has a number of GPIO pins. The state of many pins can be manipulated by code. However, some of these pins have reserved functions and can’t be controlled by code. Fortunately, there are handy diagrams of the purpose of each pin. The diagram seen in Figure 1 is known as a “pinout” and provides a map of the circuit board’s interface.

Designing a Circuit

Basically, what I need to create is a circuit for electrons to flow through, as shown in Figure 2. The electrons start their journey at pin 1, labeled 3.3V PWR in Figure 1. This pin supplies 3.3 volts of power to the circuit and it’s this power that will light the LED. In fact, 3.3 volts is too much power for the LED light. To prevent it from burning out, I place a resistor on the circuit to absorb some of the electrical energy. Next on the circuit is GPIO 5, which, according to the pinout diagram, is physical pin 29. This pin, which can be controlled by code, makes the LED light “smart.” I can set the output voltage of this pin to either high (3.3 volts) or low (0 volts) and the LED light will be either on or off, respectively.

The Circuit Diagram
Figure 2 The Circuit Diagram

Building a Circuit

Now, it’s time to build the circuit shown in Figure 2. For this, I need to take the female end of one jumper cable and connect it to pin 29 on the Raspberry Pi 2. I then place the other end, the male end, into a slot on my solderless breadboard. I chose row 7, column e. Next, I take the LED light and place the shorter leg into the slot at row 7, column a, while placing the other, longer LED into the slot at row 8, column a. Now, I take the resistor and place one end into row 8, column c and the other into row 15, column c. Finally, I place the male end of the second jumper cable into the slot at row 15, column a, and connect the female end into pin 1 on the Raspberry Pi 2. Once all of this is done, I have something that looks like Figure 3.

The Completed Wiring with Raspberry Pi 2 in a Clear Plastic Case
Figure 3 The Completed Wiring with Raspberry Pi 2 in a Clear Plastic Case

Booting up the Device

After I have Windows IoT Core installed onto a MicroSD card, I insert the SD card into the Raspberry Pi 2. Then, I connect a network cable, USB Mouse and HDMI monitor, and plug in the Raspberry Pi 2. The device will boot up and, eventually, the screen shown in Figure 4 will pop up (I make note of the device name and the IP address).

The Default Information Screen on Windows IoT Core for Raspberry Pi 2
Figure 4 The Default Information Screen on Windows IoT Core for Raspberry Pi 2

Writing the Software

With the hardware setup complete, I can now work on the software portion of my IoT project. Creating an IoT project in Visual Studio is easy. It’s essentially the same as any other UWP project. As usual, I create my project by choosing File | New Project in Visual Studio 2015, and choosing Blank App (Universal Windows) as the template. I choose to call my project “WeatherBlink.” Once the project loads, I’ll need to add a reference to the Windows IoT Extensions for the UWP. I right-click on References in my solution in Solution Explorer and in the dialog box that follows, check the Windows IoT Extensions for the UWP under Extensions in the Universal Windows tree (see Figure 5). Finally, I click OK. 

Adding a Reference to Windows IoT Extensions for the UWP in Visual Studio 2015
Figure 5 Adding a Reference to Windows IoT Extensions for the UWP in Visual Studio 2015

Now that I have the correct reference added to my project, I’ll add the following using statement to the top of the MainPage.xaml.cs file:

using Windows.Devices.Gpio;

The Windows.Devices.Gpio namespace contains all the functionality I need to access the GPIO pins on the Raspberry Pi 2. Setting the state of a given pin is easy. For example, the following code sets the value of pin 5 to High:

var gpioController = GpioController.GetDefault();
gpioPin = gpioController.OpenPin(5);
  gpioPin.Write(GpioPinValue.High);

Reading a pin’s value is just as easy:

var currentPinValue = gpioPin.Read();

Because GPIO pins are resources that need to be shared across the app, it’s easier to manage them via class-scoped variables:

private GpioPin gpioPin;
private GpioPinValue gpioPinValue;

And initialize them in a common method:

private void InitializeGPIO()
{
  var gpioController = GpioController.GetDefault();
  gpioPin = gpioController.OpenPin(5);
  gpioPinValue = GpioPinValue.High;
  gpioPin.Write(gpioPinValue);
  gpioPin.SetDriveMode(GpioPinDriveMode.Output);
}

Creating the Simple UI

Because this is a UWP app, I have access to the full range of Windows 10 UWP interface controls. This means that my IoT can have a fully interactive interface with no additional effort on my part. Many IoT implementations are “headless,” meaning that they have no UI.

This project will have a simple UI that’ll display a message based on the weather forecast. If a keyboard and mouse are attached to the Raspberry Pi 2, end users will be able to enter a ZIP code and update the weather forecast information accordingly, as shown in Figure 6.

The UI of the WeatherBlink UWP App
Figure 6 The UI of the WeatherBlink UWP App

Making the Device Smart

In order to make my IoT device aware of the weather forecast, I need to pull down weather data from the Internet. Because this is a UWP app, I have all the libraries and tools accessible to me. I chose to get my weather data from openweathermap.org/api, which provides weather data for a given location in JSON format. All temperature results are given in Kelvin. Figure 7 shows my code for checking the weather and changing the rate of blinking based on the results. Typically, frost warnings are issued once the air temperature gets to around 38 degrees Fahrenheit (3.3 degrees Celsius). If there’s a chance of frost, I want the LED to blink fast to alert me that my garden is in imminent danger. Otherwise, I want the LED to blink slowly, to let me know that there is still power to the device. Because making a REST API call and parsing a JSON response in UWP is a well-covered topic, I’ve omitted that specific code for brevity.

Figure 7 Checking Weather and the Rate of Blinking

private async void LoadWeatherData()
{
  double minTempDouble = await GetMinTempForecast();
  // 38F/3.3C = 276.483 Kelvin
  if (minTempDouble <= 276.483)
  {
   Blink(500);
   txtStatus.Text = "Freeze Warning!"
  }
  else
  {
    Blink(2000);
    txtStatus.Text = "No freezing weather in forecast."
  }

The Blink method is straightforward—it sets the interval of a dispatch timer based on the parameter sent to it:

private void Blink(int interval)
{
  blinkingTimer = new DispatcherTimer();
  blinkingTimer.Interval =
    TimeSpan.FromMilliseconds(interval);
  blinkingTimer.Tick += BlinkingTimer_Tick;
}

The BlinkingTimer_Tick method is where the code to turn the LED on or off resides. It reads the state of the pin and then sets the state to its opposite value:

private void BlinkingTimer_Tick(
  object sender, object e)
{
  var currentPinValue = gpioPin.Read();
  if (currentPinValue == GpioPinValue.High)
  {
    gpioPin.Write(GpioPinValue.Low);
  }
  else
  {
    gpioPin.Write(GpioPinValue.High);
  }
}

The full source code is available at bit.ly/1PQyT12.

Deploying the App

Deploying the app to the Raspberry Pi 2 requires an initial setup on my PC. First, I’ll need to change my architecture to ARM and then under the dropdown next to the play icon, I’ll choose Remote Machine. The Remote Connections dialog (see Figure 8) appears, where I can either enter my device’s IP address manually or select from a list of auto-detected devices. In either case, authentication doesn’t need to be enabled. Last, I hit Select and now I can deploy my solution to the device.

Remote Connections Dialog
Figure 8 Remote Connections Dialog

Design Considerations

The world of IoT opens new opportunities and challenges for developers. When building an IoT device prototype, it’s important to factor in the runtime environment where it’ll be deployed. Will the device have ready access to power and networking? A home thermostat certainly will, but a weather station placed in a remote forest might not. Clearly, most of these challenges will dictate how I build my device, for example, adding a weatherproof container for outdoor scenarios. Will my solution be headless or require a UI? Some of these challenges will dictate how I would write code. For example, if my device transmits data over a 4G network then I need to factor in data transmission costs. I certainly would want to optimize the amount of data my device sends. As with any project that’s purely software, keeping the end-user requirements in mind is critical.

Wrapping Up

While controlling an LED light from code might not change the world, there are many other applications that could. Instead of relying on a weather forecast API, I could connect a temperature sensor to the Raspberry Pi 2 and place it in or near my garden. What about a device that could send an e-mail alert if it detected moisture in a particular part of my home? Imagine installing air quality sensors all over a major city or just in a neighborhood. Imagine placing weight sensors on roofs to determine if enough snow has fallen to determine if there’s a risk of collapse. The possibilities are endless.

Go and build great things!


Frank La Vigne is a technology evangelist on the Microsoft Technology and Civic Engagement team, where he helps users leverage technology in order to create a better community. He blogs regularly at FranksWorld.com and has a YouTube channel called Frank's World TV. (youtube.com/FranksWorldTV).

Thanks to the following technical experts for reviewing this article: Rachel Appel, Robert Bernstein, Andrew Hernandez


Discuss this article in the MSDN Magazine forum