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

点击上方蓝字关注“汪宇杰博客”

640?wx_fmt=png

导语

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

640?wx_fmt=png

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

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

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

基本原理

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

640?wx_fmt=png

创建 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 按钮。

640?wx_fmt=png

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

640?wx_fmt=png

树莓派物理连接

将一个LED连接到树莓派:

长脚连接到 GPIO 17

短脚连接到接地(GROUND)

640?wx_fmt=png

附:树莓派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 消息。

640?wx_fmt=png

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

640?wx_fmt=jpeg

640?wx_fmt=jpeg

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/313509.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

使用Hash碰撞进行DoS攻击

一、哈希表碰撞攻击的基本原理 哈希表是一种查找效率极高的数据结构&#xff0c;很多语言都在内部实现了哈希表。PHP中的哈希表是一种极为重要的数据结构&#xff0c;不但用于表示Array数据类型&#xff0c;还在Zend虚拟机内部用于存储上下文环境信息&#xff08;执行上下文的…

EF Core 实现读写分离的最佳方案

前言公司之前使用Ado.net和Dapper进行数据访问层的操作, 进行读写分离也比较简单, 只要使用对应的数据库连接字符串即可. 而最近要迁移到新系统中,新系统使用.net core和EF Core进行数据访问. 所以趁着国庆假期拿出一两天时间研究了一下如何EF Core进行读写分离.思路根据园子里…

SSL工作原理

本文介绍了SSL原理、安全机制、工作过程和典型网络应用。 缩略语列表 一、概述 1.1 产生背景 基于万维网的电子商务和网上银行等新兴应用&#xff0c;极大地方便了人们的日常生活。受到人们的青睐。 因为这些应用都须要在网络上进行在线交易&#xff0c;它们对网络通信的…

在 ASP.NET Core 项目中使用 AutoMapper 进行实体映射

一、前言在实际项目开发过程中&#xff0c;我们使用到的各种 ORM 组件都可以很便捷的将我们获取到的数据绑定到对应的 List<T> 集合中&#xff0c;因为我们最终想要在页面上展示的数据与数据库实体类之间可能存在很大的差异&#xff0c;所以这里更常见的方法是去创建一些…

.NET开发者必须学习.NET Core

很多的.NET开发者在接触.Net Core之前&#xff0c;对于linux系统一点也不了解&#xff0c;也未曾有过主动去学习的念头。在接触了.Net Core之后才会慢慢学习linux相关知识&#xff0c;很多同学想转Java&#xff0c;这个很扎心&#xff0c;你有很好的条件转向.NET Core为啥要转J…

Java事务管理

事务的ACID属性&#xff1a;原子性(Atomicity )、一致性( Consistency )、隔离性或独立性( Isolation)和持久性(Durabilily) ACID 特性 A&#xff08;原子性&#xff09;事务的原子操作单元&#xff0c;对数据的修改&#xff0c;要么全部执行&#xff0c;要么全部不执行&#x…

如何提高QnA maker机器人训练中文语义理解的能力

这是一个常见的问题&#xff0c;在人工智能的世界里面&#xff0c;图像理解、语言及语义理解、数据理解是三个核心领域。而关于语言及语义理解&#xff0c;又与具体的语言和文字密切相关。目前来说&#xff0c;大家都是用机器学习去训练模型&#xff0c;如果要更好的理解中文&a…

分布式数据一致性(数据多份副本一致性)

前言 分布式数据库的数据一致性管理是其最重要的内核技术之一&#xff0c;也是保证分布式数据库满足数据库最基本的ACID特性中的 “一致性”(Consistency)的保障。在分布式技术发展下&#xff0c;数据一致性的解决方法和技术也在不断的演进&#xff0c;本文就以分布式数据库作…

Bumblebee微服务网关之请求统一验证

对于微服务网关来说&#xff0c;统一请求验证是一个比较重要和常用的功能&#xff0c;通过网关验证后台服务就无须关注请求验证&#xff1b;对于多语言平台的服务而言制定验证方式和变更验证配置都是一件比较繁琐和工作量大的事情。Bumblebee提供JWT验证插件&#xff0c;只需要…

分布式事务基础

