September 2014

Volume 29 Number 9

Azure Insider : Soup to Nuts: From Raw Hardware to Cloud-Enabled Device

Bruno Terkaly | September 2014

Bruno Terkaly and Ricardo VillalobosThere’s a new gold rush happening and it’s not about precious metals. It’s about building innovative devices for consumers and connecting them to the cloud. New Microsoft CEO Satya Nadella said last March that devices are “really uninteresting without the cloud.”

This makes sense. If the device is collecting information through sensors or cameras, how and where will you analyze this data? After all, these low-end devices such as the Raspberry Pi have limited compute power and storage space. The cloud fills this void and goes further by helping with security, device management and so on. So this month, we want to roll up our sleeves from both a hardware and software perspective and learn what it takes to truly embrace this new computing paradigm.

The SmartDoor is the Internet of Things (IoT) product we’ll build from the ground up. We will eventually attach a doorbell, a camera and a Raspberry Pi computing device (see Figure 1). The idea is that someone arrives at your doorstep and rings your doorbell. Once they press the doorbell, the device automatically takes a photo. Then this photo is forwarded to a mobile device as a push notification message (see Figure 2). The message has a hyperlink to the image of the person standing at your doorstep. This invention was inspired by the need to know who is ringing your doorbell, even if you’re not home.

This Project Combines a Doorbell, Camera and a Raspberry Pi Device
Figure 1 This Project Combines a Doorbell, Camera and a Raspberry Pi Device

The Windows Phone Receiving the Push Notification
Figure 2 The Windows Phone Receiving the Push Notification

We’ll begin by illustrating exactly how to purchase and assemble the raw hardware. Once we’ve built the hardware, we’ll build software that runs on the device itself, as well as the software running in Microsoft Azure. This and future articles, though, will focus primarily on the requisite software.

We’ll need the code to be able to take a picture and upload it to Azure. From there, it will need to send a push notification to the appropriate mobile devices. This will indicate that someone has pressed the doorbell, and a photo of that person is available. Because of the ambitious nature of this project, we’ll provide a number of blog posts to support the work and provide the needed details.

Easy as Pi

We’ll address the code that runs on the Raspberry Pi device itself and some of the code that will run in the cloud—specifically within Azure Mobile Services. On the Raspberry Pi, we’ll install and run Mono, which is a free, open source project led by Xamarin that provides a Microsoft .NET Framework-compatible set of tools including a C# compiler and a CLR. 

The beauty of Mono is it lets you write .NET code compiled on Windows and run it unchanged on the Raspberry Pi. In our case, we’ll take a photo and upload it to Azure storage. In future articles, we’ll expand the code base to support the ability to send push notifications to a Windows Phone. To do this, we’ll have to leverage Push Notifications in the Azure Service Bus and write a Windows Store or Windows Phone app.

Getting the hardware together is straightforward because almost all of it is available in a single Raspberry Pi kit called the Canakit. For more details, go to canakit.com. The kit contains a few useful things to get to get our IoT device built, including a system board, A/C adapter, general purpose input/output (GPIO) breakout, breadboard, breadboard wires, assorted resisters and LEDs. You’ll also need an external monitor and keyboard and mouse so you can configure and test the Raspberry Pi. Besides the Canakit, you’ll need two more things—a regular doorbell and a Raspberry Pi-compatible camera, both of which are easy to find.

While the pile of hardware in Figure 3 might look intimidating, it’s actually quite simple to put together. If you can build a jigsaw puzzle, you can build a device like the SmartDoor. First, plug the camera module into the Raspberry Pi board. Take the camera out of the bag and attach the flex cable to the Raspberry Pi board. Go to bit.ly/1rk3vzk for more details on sending photos to the cloud.

The Raspberry Pi Canakit (Does Not Include the Camera)
Figure 3 The Raspberry Pi Canakit (Does Not Include the Camera)

We’ll present full installation of the doorbell itself in a later article, where we will solder it to the Raspberry Pi. For now, we’ll attach a breadboard, which is a test version of an electrical circuit plugged into a Raspberry Pi. We can use jumper cables and the breadboard to simulate the doorbell.

