通过


将 GPIO 用于二进制输入

通用 I/O (GPIO) 引脚可配置为接收电信号作为输入。 在最基本的级别,这对于检测线路的打开/关闭的方案非常有用。 此类电路可能包括按钮、拨动开关、簧片开关、压力开关及其他设备,这些设备通过完成电路来表示二进制(开/关)值。

在本教程中,你将使用 .NET 和 Raspberry Pi 的 GPIO 引脚来检测线路的开始和关闭。

先决条件

  • 基于 ARM 的单板计算机(ARMv7 或更高版本)(SBC)
  • 跳线
  • 面包板 (可选)
  • 树莓派 GPIO 扩展板(可选)
  • .NET SDK 10 或更高版本

注释

本教程编写为假设目标设备为 Raspberry Pi。 但是,本教程可用于支持.NET的任何基于 Linux 的 SBC,例如 Orange Pi、ODROID 等。

确保设备上启用了 SSH。 对于 Raspberry Pi,请参阅 Raspberry Pi 文档中的 SSH 服务器设置

准备硬件

使用硬件组件生成线路,如下图所示:

显示将接地引脚连接到引脚 21 的电路图。

上图描绘了接地引脚和引脚 21 之间的直接连接。

小提示

出于说明目的,该图显示了线路板和 GPIO 分线,你可以随意将接地引脚和引脚 21 与 Raspberry Pi 上的跳线连接起来。

根据需要,请参阅以下引脚分配关系图:

Raspberry Pi GPIO 接头引脚排列图。图片由 Raspberry Pi 基金会提供。
图片由 Raspberry Pi Foundation 提供

创建应用

在首选开发环境中完成以下步骤:

  1. 使用 .NET CLIVisual Studio 创建新的.NET控制台应用。 将其命名 为 InputTutorial

    dotnet new console -o InputTutorial
    cd InputTutorial
    
  2. System.Device.Gpio 包添加到项目。 使用项目目录中的 .NET CLIVisual Studio

    dotnet package add System.Device.Gpio --version 4.0.1
    
  3. 将 Program.cs 的内容替换为以下代码:

    using System.Device.Gpio;
    using System.Threading.Tasks;
    
    const int Pin = 21;
    const string Alert = "ALERT 🚨";
    const string Ready = "READY ✅";
    
    using var controller = new GpioController();
    controller.OpenPin(Pin, PinMode.InputPullUp);
    
    Console.WriteLine(
        $"Initial status ({DateTime.Now}): {(controller.Read(Pin) == PinValue.High ? Alert : Ready)}");
    
    controller.RegisterCallbackForPinValueChangedEvent(
        Pin,
        PinEventTypes.Falling | PinEventTypes.Rising,
        OnPinEvent);
    
    await Task.Delay(Timeout.Infinite);
    
    static void OnPinEvent(object sender, PinValueChangedEventArgs args)
    {     
        Console.WriteLine(
            $"({DateTime.Now}) {(args.ChangeType is PinEventTypes.Rising ? Alert : Ready)}");
    }
    

    在前面的代码中:

    • using 声明创建一GpioController个实例。 声明 using 可确保对象被妥善处理并释放硬件资源。
      • GpioController 实例化时没有参数,指示它应检测正在运行的硬件平台,并使用 逻辑引脚编号方案
    • GPIO 引脚 21 已使用 PinMode.InputPullUp 打开。
      • 这将激活引脚并接入 上拉电阻。 在此模式下,当引脚连接到地面时,它将返回 PinValue.Low。 当引脚断开与接地的连接并且电路处于开路状态时,引脚返回PinValue.High
    • 初始状态使用三元表达式写入控制台。 引脚的当前状态通过 Read() 读取。 PinValue.High如果是,则会将Alert字符串写入控制台。 否则,它会写入 Ready 字符串。
    • RegisterCallbackForPinValueChangedEvent() 为引脚上的 PinEventTypes.RisingPinEventTypes.Falling 事件注册回调函数。 这些事件分别对应于引脚状态 PinValue.HighPinValue.Low
    • 回调函数指向调用 OnPinEvent()的方法。 OnPinEvent() 使用另一个同时写入相应 AlertReady 字符串的三元表达式。
    • 主线程在等待引脚事件时无限期休眠。
  4. 构建应用程序。 如果使用 .NET CLI,请运行 dotnet build。 若要在 Visual Studio 中生成,请按 Ctrl+Shift+B

  5. 将应用作为独立应用部署到 SBC。 有关说明,请参阅 将 .NET 应用部署到 Raspberry Pi。 请确保使用 .. 授予可执行文件chmod +x权限。

  6. 切换到部署目录并运行可执行文件,在 Raspberry Pi 上运行应用。

    ./InputTutorial
    

    控制台显示类似于以下内容的文本:

    Initial status (05/10/2022 15:59:25): READY ✅
    
  7. 断开引脚 21 与地面的连接。 控制台显示类似于以下内容的文本:

    (05/10/2022 15:59:59) ALERT 🚨
    
  8. 重新连接引脚 21 和地面。 控制台显示类似于以下内容的文本:

    (05/10/2022 16:00:25) READY ✅
    
  9. Ctrl+C 终止程序。

