banner



How To Deploy C# App To Raspberry Pi 3

Microsoft Azure profile image Dave Glover

Learn how to build .NET Core IoT apps for Raspberry Pi Linux, and connect to Azure IoT Hub

.net core loves single board computers

Follow me on Twitter.


Source Code

The source and the samples for this walk-through can be found here.


Introduction

The .NET Core IoT Library connects your applications to hardware. In this walk-through you will learn how to:

  1. Develop a C# .NET Core IoT application from a Linux, macOS or Windows 10 desktop,
  2. Deploy the app to a Raspberry Pi running Linux (or another Linux board such as the BeagleBone Black),
  3. Debug and step through your code,
  4. Stream telemetry to Azure IoT Hub,
  5. And if you are a glutton for punishment then check out the [F# .Net Core IoT] in the samples folder.

Why .NET Core

It used by millions of developers, it is mature, fast, supports multiple programming languages (C#, F#, and VB.NET), runs on multiple platforms (Linux, macOS, and Windows), and is supported across multiple processor architectures. It is used to build device, cloud, and IoT applications.

.NET Core is an open-source, general-purpose development platform maintained by Microsoft and the .NET community on GitHub.


The .NET Core IoT Libraries Open Source Project

The Microsoft .NET Core team along with the developer community are building support for IoT scenarios. The .NET Core IoT Library is supported on Linux, and Windows IoT Core, across ARM and Intel processor architectures. See the .NET Core IoT Library Roadmap for more information.

System.Device.Gpio

The System.Device.Gpio package supports general-purpose I/O (GPIO) pins, PWM, I2C, SPI and related interfaces for interacting with low-level hardware pins to control hardware sensors, displays and input devices on single-board-computers; Raspberry Pi, BeagleBoard, HummingBoard, ODROID, and other single-board-computers that are supported by Linux and Windows 10 IoT Core.

Iot.Device.Bindings

The .NET Core IoT Repository contains IoT.Device.Bindings, a growing set of community-maintained device bindings for IoT components that you can use with your .NET Core applications. If you can't find what you need then porting your own C/C++ driver libraries to .NET Core and C# is pretty straight forward too.

The drivers in the repository include sample code along with wiring diagrams. For example the BMx280 - Digital Pressure Sensors BMP280/BME280.


Software Set Up for Linux, macOS, and Windows 10 Desktops

You can create .NET Core IoT projects on Linux, macOS and Windows desktops. You need to install the following software.

  1. .NET Core
  2. Visual Studio Code

Additional Windows 10 Software Requirements

  1. Windows Subsystem for Linux (WSL). I suggest you install the Ubuntu 18.04 distribution.
  2. PuTTY SSH and telnet client

Setting up your Raspberry Pi

.Net Core requires an AMR32v7 processor and above, so anything Raspberry Pi 2 or better and you are good to go. Note, Raspberry Pi Zero is an ARM32v6 processor, and not supported.

If you've not set up a Raspberry Pi before then this is a great guide. "HEADLESS RASPBERRY PI 3 B+ SSH WIFI SETUP (MAC + WINDOWS)". The Instructions outlined for macOS will work on Linux.

This walk-through assumes the default Raspberry Pi network name, 'raspberrypi.local', and the default password, 'raspberry'.


Configure Connection to your Raspberry Pi

The following creates a new SSH key, copies the public key to the Raspberry Pi, and then installs the Visual Studio Debugger on the Raspberry Pi. Take the default options.

From Linux and macOS

Open a new Terminal, and copy and paste the following command.

            ssh-keygen              -t              rsa              &&              ssh-copy-id pi@raspberrypi.local              &&              \              ssh pi@raspberrypi.local              "curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -r linux-arm -v latest -l ~/vsdbg"                      

From Windows 10

Press the Windows Key
windows key, type 'cmd', then press the Enter key to open the Windows command prompt. Then copy and paste the following commands.

This is required because WSL 1 does not resolve .local addresses. This has been fixed in WSL 2.

Replace xxx.xxx.xxx.xxx with the IP Address of the Raspberry Pi and then copy and paste the following command into the Windows Command prompt.

            bash              -c              "ssh-keygen -t rsa && ssh-copy-id pi@xxx.xxx.xxx.xxx"              &&              ^ plink              -ssh              -pw              raspberry pi@raspberrypi.local              "curl -sSL https://aka.ms/getvsdbgsh | bash /dev/stdin -r linux-arm -v latest -l ~/vsdbg"                      

Creating your first .NET Core IoT project

Open a command prompt or terminal window, and paste in the following command(s). It will create the project directory, create the .NET Core Console app, add the Iot.Device.Bindings package, and then launch Visual Studio Code.

                          mkdir              dotnet.core.iot.csharp              &&              cd              dotnet.core.iot.csharp  dotnet new console              --langVersion              =latest              &&              dotnet add package Iot.Device.Bindings              --version              1.0.0  code              .                      
  1. Add the Visual Studio Code Build and Debug assets

  1. Replace the code in program.cs file with the following code. This code will read the Raspberry Pi CPU Temperature and display it in the system console window.
                          using              System              ;              using              Iot.Device.CpuTemperature              ;              using              System.Threading              ;              namespace              dotnet.core.iot              {              class              Program              {              static              CpuTemperature              temperature              =              new              CpuTemperature              ();              static              void              Main              (              string              []              args              )              {              while              (              true              )              {              if              (              temperature              .              IsAvailable              )              {              Console              .              WriteLine              (              $"The CPU temperature is                            {              temperature              .              Temperature              .              Celsius              }              "              );              }              Thread              .              Sleep              (              2000              );              // sleep for 2000 milliseconds, 2 seconds              }              }              }              }                      

Your Visual Studio Code program.cs file should look like the following screenshot.

sample program


Deploying the project to your Raspberry Pi

To deploy a project to your Raspberry Pi you need to configure Visual Studio Code to compile for linux-arm, how to copy the compiled code to the Raspberry Pi, and finally how to attach the debugger.

For this walk-through, we are going to use rsync to copy program files to the Raspberry Pi. Rsync is a very efficient file transfer protocol, comes standard with Linux, macOS, and Windows with the Windows Subsystem for Linux (WSL) installed.


Updating the Visual Studio Code Build Files

We need to update the launch.json and tasks.json files with the following code.

This walk-through assumes the default Raspberry Pi network name, 'raspberrypi.local', and the default password, 'raspberry'.

launch.json

The launch.json file calls a RaspberryPublish prelaunch task which builds and copies the program to the Raspberry Pi, it then starts the program on the Raspberry Pi and attaches the debugger.

                          {                                          "version"              :                                          "0.2.0"              ,                                          "configurations"              :                                          [                                          {                                          "name"              :                                          "Raspberry Pi Publish, Launch, and Attach Debugger"              ,                                          "type"              :                                          "coreclr"              ,                                          "request"              :                                          "launch"              ,                                          "preLaunchTask"              :                                          "RaspberryPublish"              ,                                          "program"              :                                          "~/${workspaceFolderBasename}/${workspaceFolderBasename}"              ,                                          "cwd"              :                                          "~/${workspaceFolderBasename}"              ,                                          "stopAtEntry"              :                                          false              ,                                          "console"              :                                          "internalConsole"              ,                                          "args"              :                                          [                                          "https://your-dmx-function.azurewebsites.net/api"                                          ],                                          "pipeTransport"              :                                          {                                          "pipeCwd"              :                                          "${workspaceRoot}"              ,                                          "pipeProgram"              :                                          "/usr/bin/ssh"              ,                                          "pipeArgs"              :                                          [                                          "pi@raspberrypi.local"                                          ],                                          "debuggerPath"              :                                          "~/vsdbg/vsdbg"                                          },                                          "windows"              :                                          {                                          "pipeTransport"              :                                          {                                          "pipeCwd"              :                                          "${workspaceRoot}"              ,                                          "pipeProgram"              :                                          "plink"              ,                                          "pipeArgs"              :                                          [                                          "-ssh"              ,                                          "-pw"              ,                                          "raspberry"              ,                                          "pi@raspberrypi.local"                                          ],                                          "debuggerPath"              :                                          "~/vsdbg/vsdbg"                                          }                                          }                                          }                                          ]                                          }                                                  

tasks.json

The tasks.json file defines how to compile the project for linux-arm and how to copy the program to the Raspberry Pi with rsync. On Windows, you must explicitly specify the IP Address of the Raspberry Pi as rsync is called via Bash and the Windows Subsystem for Linux does not resolve .local DNS names.

                          {                                          "version"              :                                          "2.0.0"              ,                                          "tasks"              :                                          [                                          {                                          "label"              :                                          "RaspberryPublish"              ,                                          "command"              :                                          "sh"              ,                                          "type"              :                                          "shell"              ,                                          "problemMatcher"              :                                          "$msCompile"              ,                                          "args"              :                                          [                                          "-c"              ,                                          "              \"              dotnet publish -r linux-arm -o bin/linux-arm/publish"              ,                                          "${workspaceFolder}/${workspaceFolderBasename}.csproj              \"              "              ,                                          ";"              ,                                          "sh"              ,                                          "-c"              ,                                          "              \"              rsync -rvuz ${workspaceFolder}/bin/linux-arm/publish/ pi@raspberrypi.local:~/${workspaceFolderBasename}              \"              "                                          ],                                          "windows"              :                                          {                                          "command"              :                                          "cmd"              ,                                          "args"              :                                          [                                          "/c"              ,                                          "              \"              dotnet publish -r linux-arm -o bin              \\              linux-arm              \\              publish"              ,                                          "${workspaceFolder}              \\              ${workspaceFolderBasename}.csproj              \"              "              ,                                          "&&"              ,                                          "bash"              ,                                          "-c"              ,                                          "              \"              rsync -rvuz $(wslpath '${workspaceFolder}')/bin/linux-arm/publish/ pi@raspberrypi.local:~/${workspaceFolderBasename}              \"              "                                          ]                                          }                                          }                                          ]                                          }                                                  

Set the Visual Studio Code Default Terminal Shell

If on Windows, then set the default Visual Studio Code default shell to Command Prompt.

  1. From Visual Studio Code
  2. Press F1
  3. Type Terminal: Select Default Shell
  4. Select Command Prompt

Build, Deploy and Debug your .NET Core IoT App

Review this Visual Studio Debugger Guide if you've not used the debugger before.

Set a breakpoint in your code, for example at the 15, and from Visual Studio Code click the Debug icon on the Activity bar, ensure "Publish, Launch and Attach Debugger" is selected in the dropdown, and click the green run icon.

Your code will build, it will be copied to your Raspberry Pi and the debugger will be attached and you can now start stepping through your code.

Publish, Launch and Attach Debugger


Connect your Raspberry Pi to Azure IoT Hub

  1. Follow the "Create an Azure IoT Hub (Free)" tutorial until the "Send simulated telemetry" section. You will need to the connection string of the device you created.

  2. Add the Package references for Azure IoT Hub and JSON.NET. This can either be done by executing the 'dotnet add package' command, or by updating the references directly in the .csproj file.

Open the dotnet.core.iot.csharp.csproj file and update the section as follows.

                          <ItemGroup>              <PackageReference              Include=              "Iot.Device.Bindings"              Version=              "1.0.0"              />              <PackageReference              Include=              "Microsoft.Azure.Devices.Client"              Version=              "1.*"              />              <PackageReference              Include=              "Newtonsoft.Json"              Version=              "12.*"              />              </ItemGroup>                      
  1. Replace the code in program.cs file with the following code and add your device connection string.

This code will read the Raspberry Pi CPU Temperature, display it, then send the telemetry to Azure IoT Hub.

                          using              System              ;              using              Iot.Device.CpuTemperature              ;              using              Newtonsoft.Json              ;              using              Microsoft.Azure.Devices.Client              ;              using              System.Text              ;              using              System.Threading              ;              using              System.Threading.Tasks              ;              namespace              dotnet.core.iot              {              class              Program              {              const              string              DeviceConnectionString              =              "<Your Azure IoT Hub Connection String>"              ;              // Replace with the device id you used when you created the device in Azure IoT Hub              const              string              DeviceId              =              "<Your Device Id>"              ;              static              DeviceClient              _deviceClient              =              DeviceClient              .              CreateFromConnectionString              (              DeviceConnectionString              ,              TransportType              .              Mqtt              );              static              CpuTemperature              _temperature              =              new              CpuTemperature              ();              static              int              _msgId              =              0              ;              const              double              TemperatureThreshold              =              42.0              ;              static              async              Task              Main              (              string              []              args              )              {              while              (              true              )              {              if              (              _temperature              .              IsAvailable              )              {              Console              .              WriteLine              (              $"The CPU temperature is                            {              Math              .              Round              (              _temperature              .              Temperature              .              Celsius              ,              2              )}              "              );              await              SendMsgIotHub              (              _temperature              .              Temperature              .              Celsius              );              }              Thread              .              Sleep              (              2000              );              // sleep for 2000 milliseconds              }              }              private              static              async              Task              SendMsgIotHub              (              double              temperature              )              {              var              telemetry              =              new              Telemetry              ()              {              Temperature              =              Math              .              Round              (              temperature              ,              2              ),              MessageId              =              _msgId              ++              };              string              json              =              JsonConvert              .              SerializeObject              (              telemetry              );              Console              .              WriteLine              (              $"Sending                            {              json              }              "              );              Message              eventMessage              =              new              Message              (              Encoding              .              UTF8              .              GetBytes              (              json              ));              eventMessage              .              Properties              .              Add              (              "temperatureAlert"              ,              (              temperature              >              TemperatureThreshold              )              ?              "true"              :              "false"              );              await              _deviceClient              .              SendEventAsync              (              eventMessage              ).              ConfigureAwait              (              false              );              }              class              Telemetry              {              [              JsonPropertyAttribute              (              PropertyName              =              "temperature"              )]              public              double              Temperature              {              get              ;              set              ;              }              =              0              ;              [              JsonPropertyAttribute              (              PropertyName              =              "messageId"              )]              public              int              MessageId              {              get              ;              set              ;              }              =              0              ;              [              JsonPropertyAttribute              (              PropertyName              =              "deviceId"              )]              public              string              DeviceId              {              get              ;              set              ;}              =              Program              .              DeviceId              ;              }              }              }                      

Redeploy the App to the Raspberry Pi

Press F5 to run the current 'Publish, Launch, and Attach Debugger' build task.


Monitor the Azure IoT Hub Telemetry

  1. Install the Visual Studio IoT Hub Toolkit.

  2. Review the Visual Studio IoT Hub Toolkit] Wiki for information on using the IoT Hub Toolkit Visual Studio Extension.


References

Remote Debugging On Linux Arm

Azure IoT libraries for .NET

How To Deploy C# App To Raspberry Pi 3

Source: https://dev.to/azure/net-core-iot-raspberry-pi-linux-and-azure-iot-hub-learn-how-to-build-deploy-and-debug-d1f

Posted by: maclennanwhoods.blogspot.com

0 Response to "How To Deploy C# App To Raspberry Pi 3"

Post a Comment

Iklan Atas Artikel

Iklan Tengah Artikel 1

Iklan Tengah Artikel 2

Iklan Bawah Artikel