One of the core components is the GPIO breadboard. The GPIO is a hardware circuit with 26 separate pins (numbered left to right) that let you expand the system to interact with other devices. Generally, these pins let you connect such things as sensors, actuators, LEDs and so on. There are different types of pins, though. For example, there are two pins providing a power source for connected devices, specifically a 3.3 volt and a 5 volt. There’s also a 0 volt pin that acts as a ground, which is necessary to define a circuit. Pins labeled GPIO act as a simple on/off switch. If you wish to perform serial communications, you’ll find TX and RX pins (RS-232) for transmitting and receiving data. The software that runs on the device will need to communicate with these pins.

One of the complexities in dealing with these pins is there’s a mismatch between the physical pins versus the logical pins with which the software communicates. This has to do with the Broadcom chips in the Raspberry Pi device. This means if a signal goes to the pin GPIO 0, your software will actually need to read pin GPIO 17. It can be illogical, so be careful.

There are other crucial hardware components. Resistors play a key role controlling current flow and lowering voltage levels, so you don’t fry the Raspberry Pi or any other devices connected to it. You’ll also need single-core wire to connect the GPIO unit to the Raspberry PI.

Testing, Testing

Consequently, we’ll need to verify that we’ve built the hardware correctly. The easiest way to test the Raspberry Pi is to simply plug in the external monitor, keyboard, optional mouse and power supply. Once that’s done, plug in the power and the boot sequence for Linux should appear. The default username will be “pi” and the password will be “raspberry.” Go to bit.ly/1k8xBFn for more details on setting up a Raspberry Pi.

The Raspberry Pi needs additional software such as Mono to be able to run C# code. Before we can do anything on the device, we’ll need to update its Raspbian OS. Luckily, Pi comes with a pre-­installed version. All we need to do is issue a couple of commands in a console window to update the OS with the latest revision. Then we can install the Mono runtime from Xamarin and some trusted root certificates. These will let the device make HTTPS requests. All these steps are explained in the blog post at bit.ly/Unehrr.

The Software Side

There are two tiers we need to code against, the client tier (the Raspberry Pi device itself) and the service tier (Azure Storage and Azure Mobile Services). There are a variety of languages and back-end services from which to choose. We’ll run C# on the client and Node.js/JavaScript on the server. This can be a controversial choice because some folks feel two different languages complicate the implementation.

Our goal was to show diversity. In the context of Node.js, we believe the numerous libraries and packages found at npmjs.org could potentially make your server code much easier. Node.js often results in a much smaller code base because the libraries are so powerful. Less code in a second language is better than lots of code in the same language. The diagram in Figure 4 highlights the expected workflow, which boils down to three steps:

  1. The client requests a Shared Access Signature (SAS) token, which is presented as a URL.
  2. The Node.js application running within Azure Mobile Services will return a SAS URL.
  3. The client will use the SAS URL to upload the photo into Azure Storage as a blob.

High-Level Architectural Diagram of the SmartDoor Project
Figure 4 High-Level Architectural Diagram of the SmartDoor Project

We hosted our Node.js application within Azure Mobile Services. This provides a lot of pre-built support for mobile device clients, such as push notifications, CRUD storage integration, identity and the ability to build a custom API.

Focus on Service

We’ll start by building our service, because it will develop the client if there’s no service tier against which to code. There would be no way to actually run and test the client unless you have a fully functional back-end service. Azure Mobile Services will host our service API.

This custom API will be based on Node.js and the Express Web framework. Our client (Raspberry Pi) will use those services to request a SAS. Then the service will use that token to upload the photo it takes to Azure Storage. Using a SaS URL helps protect our Azure Storage account, because we won’t need to store the account credentials in the Raspberry Pi. 

We addressed additional security issues in a past article (msdn.microsoft.com/magazine/dn574801). SAS tokens are also good for another reason—they free the middle tier (Node.js API) from having to broker the transfer of files to storage from the client.

Provisioning Mobile and Storage

