Internet of Things RPI2 with Fez Hat board using Windows 10 IoT Core and IoT Hubs
Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
Code/WindowsIoTCorePi2FezHat-IoTHubs
Images
ghi_elect-windows-iot-183b64180b7c
.gitattributes
.gitignore
GetIPAddressFromHostName.docx
README.md
Setting Date_Time on IoTCore.docx
Setup your device to Internet Share.pdf

README.md

Windows 10 IoT Core Hands-on Lab

ConnectTheDots will help you get tiny devices connected to Microsoft Azure, and to implement great IoT solutions taking advantage of Microsoft Azure IoT Hubs and the Universal Windows Platform.

This lab is stand-alone, but is used at Microsoft to accompany a presentation about Azure, Windows 10 IoT Core, and our IoT services. If you wish to follow this on your own, you are encouraged to do so. If not, consider attending a Microsoft-led IoT lab in your area.

In this lab you will use a Raspberry Pi 2 device with Windows 10 Iot Core and a FEZ HAT sensor hat. 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.

Note: Although AMQP is the recommended approach, at the time this lab was written that protocol was not supported by the Azure IoT Core SDK for UWP (Universal Windows Platform) applications. However, it is expected to be implemented in a short time, since it's currently under development.

This lab includes the following tasks:

  1. Setup
    1. Software
    2. Devices
    3. Azure Account
    4. Device Registration
  2. Creating a Universal App
    1. Read FEZ HAT sensors
    2. Send telemetry data to Azure IoT Hub
  3. Keep building up your project
    1. Adding extra sensors
    2. Sending commands to your devices
  4. Summary
## Pre-requisites 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:

Download Azure Device Explorer

Azure IoT Hub Device Explorer

Download the IoT Core Dashboard

## During the Lab

Setting up your Devices

For this project, you have the following items

  • Raspberry Pi 2 Model B with power supply and adaptor
  • GHI FEZ HAT
  • Your PC running Windows 10 or later
  • An Ethernet port on the PC, or an auto-crossover USB->Ethernet adapter like the Belkin F4U047.
  • Standard Ethernet cable
  • A 16GB Samsung SD Card with Windows 10 IoT Core already mounted.

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 http://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.

<Go to "blog url" and download the Windows 10 IoT Core Watcher>

  1. Enable your device to internet share with the Raspberry Pi by following the instructions in the file 'Setup your device to Internet Share.pdf'

  2. Run the Windows 10 IoT Core Dashboard on your development PC and note your Raspberry Pi IP address on the detected device [each device in this lab has a unqiue name, situated on the blue box].

    • Click the windows "Start" button
    • Type "IoT" 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-dashboard

<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>

  1. 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

  2. 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

  3. 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>

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

  5. 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

  6. 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

  7. Disconnect from the Powershell Session Exit-PSSession

### Setting up your Azure Account

Creating an IoT Hub

  1. Enter the Azure portal, by browsing to http://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

  1. 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

  2. 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](https://azure.microsoft.com/en-us/documentation/articles/iot-hub-devguide/#device-identity-registry) 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. ### 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. 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:

    ctdHelper = new ConnectTheDotsHelper(iotDeviceConnectionString: "IOT_CONNECTION_STRING",
        organization: "YOUR_ORGANIZATION_OR_SELF",
        location: "YOUR_LOCATION",
        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. Ensure that the target platform for the project is set to "ARM":

    arm-target-platform

  4. 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

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

    Remote Connection

    Setting up the Remote Connection

  6. 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

  7. 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.

  8. 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:

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

      //Button_Click(null, null);
      var timer = new DispatcherTimer();
      timer.Interval = TimeSpan.FromMilliseconds(500);
      timer.Tick += Timer_Tick;
      timer.Start();

      Which will make the Timer tick twice a second.

  9. 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

  10. 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

  11. 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

````C#
var timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(500);
timer.Tick += Timer_Tick;
timer.Start();
````
  1. 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

  2. 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:

    using GHIElectronics.UWP.Shields;
  3. 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.

    FEZHAT hat;
    DispatcherTimer telemetryTimer;
  1. 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.

    private async Task SetupHatAsync()
    {
        this.hat = await FEZHAT.CreateAsync();
    
        this.telemetryTimer = new DispatcherTimer();
    
        this.telemetryTimer.Interval = TimeSpan.FromMilliseconds(500);
        this.telemetryTimer.Tick += this.TelemetryTimer_Tick;
    
        this.telemetryTimer.Start();
    }
  2. 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"

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

    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.

  3. 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:

    private async void Page_Loaded(object sender, RoutedEventArgs e)
    {
    	// ADD CALL TO SETUP HAT ASYNC
    	// Initialize FEZ HAT shield
    	await SetupHatAsync();
    }

    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

    Asynchronous methods/keywords help optimize the execution of resources. An asynchronous method returns an answer immediately, allowing the calling program to perform other operations at the same time. Allowing multi-threaded programming. This is different to a synchronous method that waits for the method to complete before continuing to execute the rest of the code.

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

    arm-target-platform

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

    ghifezhat-build-solution

    ghifezhat-build-succeeded

  6. 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:

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

    // Light Sensor
    ConnectTheDotsSensor lSensor = ctdHelper.sensors.Find(item => item.measurename == "Light");
    lSensor.value = this.hat.GetLightLevel();
    
    this.ctdHelper.SendSensorData(lSensor);
    
    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":

    public async Task<string> ReceiveMessage()
    {
    	if (this.HubConnectionInitialized)
    	{
    		try
    		{
    			var receivedMessage = await this.deviceClient.ReceiveAsync();
    
    			if (receivedMessage != null)
    			{
    				var messageData = Encoding.ASCII.GetString(receivedMessage.GetBytes());
    				this.deviceClient.CompleteAsync(receivedMessage);
    				return messageData;
    			}
    			else
    			{
    				return string.Empty;
    			}
    		}
    		catch (Exception e)
    		{
    			Debug.WriteLine("Exception when receiving message:" + e.Message);
    			return string.Empty;
    		}
    	}
    	else
    	{
    		return string.Empty;
    	}
    }

    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":

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

    private async void CommandsTimer_Tick(object sender, object e)
    {
    	string message = await ctdHelper.ReceiveMessage();
    
    	if (message != string.Empty)
    	{
    		System.Diagnostics.Debug.WriteLine("Command Received: {0}", message);
    		switch (message.ToUpperInvariant())
    		{
    			case "RED":
    				hat.D2.Color = new FEZHAT.Color(255, 0, 0);
    				break;
    			case "GREEN":
    				hat.D2.Color = new FEZHAT.Color(0, 255, 0);
    				break;
    			case "BLUE":
    				hat.D2.Color = new FEZHAT.Color(0, 0, 255);
    				break;
    			case "OFF":
    				hat.D2.TurnOff();
    				break;
    			default:
    				System.Diagnostics.Debug.WriteLine("Unrecognized command: {0}", message);
    				break;
    		}
    	}
    }

    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.

    this.commandsTimer = new DispatcherTimer();
    this.commandsTimer.Interval = TimeSpan.FromSeconds(60);
    this.commandsTimer.Tick += this.CommandsTimer_Tick;
    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 color you selected. The feedback will also be reflected in the Device Explorer screen after a few seconds.

    cloud-to-device message received

## 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.