0

0

张高兴的 .NET IoT 入门指南:(二)GPIO 的使用

蓮花仙者

蓮花仙者

发布时间:2025-06-28 11:20:10

|

588人浏览过

|

来源于php中文网

原创

什么是 gpio

GPIO 是 General Purpose Input Output 的缩写,即“通用输入输出”。Raspberry Pi 有两列 GPIO 引脚, Raspberry Pi 通过这两行引脚进行一些硬件上的扩展,与传感器进行交互等等。

张高兴的 .NET IoT 入门指南:(二)GPIO 的使用

Raspberry Pi B+/2B/3B/3B+/Zero 引脚图

简单的讲,每一个 GPIO 引脚都有两种模式:输出模式(OUTPUT)和输入模式(INPUT)。输出模式类似于一个电源,Raspberry Pi 可以控制这个电源是否向外供电,比如打开外部的 LED 小灯,当然最有用的还是向外部设备发送信号。和输出模式相反,输入模式是接收外部设备发来的信号。其中还包含两种特殊的输入模式:上拉输入(INPUT_PULLUP)和下拉输入(INPUT_PULLDOWN)。上拉输入就是内部的上拉电阻接 VCC ,将该引脚设置为高电平,下拉输入则相反。

GPIO 通常采用标准逻辑电平,即高电平和低电平,用二进制 0 和 1 表示。在这两值中间还有阈值电平,即高电平和低电平之间的界限。Arduino 会将 -0.5 ~ 1.5 V 读取为低电平,3 ~ 5.5 V 读取为高电平, Raspberry Pi 未查到相关资料。GPIO 还可用于中断请求,即设置 GPIO 为输入模式,值达到相应的要求时进行中断。

相关类

GPIO 操作主要依赖于 GpioController 类 。这个类位于 System.Device.Gpio 名称空间下。

GpioController代码语言:javascript代码运行次数:0运行复制
// GpioController 即 GPIO 控制器// GPIO 引脚依靠 GpioController 初始化public class GpioController : IGpioController, IDisposable{    // 构造函数    public GpioController();    // PinNumberingScheme 即引脚编号方案,是一个枚举类型,包含 Board 和 Logical 两个值。    // 可以看上方的 Raspberry Pi 引脚图,以 GPIO 17 为例,如果实例化时选 Logical ,那么打开引脚时需要填写 17。    // 如果实例化时选 Board ,那么打开引脚时需要填写右侧灰色方框内的值,即 11 。    public GpioController(PinNumberingScheme numbering);    // GpioDriver 用于指定要使用的 GPIO 驱动,比如 libgpiod 或 sysfs    public GpioController(PinNumberingScheme numberingScheme, GpioDriver driver);    // 方法    // 打开 GPIO 引脚    // pinNumber 需要填写和 PinNumberingScheme 相对应的值。    // PinMode 是设置 GPIO 的模式,如输入、输出、上拉、下拉    public void OpenPin(int pinNumber, PinMode mode);    // 关闭 GPIO 引脚    public void ClosePin(int pinNumber);    // 判断某个引脚是否打开    // 注意:引脚连续打开会抛出异常    public bool IsPinOpen(int pinNumber);     // 读取指定引脚的值    public PinValue Read(int pinNumber);    // 向指定的引脚写入值    public void Write(int pinNumber, PinValue value);    // 为指定引脚的值改变时注册回调(即上文中提到的 GPIO 中断)    // PinEventTypes 是值改变的类型,包括上升沿(Rising,0->1)和下降沿(Falling,1->0),注意当设置为 None 时不会触发    // PinChangeEventHandler 为回调事件    public void RegisterCallbackForPinValueChangedEvent(int pinNumber, PinEventTypes eventTypes, PinChangeEventHandler callback);    // 为指定引脚的值改变时注销回调    public void UnregisterCallbackForPinValueChangedEvent(int pinNumber, PinChangeEventHandler callback);}

人体红外传感器实验

人体红外传感器是基于周围区域的红外热来检测运动的,也称被动红外传感器(Passive Infra-Red, PIR)。这里使用的是 HC-SR501 。当传感器检测到人体时,LED 小灯亮,当传感器未检测到人体时,LED 小灯灭。