祝贺! 你已使用 GPIO 来检测使用 NuGet 包的 System.Device.Gpio 输入! 此类型的输入有许多用途。 此示例可用于任何开关连接或中断线路的方案。 下面是一个示例,它与磁力开关一起使用,通常用于检测打开的门或窗户。

动画 GIF 演示磁簧开关的打开和关闭。开关靠近磁铁,应用显示 READY。将磁体移开,应用显示 ALERT。然后重复该动作。

激光绊线

进一步扩展前面的示例概念,让我们看看如何将其应用于创建激光行程线。 生成激光绊线需要以下附加组件:

  • KY-008 激光发射机模块
  • 激光接收器传感器模块 (请参阅以下说明)
  • 2 个 10K Ω 电阻

注释

激光接收器传感器模块 是应用于许多互联网零售商的通用模块的通用名称。 设备的名称或制造商可能有所不同,但应类似于此映像。

激光接收器传感器模块的图像

连接激光绊线硬件

按照下面的图示连接组件。

显示接收来自激光接收器传感器模块输入的电路的示意图。

请密切关注 10KΩ 电阻。 这些实现 分压器。 这是因为激光接收器模块输出 5V 以指示梁已损坏。 Raspberry Pi 仅支持最多 3.3V 的 GPIO 输入。 由于将完整的 5V 发送到引脚可能会损坏 Raspberry Pi,接收器模块的电流通过电压除法器传递,将电压减半到 2.5V。

应用源代码更新

您可以几乎使用之前相同的代码,但存在一个例外情况。 在其他示例中,我们使用了PinMode.InputPullUp,以便当引脚断开与地连接且线路断开时,引脚将返回PinValue.High

但对于激光接收器模块,我们没有检测到线路开路。 相反,我们希望将该引脚用作接收器,以接收激光接收器模块的电流。 在本例中,我们将打开PinMode.InputPullDown。 引脚在没有接收到电流时返回 PinValue.Low,当它从激光接收器模块接收到电流时返回 PinValue.High

controller.OpenPin(pin, PinMode.InputPullDown);

重要

在测试激光行程线之前,请确保在 Raspberry Pi 上部署的代码包含此更改。 程序 确实可以 没有它运行,但使用错误的输入模式可能会损坏你的 Raspberry Pi!

显示激光绊线演示的动画 GIF。激光发射器将激光传感器模块点亮,应用程序显示“已准备好”。激光束被打断,应用程序显示“警报”。然后重复该动作。

获取源代码

本教程的源码可以在 GitHub 上找到。

后续步骤