这一篇主要介绍分布式事务的基础知识&#xff0c;一些基础的算法、定理、简单应用等。下篇文章介绍互联网业界的具体实践方案。 1、CAP定理 CAP定理是由加州大学伯克利分校Eric Brewer教授提出来的&#xff0c;其核心思想是任何基于网络的数据共享&#xff0c;系统最多只能满…

支持前端、后台业务代码扩展的快速开发框架

框架采用.NetCore Vue前后端分离&#xff0c;并且支持前端、后台代码业务动态扩展&#xff0c;框架内置了一套有着20多种属性配置的代码生成器&#xff0c;可灵活配置生成的代码&#xff0c;代码生成器界面配置完成即可生成单表/主从表的增、删、改、查、导入、导出、上传、审…

保证分布式系统数据一致性的6种方案

分布式系统数据一致性的基础知识&#xff0c;传送门 1、问题的起源 在电商等业务中&#xff0c;系统一般由多个独立的服务组成&#xff0c;如何解决分布式调用时候数据的一致性&#xff1f; 具体业务场景如下&#xff0c;比如一个业务操作&#xff0c;如果同时调用服务 A、B…

15年来这8门编程语言位置十分稳定,C#从低谷开始爬升

TIOBE 编程语言排行榜 10 月份的榜单已公布&#xff0c;这期的标题比较有趣 —— “Top 8 of the TIOBE index quite stable for the last 15 years”&#xff0c;意思就是排名前 8 的编程语言在这 15 年里一直都十分稳定。有多稳定呢&#xff1f;根据 TIOBE 统计的数据&#x…

Dubbo相关

mark http://ifeve.com/dubbo-learn-book/ http://dubbo.apache.org/zh-cn/ Dubbo架构图 框架分层架构中&#xff0c;各个层次的设计要点&#xff1a; 服务接口层&#xff08;Service&#xff09;&#xff1a;该层是与实际业务逻辑相关的&#xff0c;根据服务提供方和服务消费…

同时支持EF+Dapper的混合仓储,助你快速搭建数据访问层

背景17年开始&#xff0c;公司开始向DotNet Core转型&#xff0c;面对ORM工具的选型&#xff0c;当时围绕Dapper和EF发生了激烈的讨论。项目团队更加关注快速交付&#xff0c;他们主张使用EF这种能快速开发的ORM工具&#xff1b;而在线业务团队对性能有更高的要求&#xff0c;他…

Dubbo——增强SPI的实现

一、前言 在Duboo剖析-整体架构分析中介绍了dubbo中除了Service 和 Config 层为 API外&#xff0c;其他各层均为SPI&#xff0c;为SPI意味着下面各层都是组件化可以被替换的&#xff0c;这也是dubbo比较好的一点。 二、JDK中标准SPI JDK 中的 SPI&#xff08;Service Provider…

【 .NET Core 3.0 】框架之二 || 后端项目搭建

前言至于为什么要搭建.Net Core 平台&#xff0c;这个网上的解释以及铺天盖地&#xff0c;想了想&#xff0c;还是感觉重要的一点&#xff0c;跨平台&#xff0c;嗯&#xff01;没错&#xff0c;而且比.Net 更容易搭建&#xff0c;速度也更快&#xff0c;所有的包均由Nuget提供…

怎样打造一个分布式数据库

本文来自&#xff1a;https://www.infoq.cn/article/how-to-build-a-distributed-database 文章写得很好&#xff0c;备份防丢失 在技术方面&#xff0c;我自己热衷于 Open Source&#xff0c;写了很多 Open Source 的东西&#xff0c;擅长的是 Infrastructure 领域。Infrastru…

向net core 3.0进击——Swagger的改变

前言十一小长假在不知不觉间可都没了&#xff0c;在这个小尾巴的空隙&#xff0c;把这两天鼓捣的net core 3.0升级过程记录一下&#xff0c;首先还是根据之前的顺序一个个补充进来&#xff0c;先从Swagger的变化说起&#xff08;新建工程什么的不多说了&#xff0c;就是选择的时…

Dubbo——面试问题集(1~3)

1、默认使用的是什么通信框架&#xff0c;还有别的选择吗? Dubbo默认使用netty&#xff0c;还支持mina, grizzy 配置方式&#xff1a; <dubbo:protocol name“dubbo” port“9090” server“netty” client“netty” codec“dubbo” serialization“hessian2” charset…