Windows 10 IOT Core Beginners Walkthrough using Raspberry Pi 2 and the Fez Hat

Raspberry-Pi-2-Windows-10-IoT-Core

In this walkthrough you learn all about

1. Raspberry Pi 2 device with Windows 10 Iot Core
2. FEZ HAT sensor hat.
3. Azure IoT Hub

The walkthrough will guide you through using a Windows 10 Universal Application, the sensors get the raw data and format it into a JSON string. That string is then shuttled off to the Azure IoT Hub, where it gathers the data and you can communicate commands directly back to the device. This walkthrough will take approx. 90 mins to complete.

Setup

The following sections are intended to setup your environment to be able to create and run your solutions with Windows 10 IoT Core.

Setting up your Software

Your machine setup includes the following items already downloaded:

  • Windows 10 (build 10240) or better

  • Visual Studio 2015 or above – Community Edition is sufficient.

    NOTE: If you choose to install a different edition of VS 2015, make sure to do a Custom install and select the checkbox Universal Windows App Development Tools -> Tools and Windows SDK.

  • Windows IoT Core Project Templates. You can download them from here. Alternatively, the templates can be found by searching for Windows IoT Core Project Templates in the Visual Studio Gallery or directly from Visual Studio in the Extension and Updates dialog (Tools > Extensions and Updates > Online).

  • Make sure you’ve enabled developer mode in Windows 10 by following these instructions.

Download Azure Device Explorer
Setting up your Devices

For this project, you have the following items

To setup your devices perform the following steps: 

  1. Plug the GHI FEZ HAT into the Raspberry Pi 2.

    fezhat-connected-to-raspberri-pi-2

    The FEZ hat connected to the Raspberry Pi 2 device

  2. Get your Windows 10 IoT Core SD Card and insert into the micro SD card on the Raspberry Pi device.

  3. Download the Windows 10 IoT Core image as per the instructions on https://ms-iot.github.io/content/en-US/win10/RPI.htm and run the installer on your development PC. You already have Windows IoT core image on the SD card, you still need to follow this step to get the IoT Core Watcher on to your PC.

  4. Connect the Raspberry Pi to a power supply and use the Ethernet cable to connect your device and your development PC. You can do it by plugging in one end of the spare Ethernet cable to the extra Ethernet port on your PC, and the other end of the cable to the Ethernet port on your IoT Core device. (Do this using an on-board port or an auto-crossover USB->Ethernet interface.)

    windows-10-iot-core-fez-hat-hardware-setup

  5. Wait for the OS to boot.  Download the IOT Core Watcher find internet sharing.pdf and follow the instructions to setup internet sharing.

  6. Run the **Windows 10 IoT Core Watcher** Download the IOT Core Watcher utility in your development PC and copy your Raspberry Pi IP address by right-clicking on the detected device and selecting **Copy IP Address**.

           - Click the windows "**Start**" button

           - Type "**WindowsIoTCoreWatcher**" to pull it up in the search results

           - You may want to right click on the program name and select "**Pin to Start**" to pin it to your start screen for easy access

           - Press **Enter** to run it

           ![windows-iot-core-watcher](Images/windows-iot-core-watcher.png?raw=true)

    <If your device does not show up, follow the "GetIPAddressFromHostName.docx" document for instructions on gaining your IP from your unique device name on the bright label>

    windows-iot-core-watcher

  7. Launch an administrator PowerShell console on your local PC. The easiest way to do this is to type _powershell_ in the **Search the web and Windows** textbox near the Windows Start Menu. Windows will find **PowerShell** on your machine. Right-click the **Windows PowerShell** entry and select **Run as administrator**. The PS console will show.

  8. ![Running Powershell as Administrator](Images/running-powershell-as-administrator.png?raw=true)

  9. Launch an administrator PowerShell console on your local PC. The easiest way to do this is to type powershell in the Search the web and Windows textbox near the Windows Start Menu. Windows will find PowerShell on your machine. Right-click the Windows PowerShell entry and select Run as administrator. The PS console will show.

    Running Powershell as Administrator

  10. You may need to start the WinRM service on your desktop to enable remote connections. From the PS console type the following command:

    net start WinRM

  11. From the PS console, type the following command, substituting '<IP Address>' with the IP value copied in prev:

    Set-Item WSMan:\localhost\Client\TrustedHosts -Value <machine-name or IP Address>

  12. Type Y and press Enter to confirm the change.

  13. Now you can start a session with you Windows IoT Core device. From you administrator PS console, type:

    Enter-PSSession -ComputerName <IP Address> -Credential localhost\Administrator

  14. In the credential dialog enter the following default password: p@ssw0rd.

    Note: The connection process is not immediate and can take up to 30 seconds.

    If you successfully connected to the device, you should see the IP address of your device before the prompt.

    Connected to the Raspberry using PS

  15. Disconnect from the Powershell Session Exit-PSSession