传感器图像
张高兴的 .NET IoT 入门指南:(二)GPIO 的使用

HC-SR501

硬件需求

名称

数量

HC-SR501

x1

知了追踪
知了追踪

AI智能信息助手,智能追踪你的兴趣资讯

下载

LED 小灯

x1

220 Ω 电阻

x1

杜邦线

若干

电路

张高兴的 .NET IoT 入门指南:(二)GPIO 的使用

HC-SR501

VCC - 5VGND - GNDOUT - GPIO 17 (Pin 11)

LED

VCC & 220 Ω resistor - GPIO 27 (Pin 14)GND - GND

使用 Docker 运行示例

示例地址:https://github.com/ZhangGaoxing/dotnet-core-iot-demo/tree/master/src/Hcsr501

代码语言:javascript代码运行次数:0运行复制
docker build -t pir-sample -f Dockerfile .docker run --rm -it --device /dev/gpiomem pir-sample

代码

打开 Visual Studio ,新建一个 .NET Core 控制台应用程序,项目名称为“PIR”。

引入 System.Device.Gpio NuGet 包。

新建类 Hcsr501,替换如下代码:

代码语言:javascript代码运行次数:0运行复制
public class Hcsr501 : IDisposable{    private GpioController _controller;    private readonly int _outPin;    ///     /// 构造函数    ///     /// OUT Pin    public HCSR501(int outPin, PinNumberingScheme pinNumberingScheme = PinNumberingScheme.Logical)    {        _outPin = outPin;        _controller = new GpioController(pinNumberingScheme);        _controller.OpenPin(outPin, PinMode.Input);    }    ///     /// 是否检测到人体    ///     public bool IsMotionDetected => _controller.Read(_outPin) == PinValue.High;    ///     /// Cleanup    ///     public void Dispose()    {        _controller?.Dispose();        _controller = null;    }}

在 Program.cs 中,将主函数代码替换如下:

代码语言:javascript代码运行次数:0运行复制
static void Main(string[] args){    // HC-SR501 OUT Pin    int hcsr501Pin = 17;    // LED Pin    int ledPin = 27;    // 获取 GPIO 控制器    using GpioController ledController = new GpioController(PinNumberingScheme.Logical);    // 初始化 PIR 传感器    using Hcsr501 sensor = new Hcsr501(hcsr501Pin, PinNumberingScheme.Logical);    // 打开 LED 引脚    ledController.OpenPin(ledPin, PinMode.Output);    while (true)    {        // 检测到了人体        if (sensor.IsMotionDetected == true)        {            ledController.Write(ledPin, PinValue.High);            Console.WriteLine("Detected! Turn the LED on.");        }        else        {            ledController.Write(ledPin, PinValue.Low);            Console.WriteLine("Undetected! Turn the LED off.");        }        Thread.Sleep(1000);    }}

发布、拷贝、更改权限、运行

效果图

张高兴的 .NET IoT 入门指南:(二)GPIO 的使用
张高兴的 .NET IoT 入门指南:(二)GPIO 的使用

? 如何改进?

剔除主函数循环,尝试使用 RegisterCallbackForPinValueChangedEvent() 注册一个回调进行检测。

参考General-purpose input/output - Wikipedia:https://en.wikipedia.org/wiki/General-purpose_input/outputGPIO - Raspberry Pi Documentation:https://www.raspberrypi.org/documentation/usage/gpio/GPIO source code:https://github.com/dotnet/iot/tree/master/src/System.Device.Gpio/System/Device/Gpio

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

554

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

374

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

731

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

477

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

394

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

990

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

656

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

551

2023.09.20

java数据库连接教程大全
java数据库连接教程大全

本专题整合了java数据库连接相关教程,阅读专题下面的文章了解更多详细内容。

20

2026.01.15

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Git 教程
Git 教程

共21课时 | 2.7万人学习

Git版本控制工具
Git版本控制工具

共8课时 | 1.5万人学习

Git中文开发手册
Git中文开发手册

共0课时 | 0人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号