バイナリ入力に GPIO を使用する
汎用 I/O (GPIO) ピンは、電気信号を入力として受信するように構成できます。 最も基本的なレベルでは、これは回路の開閉を検出するシナリオに役立ちます。 このような回路には、プッシュ ボタン、トグル スイッチ、リード スイッチ、圧力スイッチ、および回路を完了することによってバイナリ (オン/オフ) 値を表すその他のデバイスが含まれる場合があります。
このチュートリアルでは、.NET と Raspberry Pi の GPIO ピンを使用して、回路の開閉を検出します。
前提条件
- ARM ベース (ARMv7 以降) シングルボード コンピューター (SBC)
- ジャンパー ワイヤ
- ブレッドボード (省略可能)
- Raspberry Pi GPIO ブレークアウト基板 (省略可能)
- .NET SDK 7 以降
注意
このチュートリアルは、ターゲット デバイスを Raspberry Pi と想定して記述されています。 ただし、このチュートリアルは、Orange Pi や ODROID など、.NET をサポートしているあらゆる Linux ベースの SBC に利用できます。
デバイスで SSH が有効になっていることを確認します。 Raspberry Pi については、Raspberry Pi のドキュメントの「SSH サーバーの設定」を参照してください。
ハードウェアを準備する
ハードウェア コンポーネントを使用して、次の図に示すような回路を構築します。
上の図は、グラウンド ピンとピン 21 の直接接続を示しています。
ヒント
図は、例示する目的でブレッドボードと GPIO ブレークアウトを示していますが、Raspberry Pi のジャンパー ワイヤーでグラウンド ピンとピン 21 をご自由に接続してみてください。
必要に応じて、次のピン配列図を参照してください。
画像提供: Raspberry Pi Foundation。
アプリを作成する
お好みの開発環境で、次の手順を実行します。
.NET CLI または Visual Studio を使用して、新しい .NET コンソール アプリを作成します。 これに InputTutorial という名前を付けます。
dotnet new console -o InputTutorial cd InputTutorial
System.Device.Gpio パッケージをプロジェクトに追加します。 プロジェクト ディレクトリまたは Visual Studio から .NET CLI を使用します。
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
で開かれます。- これにより、"プルアップ" 抵抗があるピンが開きます。 このモードでは、ピンがグラウンドに接続されると、
PinValue.Low
が返されます。 ピンがグラウンドから切断され、回路が開いていると、ピンからPinValue.High
が返されます。
- これにより、"プルアップ" 抵抗があるピンが開きます。 このモードでは、ピンがグラウンドに接続されると、
- 初期状態は、三項式を使用してコンソールに書き込まれます。 ピンの現在の状態は、
Read()
で読み取ります。PinValue.High
の場合は、コンソールにAlert
文字列が書き込まれます。 それ以外の場合は、Ready
文字列が書き込まれます。 -
RegisterCallbackForPinValueChangedEvent()
は、ピンのPinEventTypes.Rising
およびPinEventTypes.Falling
イベントの両方のコールバック関数を登録します。 これらのイベントは、ピンの状態のそれぞれPinValue.High
とPinValue.Low
に対応します。 - コールバック関数は、
OnPinEvent()
というメソッドを指します。OnPinEvent()
により、対応するAlert
またはReady
文字列も書き込む別の三項式を使用します。 - メイン スレッドは、ピン イベントを待機している間、無期限にスリープ状態になります。
-
using 宣言によって、
アプリをビルドします。 .NET CLI を使用している場合は、
dotnet build
を実行します。 Visual Studio でビルドするには、Ctrl+Shift+B キーを押します。アプリを自己完結型アプリとして SBC にデプロイします。 手順については、「Raspberry Pi への .NET アプリのデプロイ」を参照してください。
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 キーを押してプログラムを終了します。
おめでとうございます。
System.Device.Gpio
NuGet パッケージを使用して GPIO を使用して入力を検出しました。 この種類の入力には多くの用途があります。 この例は、スイッチと回路の接続または切断のあらゆるシナリオで使用できます。 次に、開いているドアや窓の検出によく使用される磁気リードスイッチでそれを使用する例を示します。
レーザー トリップワイヤー
前の例の概念をさらに拡張して、これがレーザー トリップ ワイヤーの作成にどのように適用されるかを見てみましょう。 レーザー トリップ ワイヤーを構築するには、次の追加コンポーネントが必要です。
- KY-008 レーザー トランスミッタ モジュール
- レーザー レシーバー センサー モジュール ("下記の「注」を参照")
- 10K Ω 抵抗 (2 個)
注意
"レーザー レシーバー センサー モジュール" は、多くのインターネット上の販売店で見られる一般的なモジュールに使用される総称です。 デバイスの名前や製造元は異なる場合がありますが、この画像のようなものです。
レーザー トリップ ワイヤー ハードウェアを接続する
次の図に示すように、コンポーネントを接続します。
10K のΩ抵抗には細心の注意を払ってください。 これらは分圧器を実装します。 これは、レーザー レシーバー モジュールが、ビームが破損したことを示すために 5 V を出力しているためです。 Raspberry Pi が GPIO 入力に対してサポートするのは、最大 3.3 V までです。 ピンに完全に 5 V を送信すると Raspberry Pi が損傷するおそれがあるため、レシーバー モジュールからの電流は分圧器を通過して電圧を半分の 2.5 V にします。
ソース コードの更新を適用する
以前と "ほぼ" 同じコードを使用できますが、例外が 1 つあります。 他の例では、ピンがグラウンドから切断され、回路が開いているときにピンが PinValue.High
を返すように PinMode.InputPullUp
を使用しました。
ただし、レーザー レシーバー モジュールの場合、開回路を検出していません。 代わりに、レーザー レシーバー モジュールからの電流のシンクとしてピンを機能させる必要があります。 この場合は、PinMode.InputPullDown
でピンを開きます。 このようにして、ピンは電流を受けていないときに PinValue.Low
を返し、レーザー レシーバー モジュールから電流を受け取るときに PinValue.High
を返します。
controller.OpenPin(pin, PinMode.InputPullDown);
重要
レーザー トリップ ワイヤーをテストする前に、Raspberry Pi に展開されているコードにこの変更が含まれていることをご確認ください。 プログラムは、それがなくても "動作します" が、間違った入力モードを使用すると、Raspberry Pi が損傷するおそれがあります。
ソース コードを入手する
このチュートリアルのソースは、GitHub から入手できます。
次のステップ
.NET