Provisioning Azure Mobile Services consists of just a few clicks in the Azure portal. The same is true for provisioning Azure Storage. As with anything that’s provisioned, you’ll need to think about URLs and the naming conventions you want to use for your cloud-based services. You also should consider which of the several global datacenters you’d like to use, making sure your storage account is in the same datacenter as Azure Mobile Services, so as to minimize latency and avoid data transfer costs. You can find more detailed steps for provisioning your Azure Mobile Services and Azure Storage account at bit.ly/WyQird.

Shared Access Signatures

As shown in Figure 4, the Raspberry Pi client will request an SAS token from Azure Mobile Services. It will do so by issuing a get request from an API we define within Azure Mobile Services. SAS tokens free the middle tier (Node.js API) from having to broker the transfer of files to storage from the client.

The code in Figure 5 is an excerpt of the Node.js running within Azure Mobile Services as an API service endpoint. The purpose is to respond to requests from Raspberry Pi clients that need an SAS. The Raspberry Pi will issue a “get” request against the endpoint hosted in Azure Mobile Services, passing in the application key, which is an identifier that uniquely represents our mobile service.

Figure 5 Node.js Code for the Microsoft Azure Mobile Services API

exports.get = function(request, response) {
  // These are part of "App Settings" in the configuration section
  // of your service. Shouldn't be hardcoded into this Node.js script.
  containerName = request.service.config.appSettings.PhotoContainerName;
    accountName = request.service.config.appSettings.AccountName;
    accountKey = request.service.config.appSettings.AccountKey;
  // Connect to the Blob service.
  blobService = azure.createBlobService(
    accountName,accountKey,accountName + '.blob.core.windows.net');
  createContainer();
  createPolicies();
  var sasResponse = GetSAS();
  return request.respond(201, sasResponse);
}

The application key represents a secure way to communicate with the specific Azure Mobile Service. The service will obtain this key from the portal, which the code running on the Raspberry Pi will use, so you should keep it handy. Then you can paste it into the client code. The client receives an SAS encapsulated within a URL the client can use in a later operation to upload a photo.

Now we’ll focus on some of the code that represents the server side Node.js application. There’s a powerful Node.js SDK tailored for Azure available at bit.ly/Unnikj. This code base provides a lot of support for other parts of the Azure platform, such as working with tables, queues, topics, notification hubs, core management and so on. You can find a tutorial on integrating Node.js and Azure Blob Storage at bit.ly/1nBEvBa.

For our purposes, the SAS the Node.JS application returns to the client is tied to the storage account we previously provisioned. As such, the Node.js application will need the storage account’s account name and management key.

Azure Mobile Services lets you externalize configuration settings from your Node.js application. It’s generally considered bad programming practice to hardcode account key settings directly in code. App settings let you set key-value pairs the service runtime can read. You can learn more about it at bit.ly/1pwGFRN.

Ultimately, the Node.js code will return a URL with the SAS the client can use to upload photos. Along with the SAS token, the Node.js app returns an HTTP status of 201. This means it has fulfilled that request and created a new resource (the SAS token).

You’ll find a more detailed walk-through that addresses Node.js, SAS URL and the app settings at bit.ly/WyQird.

Inside the Raspberry Pi Code

The hardware/software interface is actually quite straightforward. You can think of the client-side code as a giant state machine. It’s in a constant loop checking the status of the GPIO pins. As you can see from the code in Figure 6, we’re just checking to see if a pin is on or off, true or false.

Figure 6 Long-Polling Loop Interfacing with the Raspberry Pi GPIO to Control Behavior

while (true)
{
  // If pin 17 is off, we are ready.
  if (!s_Gpio.InputPin(FileGPIO.FileGPIO.enumPIN.gpio17))
  {
    showReady(true);
    // If pin 22 is true, indicate to the user that the system is busy,
    // take a photograph and then upload to the cloud.
    if (s_Gpio.InputPin(FileGPIO.FileGPIO.enumPIN.gpio22))
    {
      showReady(false);
      TakeAndSendPicture();
    }
  }
  else
  {
    // Not ready to take a photo yet.
    showReady(false);
    break;
  }
  // Pause for one-tenth of a second.
  System.Threading.Thread.Sleep(100);
}