Setting up your Azure Account
Creating an IoT Hub
  1. Enter the Azure portal, by browsing to https://portal.azure.com

  2. Create a new IoT Hub. To do this, click New in the jumpbar, then click Internet of Things, then click Azure IoT Hub.

    Creating a new IoT Hub

    Creating a new IoT Hub

  3. Configure the IoT hub with the desired information:

    • Enter a Name for the hub e.g. iot-sample,

    • Select a Pricing and scale tier (F1 Free tier is enough),

    • Create a new resource group, or select and existing one. For more information, see Using resource groups to manage your Azure resources.

    • Select the Region such as North Europe where the service will be located.

      new iot hub settings

      New IoT Hub Settings

  4. It can take a few minutes for the IoT hub to be created. Once it is ready, open the blade of the new IoT hub, take note of the URI and select the key icon at the top to access to the shared access policy settings:

    IoT hub shared access policies

  5. Select the Shared access policy called iothubowner, and take note of the Primary key and connection string in the right blade. You should copy these into a text file for future use.

    Get IoT Hub owner connection string

Registering your device

You must register your device in order to be able to send and receive information from the Azure IoT Hub. This is done by registering a Device Identity in the IoT Hub.

  1. Open the Device Explorer app (C:\Program Files (x86)\Microsoft\DeviceExplorer\DeviceExplorer.exe) and fill the IoT Hub Connection String field with the connection string of the IoT Hub you created in previous steps and click on Update.

    Configure Device Explorer

  2. Go to the Management tab and click on the Create button. The Create Device popup will be displayed. Fill the Device ID field with a new Id for your device (myFirstDevice for example) and click on Create:

    Creating a Device Identity

  3. Once the device identity is created, it will be displayed in the grid. Right click on the identity you just created, select Copy connection string for selected device and take note of the value copied to your clipboard, since it will be required to connect your device with the IoT Hub.

    Copying Device connection information

    Note: The device identities registration can be automated using the Azure IoT Hubs SDK. An example of how to do that can be found here.

Creating a Universal App

Now that the device is configured, you will see how to create an application to read the value of the FEZ HAT sensors, and then send those values to an Azure IoT Hub.

Read FEZ HAT sensors

