Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Mastering Internet of Things

You're reading from   Mastering Internet of Things Design and create your own IoT applications using Raspberry Pi 3

Arrow left icon
Product type Paperback
Published in Mar 2018
Publisher Packt
ISBN-13 9781788397483
Length 410 pages
Edition 1st Edition
Concepts
Arrow right icon
Author (1):
Arrow left icon
Peter Waher Peter Waher
Author Profile Icon Peter Waher
Peter Waher
Arrow right icon
View More author details
Toc

Table of Contents (18) Chapters Close

Preface 1. Preparing Our First Raspberry Pi Project 2. Creating a Sensor to Measure Ambient Light FREE CHAPTER 3. Creating an Actuator for Controlling Illumination 4. Publishing Information Using MQTT 5. Publishing Data Using HTTP 6. Creating Web Pages for Your Devices 7. Communicating More Efficiently Using CoAP 8. Interoperability 9. Social Interaction with Your Devices Using XMPP 10. The Controller 11. Product Life Cycle 12. Concentrators and Bridges 13. Using an Internet of Things Service Platform 14. IoT Harmonization 15. Security for the Internet of Things 16. Privacy 17. Other Books You May Enjoy

Creating your first project

Let's begin. Since our Raspberry Pi now runs Windows 10 IoT Core, .NET Core applications will run on it, including Universal Windows Platform (UWP) applications. From a blank solution, let's create our first Raspberry Pi application. Choose Add and New Project. In the Visual C# category, select Blank App (Universal Windows). Let's call our project FirstApp. Visual Studio will ask us for target and minimum platform versions. Check the screenshot and make sure the version you select is lower than the version installed on your Raspberry Pi.

In our case, the Raspberry Pi runs Build 15063. This is the March 2017 release. So, we accept Build 14393 (July 2016) as the target version and Build 10586 (November 2015) as the minimum version. If you want to target the Windows 10 Fall Creators Update, which supports .NET Core 2, you should select Build 16299 for both.

In the Solution Explorer, we should now see the files of our new UWP project:

New project

Adding NuGet packages

We proceed by adding functionality to our app from downloadable packages, or NuGets. From the References node, right-click and select Manage NuGet Packages. First, go to the Updates tab and make sure the packages that you already have are updated. Next, go to the Browse tab, type Firmata in the search box, and press Enter. You should see the Windows-Remote-Arduino package. Make sure to install it in your project. In the same way, search for the Waher.Events package and install it.

Aggregating capabilities

Since we're going to communicate with our Arduino using a USB serial port, we must make a declaration in the Package.appxmanifest file stating this. If we don't do this, the runtime environment will not allow the app to do it. Since this option is not available in the GUI by default, you need to edit the file using the XML editor. Make sure the serialCommunication device capability is added, as follows:

<Capabilities> 
   <Capability Name="internetClient" /> 
   <DeviceCapability Name="serialcommunication"> 
         <Device Id="any"> 
               <Function Type="name:serialPort" /> 
         </Device> 
   </DeviceCapability> 
</Capabilities> 

Initializing the application

Before we do any communication with the Arduino, we need to initialize the application. We do this by finding the OnLaunched method in the App.xml.cs file. After the Window.Current.Activate() call, we make a call to our Init() method where we set up the application.

   Window.Current.Activate(); 
   Task.Run((Action)this.Init); 
We execute our initialization method from the thread pool, instead of the standard thread. This is done by calling Task.Run(), defined in the System.Threading.Tasks namespace. The reason for this is that we want to avoid locking the standard thread. Later, there will be a lot of asynchronous calls made during initialization. To avoid problems, we should execute all these from the thread pool, instead of from the standard thread.

We'll make the method asynchronous:

private async void Init() 
{ 
   try 
   { 
         Log.Informational("Starting application."); 
         ... 
   } 
   catch (Exception ex) 
   { 
         Log.Emergency(ex); 
          
         MessageDialog Dialog =  
new MessageDialog(ex.Message, "Error"); 
         await Dialog.ShowAsync(); 
} IoT Desktop }