There are two ways to check pin status. The first approach, and the one we’ve taken here, is to talk to the file system. By checking for specific files with specific values, we can determine if a pin is on or off. Another approach, which typically offers higher performance, is to check specific locations in memory for specific values. Although it’s slower to work with the file system, it’s considered safer. This approach leverages the built-in driver Linux provides.

Let’s address some of the code that will run on top of Mono on the Raspberry Pi using C#. The Raspberry Pi will perform four basic steps. First, it will respond to someone pressing the doorbell button. Second, based on the doorbell button being pressed, it will take a photo and save it to local storage. Third, it will request an SAS token it will then use to upload a photo. Fourth, it will upload the photo to Azure Storage as a blob. Although the code is written in C#, it’s all based on REST. This means any language or environment capable of HTTP can perform these four steps.

We can control the Raspberry Pi by communicating with the GPIO. There are only four points at which our application is going to use GPIO 2 for input and GPIO 1 for output. We’ll present some C# code to interface with these pins. Take a look at the main loop of the Raspberry Pi C# code in Figure 6. Pins 17 and 22 are used to test for device readiness and to take and upload a photo based on the doorbell button being pressed.

This infinite long-polling loop is constantly checking pin voltages. So the software knows something needs to be accomplished—like taking a photo. This loop runs at around 10hz as it polls the pin status. If you’re interested in learning more about benchmarking speed, go to bit.ly/1trFzt9.

Various languages operate at different speeds. For example, Python is fairly slow and you can’t use it in scenarios where speed is crucial. In this case, 10hz is fast enough to check if the doorbell switch has pulled pin 22 to Power when someone presses it.