In order to get the information out of the hat sensors, you will take advantage of the Developers' Guide that GHI Electronics published.

  1. Find the folder on your USB Stick called 'ghi_elect-windows-iot-183b64180b7c'and open the Microsoft Visual Studio Solution File

  2. After opening the solution you will see several projects. The Developers's Guide comes with examples of many of the shields provided by the company. Right-click the one named GHIElectronics.UAP.Examples.FEZHAT, and select Set as Startup Project.

    Set FEZ HAT examples project as default

    Setting the FEZ hat example as the default project

  3. Ensure that the target platform for the project is set to "ARM":

    arm-target-platform

  4. Build the solution to restore the NuGet packages, and make sure it builds:

    ghifezhat-build-solution

    ghifezhat-build-succeeded

    Note: Now you will inspect the sample code to see how it works. Bear in mind that this example is intended to show all the available features of the shield, while in this lab you will use just a couple of them (temperature and light sensors).

  5. Open the MainPage.xaml.cs file and locate the Setup method.

        1: private async void Setup()
        2: {
        3:     this.hat = await GIS.FEZHAT.CreateAsync();
        4:  
        5:     this.hat.S1.SetLimits(500, 2400, 0, 180);
        6:     this.hat.S2.SetLimits(500, 2400, 0, 180);
        7:  
        8:     this.timer = new DispatcherTimer();
        9:     this.timer.Interval = TimeSpan.FromMilliseconds(100);
       10:     this.timer.Tick += this.OnTick;
       11:     this.timer.Start();
       12: }
    

    WHAT DOES THIS CODE DO?: In the first line, the program creates an instance of the FEZ HAT driver and stores it in a local variable. The driver is used for interacting with the shield. Then, after setting the limits for the servos (not used in this lab), a new DispatchTimer is created. A timer is often used in projects of this kind to poll the state of the sensors and perform operations. In this case the OnTick method is called every 100 miliseconds. You can see this method below.

        1: private void OnTick(object sender, object e)
        2: {
        3:     double x, y, z;
        4:  
        5:     this.hat.GetAcceleration(out x, out y, out z);
        6:  
        7:     this.LightTextBox.Text = this.hat.GetLightLevel().ToString("P2", CultureInfo.InvariantCulture);
        8:     this.TempTextBox.Text = this.hat.GetTemperature().ToString("N2", CultureInfo.InvariantCulture);
        9:     this.AccelTextBox.Text = $"({x:N2}, {y:N2}, {z:N2})";
       10:     this.Button18TextBox.Text = this.hat.IsDIO18Pressed().ToString();
       11:     this.Button22TextBox.Text = this.hat.IsDIO22Pressed().ToString();
       12:     this.AnalogTextBox.Text = this.hat.ReadAnalog(GIS.FEZHAT.AnalogPin.Ain1).ToString("N2", CultureInfo.InvariantCulture);
       13:  
       14:     ...
       15: }
    

    This sample shows how to use the FEZ HAT to get data from the sensors.

  6. To deploy the application to the Raspberry Pi, the device has to be on the same network as the development computer. To run the program, select Remote device in the Debug Target dropdown list:

    Deploy to Remote machine

    Deploying the application to a Remote Machine

  7. If a remote machine has not been selected before, the Select Remote Connection screen will be displayed:

    Remote Connection

    Setting up the Remote Connection

  8. If the device is not auto-detected, the Raspberry Pi IP or name can be entered in the Address field. Otherwise, click the desired device. Change the Authentication Mode to Universal (Unencrypted Protocol) or none if unavaliable:

    Set Authentication mode to Universal

    Setting the Authentication Mode

  9. If you want to change the registered remote device later it can be done in the project Properties page. Right-click the project name (GHIElectronics.UAP.Examples.FEZHAT) and select Properties. In the project Properties' page, select the Debug tab and enter the new device name or IP in the Remote Machine field.

    Change Remote connection

    Changing the Remote Connection Settings

    Note: Clicking the Find button will display the Remote Connection screen.

  10. Click the debug button to start the deployment to the Raspberry Pi. The first deployment will take some time as the remote debug tools, frameworks, and your code all need to be deployed. This could take up to a couple of minutes to completely deploy. You can monitor the status in the Visual Studio "Output" window.

    debug-ghifezhat

  11. If the program is successfully deployed to the device, the current value of the different sensors will be displayed in the Visual Studio output window. The shield leds will also be turned on and off alternately. The Debug.Writeline code above will display sensor data in the "Output" window:

    ghifezhat-debug-output

Send telemetry data to the Azure IoT Hub

Now that you know how to read the FEZ HAT sensors data, you will send that information to an Azure IoT Hub. To do that, you will use an existing project located in the Code\WindowsIoTCorePi2FezHat-IoTHubs\Code\WindowsIoTCorePi2FezHat\Begin folder.

