首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >张高兴的 .NET Core IoT 入门指南:(二)GPIO 的使用

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

作者头像
张高兴
发布2019-02-26 10:30:19
1.5K0
发布2019-02-26 10:30:19
举报
文章被收录于专栏:张高兴的博客张高兴的博客

什么是 GPIO

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

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

简单的讲,每一个 GPIO 引脚都有两种模式:输出模式(OUTPUT)和输入模式(INPUT)。输出模式类似于一个电源,Raspberry Pi 可以控制这个电源是否向外供电,比如打开外部的 LED 小灯,当然最有用的还是向外部设备发送信号。输入模式相当于电源的阴极,还是以 LED 小灯为例,只不过这次 LED 小灯的阳极接着外部电源,一个电路只有产生电压差时才会有电流,因此要想让小灯亮需要让电流流入 Raspberry Pi 中。和输出模式相反,输入模式是接收外部设备发来的信号。

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

相关类(Class)

此处默认各位是面向对象的程序员,具有一定的 C# 基础,这里只介绍本人认为常用的方法,介绍将以代码注释的形式体现。

GPIO 操作主要依赖于两个类: GpioControllerGpioPin 。这两个类位于 System.Devices.Gpio 名称空间下。

GpioController

// GpioController 即 GPIO 控制器
// GPIO 引脚依靠 GpioController 初始化
public class GpioController : IDisposable
{
    // 构造函数
    /* PinNumberingScheme 即引脚编号方案,是一个枚举类型,包含 Board 和 Gpio 两个值。 
     * 可以看上方的 Raspberry Pi 引脚图,以 GPIO 17 为例,如果实例化时选 Gpio ,那么打开引脚时需要填写 17。
     * 如果实例化时选 Board ,那么打开引脚时需要填写右侧灰色方框内的值,即 11 。
    */
    public GpioController(PinNumberingScheme numbering = PinNumberingScheme.Gpio);
    // 第二个构造函数中的 GpioDriver 应该是用于扩展的,一般还是用 Raspberry Pi 默认的 GPIO 驱动。
    public GpioController(GpioDriver driver, PinNumberingScheme numbering = PinNumberingScheme.Gpio);

    // 属性
    // 获取已打开的所有 GPIO 引脚
    public IEnumerable<GpioPin> OpenPins { get; }

    // 方法
    // 打开 GPIO 引脚,pinNumber 需要填写和 PinNumberingScheme 相对应的值。
    public GpioPin OpenPin(int pinNumber);
    // 关闭 GPIO 引脚
    public void ClosePin(int pinNumber);
    public void ClosePin(GpioPin pin);
    // 判断某个引脚是否打开
    // 注意:引脚连续打开会抛出异常
    public bool IsPinOpen(int pinNumber); 
}

GpioPin

// GpioPin 表示单个的引脚实体
// 需要通过 GpioController.OpenPin() 获取
public class GpioPin : IDisposable
{
    // 属性
    // 一个去抖时间,即在此时间间隔引脚电平变化,不触发 ValueChanged 事件
    public TimeSpan DebounceTimeout { get; set; }

    // 事件
    // 引脚电平变化时触发
    public event EventHandler<PinValueChangedEventArgs> ValueChanged;

    // 方法
    // 读取当前引脚电平
    public PinValue Read();
    // 向引脚写入指定电平
    public void Write(PinValue value);
}

人体红外传感器实验

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

人体红外传感器是基于周围区域的红外热来检测运动的,也称被动红外传感器(Passive Infra-Red, PIR)。

这里使用的是 HC-SR501 。当传感器检测到人体时,LED 小灯亮,当传感器未检测到人体时,LED 小灯灭。

传感器图像

HC-SR501

硬件

名称

数量

HC-SR501

x1

LED 小灯

x1

220 Ω 电阻

x1

杜邦线

若干

电路

HC-SR501

  • VCC - 5V
  • GND - GND
  • OUT - GPIO 17

LED

  • VCC & 220 Ω resistor - GPIO 27
  • GND - GND

代码

  1. 打开 Visual Studio ,新建一个 .NET Core 控制台应用程序,项目名称为“PIR”。
  2. 引入 System.Devices.Gpio NuGet 包。
  3. 新建类 HCSR501,替换如下代码(此处略有精简,只为必要的代码,不包含自定义事件,详细可查看提供的示例): public class HCSR501 : IDisposable { private GpioPin sensor; private readonly int pinOut; /// <summary> /// 构造函数 /// </summary> /// <param name="pin">OUT Pin</param> public HCSR501(int pin) { pinOut = pin; } /// <summary> /// 初始化 /// </summary> public void Initialize() { // 实例化 GpioController GpioController controller = new GpioController(PinNumberingScheme.Gpio); // 打开引脚,设置模式为输入模式 sensor = controller.OpenPin(pinOut, PinMode.Input); } /// <summary> /// 读取 /// </summary> /// <returns>是否检测到人体</returns> public bool Read() { // 当电平为高时,认为检测到人体 if (sensor.Read() == PinValue.High) { return true; } else { return false; } } }
  4. Program.cs 中,将主函数代码替换如下: static void Main(string[] args) { // get the GPIO controller // 获取 GPIO 控制器 GpioController controller = new GpioController(PinNumberingScheme.Gpio); // open PIN 27 for led // 为 led 打开引脚 27 GpioPin led = controller.OpenPin(27, PinMode.Output); // initialize PIR sensor // 初始化传感器 HCSR501 sensor = new HCSR501(17); sensor.Initialize(); // loop // 循环 while (true) { if (sensor.Read() == true) { // turn the led on when the sensor detected infrared heat // 当传感器检测到热量时打开 led led.Write(PinValue.High); Console.WriteLine("Detected! Turn the LED on."); } else { // turn the led off when the sensor undetected infrared heat // 当传感器未检测到热量时关闭 led led.Write(PinValue.Low); Console.WriteLine("Undetected! Turn the LED off."); } // wait for a second // 等待 1s Thread.Sleep(1000); } }
  5. 发布、拷贝、更改权限、运行

效果图

  如何改进?

剔除主函数循环,尝试在自定义事件中进行检测,即 GpioPin 的 ValueChanged 事件。


  备注

下一篇文章将谈谈 IIC 总线的使用。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-01-27 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 什么是 GPIO
  • 相关类(Class)
    • GpioController
      • GpioPin
      • 人体红外传感器实验
        • 传感器图像
          • 硬件
            • 电路
              • 代码
                • 效果图
                相关产品与服务
                云函数
                云函数(Serverless Cloud Function,SCF)是腾讯云为企业和开发者们提供的无服务器执行环境,帮助您在无需购买和管理服务器的情况下运行代码。您只需使用平台支持的语言编写核心代码并设置代码运行的条件,即可在腾讯云基础设施上弹性、安全地运行代码。云函数是实时文件处理和数据处理等场景下理想的计算平台。
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档