Each of the three pins performs a different function. The first input, pin 17, must be connected to the Ground pin (which is interpreted by C# as false). If this isn’t configured this way, the program will exit. Pin 22 must be set to Power (which is interpreted as true). When pin 22 is true, the photo-taking process starts in TakeAndSend­Picture. The showReady method uses pin 4, an output pin, to show the program is ready to shoot and upload pictures by driving an LED.

The solution leverages conditional compilation symbols so the appropriate code runs on the Raspbian OS, versus the normal Windows/Desktop OS. The code in the solution has to be different because taking a picture under Raspbian OS is not an API call. It involves running an executable in its own process. Under Windows 8, on the other hand, you leverage the CaptureFileAsync API of CameraCaptureUI.

To take the photo, we call into the built-in raspistill executable as shown in Figure 7. This is already configured to snap a photo and save it as a JPEG. This lets you specify the filename, photo quality and the image size. Raspistill is started as a child process. While the photo is being taken, the code requests an SAS URL from the Azure Mobile Service. It then uploads the picture to Azure Blob Storage.

Figure 7 Taking a Photo and Uploading It to the Cloud

static void TakeAndSendPicture()
{
#if LINUX
  // Start photo-taking process. This will kick off the raspistill process.
  // We'll wait for it to exit after we get the photo URL.
  Process raspistill = new Process();
  raspistill.StartInfo = new ProcessStartInfo("/usr/bin/raspistill",
    "-n -q " + photoQuality +
    " -o /home/pi/Desktop/me.jpg -h 200 -w 200 -t 500")
    {
      UseShellExecute = false
    };
    raspistill.Start();
#endif
  // Get Photo URL while the picture is being taken.
  WebRequest photoRequest = WebRequest.Create(
    "https://raspberrypiservice.azure-mobile.net/api/getuploadblobsas?");
  photoRequest.Method = "GET";
  photoRequest.Headers.Add("X-ZUMO-APPLICATION", 
    "AIzNtpTdQLjORKJJhTrQWWRSHSnXcN78");
  PhotoResponse photoResp = null;
  using (var sbPhotoResponseStream = 
    photoRequest.GetResponse().GetResponseStream())
  {
    StreamReader sr = new StreamReader(sbPhotoResponseStream);
    string data = sr.ReadToEnd();
    photoResp = JsonConvert.DeserializeObject<PhotoResponse>(data);
  }
  Console.WriteLine("Pushing photo to SAS Url: " + photoResp.sasUrl);
  WebRequest putPhotoRequest = WebRequest.Create(photoResp.sasUrl);
  putPhotoRequest.Method = "PUT";
  putPhotoRequest.Headers.Add("x-ms-blob-type", "BlockBlob");
#if LINUX
  // Wait until the photo is taken.
  raspistill.WaitForExit();
  FileStream fs = new FileStream(@"/home/pi/Desktop/me.jpg", 
    FileMode.Open);
#else
  FileStream fs = new FileStream(@"testPhoto.jpg", FileMode.Open);
#endif
  using (fs)
  using (var reqStream = putPhotoRequest.GetRequestStream())
  {
    Console.WriteLine("Writing photo to blob...");
    fs.CopyTo(reqStream);
  }
  using (putPhotoRequest.GetResponse())
  {
  }
}

The Visual Studio solution is built to run on a Raspberry Pi, as well as on a traditional Windows OS. The solution leverages conditional compilation symbols so that the appropriate code runs on the Raspbian OS versus the normal Windows desktop OS. The code in the solution has to be different because taking a picture under Raspbian OS is platform-specific. To keep things simple, when compiled for Windows 8, we don’t take a photo. Instead, we upload an existing image (testPhoto.jpg) to the cloud.

The good news is you can share a lot of code between Windows and Raspbian. Everything from acquiring the SAS to uploading the photo is identical. So if it works in Windows, it will most likely work the same way on Raspbian. This dramatically simplifies client-based code development and testing. The Raspberry Pi is a constrained device, so it’s best to minimize the work done on the device itself.

Once the device takes a photo, you should be able to see it in two places. The first place is on the device itself, specifically in /home/pi/Desktop/me.jpg, where it was specified on the command line. Then, of course, the whole point is to upload the image to the Azure Storage Account container.

Wrapping Up

This is a solid starting point for building your own Internet of Things device. We’ve tried to address everything from procuring the hardware, assembly, installing software, writing software and testing functionality. We’ve also supplied many supporting blog posts. But this solution isn’t complete.

In the next article, we’ll address the way push notifications are sent to phones so you can view the photo of the person ringing the doorbell on a mobile device. We’ll introduce the notification service, which is part of the Azure Service Bus. We’ll also build a Windows Phone application capable of receiving push notifications from Azure. Finally, we’ll address additional storage mechanisms, such as using a MongoDB NoSQL database and interfacing with a face recognition back end. Stay tuned for more Internet of Things with Azure.


Bruno Terkaly is a developer evangelist for Microsoft. His depth of knowledge comes from years of experience in the field, writing code using a multitude of platforms, languages, frameworks, SDKs, libraries and APIs. He spends time writing code, blogging and giving live presentations on building cloud-based applications, specifically using the Microsoft Azure platform. You can read his blog at blogs.msdn.com/b/brunoterkaly.

Steven Edouard is a developer evangelist for Microsoft. Before that, he worked on the .NET runtime team as a software test engineer delivering products like the .NET Framework 4.5 and .NET Native Compilation. Now his passion resides in exciting people on the limitless potentials of cloud computing services through engaging technical demonstrations, online content and presentations.

Thanks to the following Microsoft technical experts for their review: Gil Isaacs and Brent Stineman
In an IT career that has lasted more than 20 years, Brent Stineman has touched on everything from mobile to the mainframe. Currently, he uses his passion for cloud computing and the Azure platform to help empower enterprise architects as an evangelist with the Technical Evangelism and Development (TED) group at Microsoft’s Developer Experience (DX) division. You can follow Brent at: twitter.com/brentCodeMonkey.

Gil Isaacs is a technical evangelist for the Microsoft Azure platform in the Developer Experience (DX) division.  His role is to help customers be successful more quickly as they evolve to cloud-based architectures.  Gil’s experience is based on years spent coding and helping customers solve problems across a heterogeneous mix of technologies.  Gil currently focuses on bringing Open Source technologies to Azure.  You can follow Gil at twitter.com/gilisaacs.