1.

  1. Open the Microsoft Visual Studio solution file located in the Code\WindowsIoTCorePi2FezHat-IoTHubs\Code\WindowsIoTCorePi2FezHat\Begin folder.

  2. Before running the application, you must set the Device connection information. Go to the MainPage method of the MainPage.xaml.cs file and replace IOT_CONNECTION_STRING with your device connection string, obtained in previous steps using the Device Explorer app:

        1: ctdHelper = new ConnectTheDotsHelper(iotDeviceConnectionString: "IOT_CONNECTION_STRING",
        2:     organization: "YOUR_ORGANIZATION_OR_SELF",
        3:     location: "YOUR_LOCATION",
        4:     sensorList: sensors);
    

    Copying Device connection information

    Note: An Organization/School and Location may also be provided. Those values will be part of the telemetry data message, and could be used to get a better classification of the data received.

  3. Before the app can be deployed you need to change the solution target platform, since the Raspberry Pi is based on the ARM architecture. To do that select ARM in the Solution Platform dropdown:

    Set Solution Platform

    Setting the Solution Platform

  4. Insert code for a sensor timer

    1. Instead of the Button_Click method (commented out in the code in green) find the comment "//ADD TIMER_TICK METHOD HERE" and add the code below:

          1: private void Timer_Tick(object sender, object e)
          2: {
          3:     ConnectTheDotsSensor sensor = ctdHelper.sensors.Find(item => item.measurename == "Temperature");
          4:     sensor.value = counter++;
          5:     ctdHelper.SendSensorData(sensor);
          6: }
      
    2. Now uncomment (remove the //) lines of code like below for the timer to be initiated:

          1: //Button_Click(null, null);
          2: var timer = new DispatcherTimer();
          3: timer.Interval = TimeSpan.FromMilliseconds(500);
          4: timer.Tick += Timer_Tick;
          5: timer.Start();
      

      Which will make the Timer tick twice a second.

  5. Before adding real sensor information you can run this code to see how the device connects to your Azure IoT Hub and sends information. Run the application.

    Debug Console output

    Debugging in the Output Window

  6. After the app has been successfully deployed, it can start sending messages to the IoT Hub.

    The information being sent can be monitored using the Device Explorer application. Run the application and go to the Data tab and select the name of the device you want to monitor (myFirstDevice in your case), then click on Monitor

    Monitoring messages sent

    Note: If the Device Explorer hub connection is not configured yet, you can follow the instructions explained in the Registering your device section

  7. Now remove the timer created in that flow before you continue. A new timer will be created in the next steps replacing the previous one. Remove the Timer_Tick method you created before and delete the following lines from the MainPage constructor

        1: var timer = new DispatcherTimer();
        2: timer.Interval = TimeSpan.FromMilliseconds(500);
        3: timer.Tick += Timer_Tick;
        4: timer.Start();
    
  8. Now that the device is connected to the Azure IoT Hub, add some real sensor information. First, you need to add a reference the FEZ HAT drivers. To do so, instead of manually adding the projects included in the GHI Developer's Guide, you will install the NuGet package that they provide. To do this, open the Package Manager Console (Tools/NuGet Package Manager/Package Manager Console) and execute the following command:

     PM> Install-Package GHIElectronics.UWP.Shields.FEZHAT
    

    Intalling GHI Electronics NuGet package

    Installing the FEZ hat Nuget package

  9. Add a reference to the FEZ HAT library namespace in the MainPage.xaml.cs file. Find all the 'using' statements of code at the top of the file and add the following line of code to the end of them:

        1: using GHIElectronics.UWP.Shields;
    
  10. Declare the variables that will hold the reference to the following objects, find the comment "//DECLARE VARIABLES HERE" and ad the code below:

    • hat: Of the type Shields.FEZHAT, will contain the fez hat driver object that you will use to communicate with the FEZ hat through the Raspberry Pi hardware.

    • telemetryTimer: of the type DispatchTimer, that will be used to poll the hat sensors at regular basis. For every tick of the timer the value of the sensors will be get and sent to Azure.

          1: FEZHAT hat;
          2: DispatcherTimer telemetryTimer;
      
  11. You will add the following method to initialize the objects used to handle the communication with the hat, find the comment "//ENTER SETUP HAT ASYNC METHOD HERE" and place below. The TelemetryTimer_Tick method will be defined next, and will be executed every 500 ms according to the value hardcoded in the Interval property.

        1: private async Task SetupHatAsync()
        2: {
        3:     this.hat = await FEZHAT.CreateAsync();
        4:  
        5:     this.telemetryTimer = new DispatcherTimer();
        6:  
        7:     this.telemetryTimer.Interval = TimeSpan.FromMilliseconds(500);
        8:     this.telemetryTimer.Tick += this.TelemetryTimer_Tick;
        9:  
       10:     this.telemetryTimer.Start();
       11: }
    
  12. The following method will be executed every time the timer ticks, and will poll the value of the hat's temperature sensor, send it to the Azure IoT Hub and show the value obtained. Place the code just below the comment "//ENTER TELEMENTRYTIMER_TICK METHOD HERE"

        1: private void TelemetryTimer_Tick(object sender, object e)
        2: {
        3:     // Temperature Sensor
        4:     var tSensor = ctdHelper.sensors.Find(item => item.measurename == "Temperature");
        5:     tSensor.value = this.hat.GetTemperature();
        6:     this.ctdHelper.SendSensorData(tSensor);
        7:  
        8:     this.HelloMessage.Text = "Temperature: " + tSensor.value.ToString("N2");
        9:  
       10:     System.Diagnostics.Debug.WriteLine("Temperature: {0} °C", tSensor.value);
       11: }
    

    WHAT DOES THIS CODE DO?: The first statement gets the ConnectTheDots sensor from the sensor collection already in place in the project (the temperature sensor was already included in the sample solution). Next, the temperature is polled out from the hat's temperature sensor using the driver object you initialized in the previous step. Then, the value obtained is sent to Azure using the ConnectTheDots's helper object ctdHelper which is included in the sample solution.

    The last two lines are used to show the current value of the temperature sensor to the debug console respectively.

  13. Before running the application you need to add the call to the SetupHatAsync method. Find the Page_Loaded method and place those two lines of code inside the {} curly brackets:

        1: private async void Page_Loaded(object sender, RoutedEventArgs e)
        2: {
        3:     // ADD CALL TO SETUP HAT ASYNC
        4:     // Initialize FEZ HAT shield
        5:     await SetupHatAsync();
        6: }
    

    Note you need to add the the async word (a modifier) to the event handler to properly handle an asynchronous call to the FEZ HAT initialization method. Place async as shown above between private and void WHAT DOES ASYNCHRONOUS MEAN?

  14. Now you are ready to run the application. Connect the Raspberry Pi with the FEZ HAT and run the application. After the app is deployed you will start to see in the output console the values polled from the sensor. The information sent to Azure is also shown in the console.

    Console output

    Output Window

    You can also check that the messages were successfully received by monitoring them using the Device Explorer

    Telemetry messages received

Keep building up your project

Adding extra sensors

Now that your application is sending information from your device to the cloud for one sensor - lets add some more!

  1. To incorporate the data from the Light sensor you will need to add a new ConnectTheDots sensor:

        1: // Hard coding guid for sensors. Not an issue for this particular application which is meant for testing and demos
        2: List<ConnectTheDotsSensor> sensors = new List<ConnectTheDotsSensor> {
        3:     new ConnectTheDotsSensor("2298a348-e2f9-4438-ab23-82a3930662ab", "Light", "L"),
        4:     new ConnectTheDotsSensor("d93ffbab-7dff-440d-a9f0-5aa091630201", "Temperature", "C"),
        5: };
    
  2. Next, add the following code to the TelemetryTimer_Tick method to poll the data from the temperature sensor and send it to Azure.

        1: // Light Sensor
        2: ConnectTheDotsSensor lSensor = ctdHelper.sensors.Find(item => item.measurename == "Light");
        3: lSensor.value = this.hat.GetLightLevel();
        4:  
        5: this.ctdHelper.SendSensorData(lSensor);
        6:  
        7: System.Diagnostics.Debug.WriteLine("Temperature: {0} °C, Light {1}", tSensor.value.ToString("N2"), lSensor.value.ToString("P2", System.Globalization.CultureInfo.InvariantCulture));
    

    After running the app you will see the following output in the debug console. In this case two messages are sent to Azure in every timer tick:

    Debug console after adding Light Sensor

    Output Window after Adding the Light Sensor

Send commands to your device

Azure IoT Hub is a service that enables reliable and secure bi-directional communications between millions of IoT devices and an application back end. In this section you will see how to send cloud-to-device messages to your device to command it to change the color of one of the FEZ HAT leds, using the Device Explorer app as the back end.

  1. Open the Universal app you created before and add the following method to the ConnectTheDotsHelper.cs file. Add the code to the bottom of the file where you see the comment "//ADD RECIEVE MESSAGE METHOD HERE":

        1: public async Task<string> ReceiveMessage()
        2: {
        3:     if (this.HubConnectionInitialized)
        4:     {
        5:         try
        6:         {
        7:             var receivedMessage = await this.deviceClient.ReceiveAsync();
        8:  
        9:             if (receivedMessage != null)
       10:             {
       11:                 var messageData = Encoding.ASCII.GetString(receivedMessage.GetBytes());
       12:                 this.deviceClient.CompleteAsync(receivedMessage);
       13:                 return messageData;
       14:             }
       15:             else
       16:             {
       17:                 return string.Empty;
       18:             }
       19:         }
       20:         catch (Exception e)
       21:         {
       22:             Debug.WriteLine("Exception when receiving message:" + e.Message);
       23:             return string.Empty;
       24:         }
       25:     }
       26:     else
       27:     {
       28:         return string.Empty;
       29:     }
       30: }
    

    The ReceiveAsync method returns the received message at the time that it is received by the device. The call to CompleteAsync() notifies IoT Hub that the message has been successfully processed and that it can be safely removed from the device queue. If something happened that prevented the device app from completing the processing of the message, IoT Hub will deliver it again.

  2. Now you will add the logic to process the messages received. Open the MainPage.xaml.cs file and add a new timer to the MainPage class. Add the new variable to the section "//DECLARE VARIABLES HERE":

        1: DispatcherTimer commandsTimer;
    
  3. Add the following method, which will be in charge of processing the commands where it says "//ENTER COMMANDTIMER_TICK METHOD HERE":

        1: private async void CommandsTimer_Tick(object sender, object e)
        2: {
        3:     string message = await ctdHelper.ReceiveMessage();
        4:  
        5:     if (message != string.Empty)
        6:     {
        7:         System.Diagnostics.Debug.WriteLine("Command Received: {0}", message);
        8:         switch (message.ToUpperInvariant())
        9:         {
       10:             case "RED":
       11:                 hat.D2.Color = new FEZHAT.Color(255, 0, 0);
       12:                 break;
       13:             case "GREEN":
       14:                 hat.D2.Color = new FEZHAT.Color(0, 255, 0);
       15:                 break;
       16:             case "BLUE":
       17:                 hat.D2.Color = new FEZHAT.Color(0, 0, 255);
       18:                 break;
       19:             case "OFF":
       20:                 hat.D2.TurnOff();
       21:                 break;
       22:             default:
       23:                 System.Diagnostics.Debug.WriteLine("Unrecognized command: {0}", message);
       24:                 break;
       25:         }
       26:     }
       27: }
    

    It reads the message received, and according to the text of the command, it set the value of the hat.D2.Color attribute to change the color of the FEZ HAT's LED D2. When the "OFF" command is received the TurnOff() method is called, which turns the LED off.

  4. Lastly, add the following piece of code to the SetupHatAsync method in order to initialize the timer used to poll for messages.

        1: this.commandsTimer = new DispatcherTimer();
        2: this.commandsTimer.Interval = TimeSpan.FromSeconds(60);
        3: this.commandsTimer.Tick += this.CommandsTimer_Tick;
        4: this.commandsTimer.Start();
    

    Note: The recommended interval for HTTP/1 message polling is 25 minutes. For debugging and demostration purposes a 1 minute polling interval is fine (you can use an even smaller interval for testing), but bear it in mind for production development. Check this article for guidance. When AMQP becomes available for the IoT Hub SDK using UWP apps a different approach can be taken for message processing, since AMQP supports server push when receiving cloud-to-device messages, and it enables immediate pushes of messages from IoT Hub to the device. The following article explains how to handle cloud-to-device messages using AMQP.

  5. Deploy the app to the device and open the Device Explorer app.

  6. Once it's loaded (and configured to point to your IoT hub), go to the Messages To Device tab, check the Monitor Feedback Endpoint option and write your command in the Message field. Click on Send

    Sending cloud-to-device message

  7. After a few seconds the message will be processed by the device and the LED will turn on in the colour you selected. The feedback will also be reflected in the Device Explorer screen after a few seconds.

Summary

In this lab, you have learned how to create a Universal app that reads from the sensors of a FEZ hat connected to a Raspberry Pi 2 running Windows 10 IoT Core, and upload those readings to an Azure IoT Hub. You also added more sensors to your application and implemented how to use the IoT Hubs Cloud-To-Device messages feature to send simple commands to your devices.