The static Log class is available in the Waher.Events namespace, belonging to the NuGet we included earlier. (MessageDialog is available in Windows.UI.Popups, which might be a new namespace if you're not familiar with UWP.)

Communicating with the Arduino

The Arduino is accessed using Firmata. To do that, we use the Windows.Devices.Enumeration, Microsoft.Maker.RemoteWiring, and Microsoft.Maker.Serial namespaces, available in the Windows-Remote-Arduino NuGet. We begin by enumerating all the devices it finds:

DeviceInformationCollection Devices =  
   await UsbSerial.listAvailableDevicesAsync(); 
foreach (DeviceInformationDeviceInfo in Devices) 
{ 

If our Arduino device is found, we will have to connect to it using USB:

if (DeviceInfo.IsEnabled&&DeviceInfo.Name.StartsWith("Arduino")) 
{ 
   Log.Informational("Connecting to " + DeviceInfo.Name); 
 
   this.arduinoUsb = new UsbSerial(DeviceInfo); 
   this.arduinoUsb.ConnectionEstablished += () => 
         Log.Informational("USB connection established."); 

Attach a remote device to the USB port class:

this.arduino = new RemoteDevice(this.arduinoUsb); 

We need to initialize our hardware, when the remote device is ready:

this.arduino.DeviceReady += () => 
{ 
   Log.Informational("Device ready."); 
 
   this.arduino.pinMode(13, PinMode.OUTPUT);    // Onboard LED. 
   this.arduino.digitalWrite(13, PinState.HIGH); 
 
   this.arduino.pinMode(8, PinMode.INPUT);      // PIR sensor. 
   MainPage.Instance.DigitalPinUpdated(8,
this.arduino.digitalRead(8));
this.arduino.pinMode(9, PinMode.OUTPUT); // Relay. this.arduino.digitalWrite(9, 0); // Relay set to 0 this.arduino.pinMode("A0", PinMode.ANALOG); // Light sensor. MainPage.Instance.AnalogPinUpdated("A0",
this.arduino.analogRead("A0")); };
Important: the analog input must be set to PinMode.ANALOG, not PinMode.INPUT. The latter is for digital pins. If used for analog pins, the Arduino board and Firmata firmware may become unpredictable.

Our inputs are then reported automatically by the Firmata firmware. All we need to do to read the corresponding values is to assign the appropriate event handlers. In our case, we forward the values to our main page, for display:

this.arduino.AnalogPinUpdated += (pin, value) => 
{ 
   MainPage.Instance.AnalogPinUpdated(pin, value); 
}; 
 
this.arduino.DigitalPinUpdated += (pin, value) => 
{ 
   MainPage.Instance.DigitalPinUpdated(pin, value); 
}; 

Communication is now set up. If you want, you can trap communication errors, by providing event handlers for the ConnectionFailed and ConnectionLost events. All we need to do now is to initiate communication. We do this with a simple call:

this.arduinoUsb.begin(57600, SerialConfig.SERIAL_8N1); 

Testing the app

Make sure the Arduino is still connected to your PC via USB. If you run the application now (by pressing F5), it will communicate with the Arduino, and display any values read to the event log. In the GitHub project, I've added a couple of GUI components to our main window, that display the most recently read pin values on it. It also displays any event messages logged. We leave the relay for later chapters.

For a more generic example, see the Waher.Service.GPIO project at https://github.com/PeterWaher/IoTGateway/tree/master/Services/Waher.Service.GPIO. This project allows the user to read and control all pins on the Arduino, as well as the GPIO pins available on the Raspberry Pi directly.

Deploying the app

You are now ready to test the app on the Raspberry Pi. You now need to disconnect the Arduino board from your PC, and install it on top of the Raspberry Pi. The power of the Raspberry Pi should be turned off when doing this. Also make sure the serial cable is connected to one of the USB ports of the Raspberry Pi. Begin by switching the target platform, from Local Machine to Remote Machine, and from x86 to ARM:

Run on a remote machine with an ARM processor

Your Raspberry Pi should appear automatically in the following dialog. You should check the address with the IoT Dashboard used earlier, to make sure you're selecting the correct machine:

Select your Raspberry Pi

You can now run or debug your app directly on the Raspberry Pi, using your local PC. The first deployment might take a while, since the target system needs to be properly prepared. Subsequent deployments will be much faster. Open the Device Portal from the IoT Dashboard, and take a Screenshot, to see the results. You can also go to the Apps Manager in the Device Portal, and configure the app to be started automatically at startup:

App running on the Raspberry Pi
lock icon The rest of the chapter is locked
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime