前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >田牌魔术 | .NET Core 3.0 + Azure 远程点亮树莓派上的一盏灯

田牌魔术 | .NET Core 3.0 + Azure 远程点亮树莓派上的一盏灯

作者头像
Edi Wang
发布2019-10-10 11:12:18
7990
发布2019-10-10 11:12:18
举报
文章被收录于专栏:汪宇杰博客汪宇杰博客

导语

3年前,我写过一篇《Windows 10 IoT Core + Azure 远程控制LED》,实现了《生活大爆炸》中的注孤生实验,让信号从家里出发,绕地球转一圈,经过微软美国数据中心,返回家里点亮树莓派上连接的一个 LED 灯泡。然而3年后的现在,Windows 10 IoT Core 以及UWP 已经冰冰凉透心凉,甚至微软至今也没有支持树莓派4的 Windows 版本。我只能苟且偷生,委曲求全,开荤 Linux,使用 .NET Core 重现了这个实验。微软和社区对于 .NET Core IoT 非常积极,提供了比 UWP 好用不少的 IoT 基础库,让我这个项目迁移非常方便。

.NET Core IoT 全家桶:https://github.com/dotnet/iot

在开始之前,如果你还没有在树莓派上配置.NET Core环境,可以参考我之前写的:

在树莓派4上安装 .NET Core 3.0 运行时及 SDK

“自启动”树莓派上的 .NET Core 3.0 环境

基本原理

我们要从自己电脑上发送信号到 Azure IoT Hub,树莓派上的.NET Core程序会监听消息,并控制LED开关。

创建 Azure IoT Hub

请根据微软文档创建 IoT Hub。最后记下你的连接字符串,看起来就像这样:

HostName=<Your Hub Name>.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=<Your Key>

微软文档:https://docs.microsoft.com/en-us/azure/iot-hub/quickstart-send-telemetry-dotnet?WT.mc_id=AZ-MVP-5002809

下载并安装 Azure Device Explorer (https://aka.ms/aziotdevexp)

把连接字符串粘贴到 Configuration / Connection Information里,点击 Update 按钮。

切换到 Management 选项卡,点击 Create ,输入你的设备名称,勾选 Auto Generate Keys

树莓派物理连接

将一个LED连接到树莓派:

长脚连接到 GPIO 17

短脚连接到接地(GROUND)

附:树莓派4 GPIO 全家桶图(来自网络)

复制粘贴

创建一个 .NET Core 3.0 控制台程序。添加 Microsoft.Azure.Devices.Client 以及 System.Device.Gpio NuGet 包。前者用于和Azure IoT Hub通讯,后者用于控制 GPIO 来开关LED灯泡。

<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>

<OutputType>Exe</OutputType>

<TargetFramework>netcoreapp3.0</TargetFramework>

</PropertyGroup>

<ItemGroup>

<PackageReference Include="Microsoft.Azure.Devices.Client" Version="1.21.1" />

<PackageReference Include="System.Device.Gpio" Version="1.0.0" />

</ItemGroup>

</Project>

Program.cs 最终代码如下。记得把里面的字符串常量换成你自己的 Azure IoT Hub 信息。

using System;

using System.Device.Gpio;

using System.Text;

using System.Threading;

using System.Threading.Tasks;

using Microsoft.Azure.Devices.Client;

using Microsoft.Azure.Devices.Client.Exceptions;

namespace AzureLightControl

{

class Program

{

private const string IotHubUri = "<Your Hub Name>.azure-devices.net";

private const string DeviceKey = "<Your Key>";

private const string DeviceId = "<Your Device ID>";

private const int Pin = 17;

private static CancellationToken _ct;

static async Task Main(string[] args)

{

Console.WriteLine("------------------------------");

Console.WriteLine(" Azure IoT Hub Light Control");

Console.WriteLine("------------------------------");

var cts = new CancellationTokenSource();

_ct = cts.Token;

Console.CancelKeyPress += (sender, eventArgs) =>

{

Console.WriteLine($"{DateTime.Now} > Cancelling...");

cts.Cancel();

eventArgs.Cancel = true;

};

try

{

var t = Task.Run(Run, cts.Token);

await t;

}

catch (IotHubCommunicationException)

{

Console.WriteLine($"{DateTime.Now} > Operation has been canceled.");

}

catch (OperationCanceledException)

{

Console.WriteLine($"{DateTime.Now} > Operation has been canceled.");

}

finally

{

cts.Dispose();

}

Console.ReadKey();

}

private static async Task Run()

{

using var deviceClient = DeviceClient.Create(IotHubUri, new DeviceAuthenticationWithRegistrySymmetricKey(DeviceId, DeviceKey));

using var controller = new GpioController();

controller.OpenPin(Pin, PinMode.Output);

Console.WriteLine($"{DateTime.Now} > Connected to the best cloud on the planet.");

Console.WriteLine($"Azure IoT Hub: {IotHubUri}");

Console.WriteLine($"Device ID: {DeviceId}");

Console.WriteLine($"{DateTime.Now} > GPIO pin enabled for use: {Pin}");

while (!_ct.IsCancellationRequested)

{

Console.WriteLine($"{DateTime.Now} > Waiting new message from Azure...");

var receivedMessage = await deviceClient.ReceiveAsync(_ct);

if (receivedMessage == null) continue;

var msg = Encoding.ASCII.GetString(receivedMessage.GetBytes());

Console.WriteLine($"{DateTime.Now} > Received message: {msg}");

switch (msg)

{

case "on":

Console.WriteLine($"{DateTime.Now} > Turn on the light.");

controller.Write(Pin, PinValue.High);

break;

case "off":

Console.WriteLine($"{DateTime.Now} > Turn off the light.");

controller.Write(Pin, PinValue.Low);

break;

default:

Console.WriteLine($"Unknown command: {msg}");

break;

}

await deviceClient.CompleteAsync(receivedMessage, _ct);

}

}

}

}

这里面,deviceClient.ReceiveAsync() 负责监听 Azure IoT Hub 有没有发来新消息,并处理收到的消息,完事后调用 CompleteAsync() 告诉 Azure 这个消息已经处理好了,这样的话设备再次连接到 Azure 就不会重复处理这条消息。

处理消息十分直接,读取消息内容为字符串,如果写着"on",就向GPIO 17输出高电位,即点亮灯泡。如果是"off",就输出低电位关闭灯泡。

能跑就行

将源代码或者发布后的dll全家桶复制到树莓派。然后在树莓派上用 .NET CLI 启动程序。在 PC 上,通过 Device Explorer 向设备发送 on 或 off 消息。

现在你学会了通过互联网控制家里灯泡开关的魔术:

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2019-10-07,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 汪宇杰博客 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
相关产品与服务
物联网通信
腾讯云物联网通信(Internet of Things Hub, IoT Hub)旨在提供一个安全、稳定、高效的连接平台,帮助开发者低成本、快速地实现“设备-设备”、“设备-用户应用”、“设备-云服务”之间可靠、高并发的数据通信。物联网通信平台不仅可以实现设备之间的互动、设备的数据上报和配置下发,还可以基于规则引擎和腾讯云产品打通,方便快捷地实现海量设备数据的存储、计算以及智能分析。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档