Использование GPIO для двоичного ввода
Контакты ввода-вывода общего назначения (GPIO) можно настроить для получения электрических сигналов в качестве входных данных. На самом базовом уровне это полезно для сценариев, которые обнаруживают открытие или закрытие цепи. Такие цепи могут включать в себя кнопки, выключатели, выключатели, выключатели, выключатели давления и другие устройства, которые представляют двоичные значения (вкл./выкл.) путем завершения цепи.
В этом руководстве вы будете использовать .NET и контакты GPIO Raspberry Pi для обнаружения открытия и закрытия цепи.
Предварительные требования
- Однопанеарный компьютер (SBC) на основе ARM (ARMv7 или более поздней версии)
- оптоволоконные кабеля с разъемами на обоих концах;
- Монтажная плата (необязательно)
- Коммутационная плата GPIO Raspberry Pi (необязательно)
- Пакет SDK для .NET 7 или более поздней версии
Примечание
В этом руководстве предполагается, что целевое устройство — Raspberry Pi. Однако это руководство можно использовать для любого SBC на базе Linux, поддерживающего .NET, например Orange Pi, ODROID и т. д.
Убедитесь, что на устройстве включен протокол SSH. Сведения о Raspberry Pi см. в разделе Настройка сервера SSH в документации по Raspberry Pi.
Подготовка оборудования
Используйте компоненты оборудования для создания цепи, как показано на следующей схеме:
На изображении выше показано прямое соединение между заземленным штырьем и контактом 21.
Совет
На схеме показана доска и прорыв GPIO в иллюстративных целях, но вы можете просто подключить заземленную булавку и булавку 21 с помощью перемычки на Raspberry Pi.
При необходимости смотрите следующую схему контактов:
Изображение взято с Raspberry Pi Foundation.
Создайте приложение
Выполните следующие действия в предпочитаемой среде разработки.
Создайте консольное приложение .NET с помощью .NET CLI или Visual Studio. Назовите его InputTutorial.
dotnet new console -o InputTutorial cd InputTutorial
Добавьте в проект пакет System.Device.Gpio . Используйте либо .NET CLI из каталога проекта, либо Visual Studio.
dotnet add package System.Device.Gpio --version 2.2.0-*
Замените содержимое 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
помощью .- Откроется контакт с задействованным резистором PullUp . В этом режиме, когда контакт подключен к земле, он возвращает
PinValue.Low
. Если контакт отсоединен от земли и цепь открыта, контакт возвращает .PinValue.High
- Откроется контакт с задействованным резистором PullUp . В этом режиме, когда контакт подключен к земле, он возвращает
- Начальное состояние записывается в консоль с помощью тернарного выражения. Текущее состояние закрепления считывается с помощью
Read()
. Если этоPinValue.High
, строка записываетсяAlert
в консоль. В противном случае он записываетReady
строку. -
RegisterCallbackForPinValueChangedEvent()
регистрирует функцию обратного вызова дляPinEventTypes.Rising
событий иPinEventTypes.Falling
в закреплении. Эти события соответствуют состояниямPinValue.High
закрепления иPinValue.Low
соответственно. - Функция обратного вызова указывает на метод с именем
OnPinEvent()
.OnPinEvent()
использует другое тернарное выражение, которое также записывает соответствующиеAlert
строки илиReady
. - Поток main постоянно переходит в спящий режим во время ожидания событий закрепления.
-
Объявление using создает экземпляр
Построение приложения. При использовании интерфейса командной строки .NET выполните команду
dotnet build
. Чтобы выполнить сборку в Visual Studio, нажмите клавиши CTRL+SHIFT+B.Разверните приложение в SBC как автономное приложение. Инструкции см. в статье Развертывание приложений .NET в Raspberry Pi. Обязательно предоставьте исполняемому файлу разрешение execute с помощью
chmod +x
.Запустите приложение на устройстве Raspberry Pi, перейдя в каталог развертывания и запустив исполняемый файл.
./InputTutorial
В консоли отображается следующий текст:
Initial status (05/10/2022 15:59:25): READY ✅
Отключите контакт 21 от земли. В консоли отображается следующий текст:
(05/10/2022 15:59:59) ALERT 🚨
Повторно подключите контакт 21 и заземление. В консоли отображается следующий текст:
(05/10/2022 16:00:25) READY ✅
Завершите работу программы, нажав клавиши CTRL+C.
Поздравляем! Вы использовали GPIO для обнаружения входных данных с помощью System.Device.Gpio
пакета NuGet! Этот тип входных данных используется во многих целях. Этот пример можно использовать в любом сценарии, где коммутатор подключает или разрывает цепь. Ниже приведен пример использования с магнитным орехом, который часто используется для обнаружения открытых дверей или окон.
Лазерный триппровод
Немного расширив предыдущий пример концепции, давайте рассмотрим, как это можно применить к созданию лазерного триппровода. Для создания лазерной tripwire требуются следующие дополнительные компоненты:
- Модуль лазерного передатчика KY-008
- Модуль датчика лазерного приемника (см. примечание ниже)
- 2 резистора Ω 10 000
Примечание
Модуль датчика лазерного приемника — это общее имя, применяемое к общему модулю, который можно найти во многих интернет-магазинах. Имя устройства может отличаться по имени или изготовителю, но оно должно напоминать этот образ.
Подключение лазерного оборудования tripwire
Подключите компоненты, как описано на следующей схеме.
Обратите особое внимание на резисторы Ω 10K. Они реализуют разделитель напряжения. Это связано с тем, что модуль лазерного приемника выводит 5 В, чтобы указать, что луч сломан. Raspberry Pi поддерживает только 3,3 В для ввода GPIO. Так как отправка полного 5 В на контакт может повредить Raspberry Pi, ток от модуля приемника проходит через делитель напряжения, чтобы вдвое снизить напряжение до 2,5 В.
Применение обновлений исходного кода
Вы можете использовать почти тот же код, что и ранее, за одним исключением. В других примерах мы использовали PinMode.InputPullUp
для того, чтобы при отключении контакта от земли и открытой цепи, контакт возвращал PinValue.High
.
Однако в случае с модулем лазерного приемника мы не обнаруживаем открытую цепь. Вместо этого мы хотим, чтобы контакт действовал в качестве приемника для тока, поступающего из модуля лазерного приемника. В этом случае мы откроем закрепление с PinMode.InputPullDown
помощью . Таким образом, контакт возвращается PinValue.Low
, когда он не получает ток, и PinValue.High
когда он получает ток от модуля лазерного приемника.
controller.OpenPin(pin, PinMode.InputPullDown);
Важно!
Перед тестированием лазерного триппровода убедитесь, что код, развернутый на устройстве Raspberry Pi, включает это изменение. Программа работает без него, но использование неправильного режима ввода рискует повредить ваш Raspberry Pi!
Получение исходного кода
Исходный код для этого учебника доступен на сайте GitHub.