Использование 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.

На изображении выше показано прямое соединение между заземленным штырьем и контактом 21.

Совет

На схеме показана доска и прорыв GPIO в иллюстративных целях, но вы можете просто подключить заземленную булавку и булавку 21 с помощью перемычки на Raspberry Pi.

При необходимости смотрите следующую схему контактов:

Диаграмма, показывающая схему контактов верхнего контактного ряда GPIO Raspberry Pi. Изображение взято с Raspberry Pi Foundation.
Изображение взято с Raspberry Pi Foundation.

Создайте приложение

Выполните следующие действия в предпочитаемой среде разработки.

  1. Создайте консольное приложение .NET с помощью .NET CLI или Visual Studio. Назовите его InputTutorial.

    dotnet new console -o InputTutorial
    cd InputTutorial
    
  2. Добавьте в проект пакет System.Device.Gpio . Используйте либо .NET CLI из каталога проекта, либо Visual Studio.

    dotnet add package System.Device.Gpio --version 2.2.0-*
    
  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 гарантирует, что объект удален и аппаратные ресурсы освобождены должным образом.
    • Контакт GPIO 21 открывается с PinMode.InputPullUpпомощью .
      • Откроется контакт с задействованным резистором PullUp . В этом режиме, когда контакт подключен к земле, он возвращает PinValue.Low. Если контакт отсоединен от земли и цепь открыта, контакт возвращает .PinValue.High
    • Начальное состояние записывается в консоль с помощью тернарного выражения. Текущее состояние закрепления считывается с помощью Read(). Если это PinValue.High, строка записывается Alert в консоль. В противном случае он записывает Ready строку.
    • RegisterCallbackForPinValueChangedEvent() регистрирует функцию обратного вызова для PinEventTypes.Rising событий и PinEventTypes.Falling в закреплении. Эти события соответствуют состояниям PinValue.High закрепления и PinValue.Lowсоответственно.
    • Функция обратного вызова указывает на метод с именем OnPinEvent(). OnPinEvent() использует другое тернарное выражение, которое также записывает соответствующие Alert строки или Ready .
    • Поток main постоянно переходит в спящий режим во время ожидания событий закрепления.
  4. Построение приложения. При использовании интерфейса командной строки .NET выполните команду dotnet build. Чтобы выполнить сборку в Visual Studio, нажмите клавиши CTRL+SHIFT+B.

  5. Разверните приложение в SBC как автономное приложение. Инструкции см. в статье Развертывание приложений .NET в Raspberry Pi. Обязательно предоставьте исполняемому файлу разрешение execute с помощью 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 для обнаружения входных данных с помощью System.Device.Gpio пакета NuGet! Этот тип входных данных используется во многих целях. Этот пример можно использовать в любом сценарии, где коммутатор подключает или разрывает цепь. Ниже приведен пример использования с магнитным орехом, который часто используется для обнаружения открытых дверей или окон.

Анимированный GIF-файл, демонстрирующий открытие и закрытие переключателя с магнитным орехом. Переключатель предоставляется магниту, а приложение отображает готово. Магнит удаляется, а приложение отображает оповещение. Затем действие повторяется.

Лазерный триппровод

Немного расширив предыдущий пример концепции, давайте рассмотрим, как это можно применить к созданию лазерного триппровода. Для создания лазерной 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!

Анимированный GIF-файл, показывающий демонстрацию лазерного триппровода. Лазерный излучатель освещает модуль лазерного датчика, и приложение отображает готово. Лазерный луч сломан, и приложение отображает оповещение. Затем действие повторяется.

Получение исходного кода

Исходный код для этого учебника доступен на сайте GitHub.

Дальнейшие действия