IoTへの挑戦 Raspberry PiでWindows 10 IoT Coreを動かす(11)
■ボタンとLED点滅の新規プロジェクトの作成
サンプル・プログラムのBlinkyHeadlessとのPushButtonのLEDとプッシュ・ボタンの処理を一緒にして、
- GPIO5に接続されたLEDを500ms間隔で点滅
- GPIO6に接続されたLEDをGPIO26に接続されたプッシュ・スイッチでLEDを点滅
させます。プッシュ・スイッチの処理とLEDの点滅はサンプル・プログラムのPushButtonと同じですが、ウィンドウへの表示処理は削除してあります。
●新規のプロジェクトとして作成
今回は、新しくプロジェクトの作成から始めます。今までサンプルのプロジェクトを開いて修正していましたが、今後はサンプルがないものもあるので、新規にプロジェクトを作りました。
新規のプロジェクト作成は次に示すように、メニューバーの、
ファイル > 新規作成(N) > プロジェクト(P) |
を選択します。
●プロジェクト種類、プロジェクト名、格納場所を決める
次のウィンドウでテンプレートを選択してプロジェクトの種類を選択し、プロジェクト名、プロジェクトの格納場所を指定することができます。
次のウィンドウでは、プロジェクトを格納するフォルダ、プロジェクト名を任意のものに変更することもできます。
OKボタンをクリックすると、次に示すようにテンプレートが表示されます。
ソリューションエクスプローラの参照を確認すると、Windows Iot Extensions for the UWP がありません。Windows Iot Extensions for the UWPを参照できるようにメニューバーの、
プロジェクト(P) > 参照の追加(R) |
を選択し、参照マネージャのウィンドウを表示します。
Universal Windowsの拡張を選択し、。Windows Iot Extensions for the UWPをチェックしIotの処理の参照ができるようにします。OKボタンをクリックして新たな参照を追加します。
参照を追加し、プログラムを記述した結果を次に示します。
usingディレクティブで指定した名前空間を省略して記述できるようになります。今回使用している名前空間の指定のみ行っています。
// Copyright (c) Microsoft. All rights reserved. using System; using Windows.ApplicationModel.Background; using Windows.Devices.Gpio; using Windows.System.Threading; |
プロジェクトの名前と同じ名前空間が作られ、その中に今回のプログラムを記述していきます。
namespace pushbuttonheadless { |
クラスが記述されます。class StartupTaskの中に、Run()関数、InitGPIO()関数、 buttonPin_ValueChanged()関数、Timer_Tick()関数が記述されています。プログラムが起動されるとユーザ・プログラムが最初に実行されるのはRun()関数です。このRun()関数中でInitGPIO()関数でGPIOの初期化を行い、システム・タイマ設定を行いイベント待ちになります。
プッシュ・スイッチが押されたときbuttonPin_ValueChanged()関数が起動し、タイマが500msを計時するとTimer_Tick()関数が起動され、LEDの点滅の制御を行います。
public sealed class StartupTask : IBackgroundTask { BackgroundTaskDeferral deferral; private GpioPinValue value = GpioPinValue.High; private const int T_LED_PIN = 5; private GpioPin pin; private ThreadPoolTimer timer; private const int LED_PIN = 6; private const int BUTTON_PIN = 26; private GpioPin ledPin; private GpioPin buttonPin; private GpioPinValue ledPinValue = GpioPinValue.High; |
ここまでで、必要な変数、定数の設定を行っています。タイマによる点滅はGPIO5番ポート、プッシュ・スイッチはGPIO26番ポート、プッシュ・スイッチにより点滅するLEDはGPIO6番ポートと定義されています。
次のRun()関数は、遅延の処理、GPIOの初期化、タイマの設定を行っています。
public void Run(IBackgroundTaskInstance taskInstance) { deferral = taskInstance.GetDeferral(); InitGPIO(); timer=ThreadPoolTimer.CreatePeriodicTimer(Timer_Tick,TimeSpan.FromMilliseconds(500)); } |
●汎用入出力ポートGPIOの初期化
タイマ用のLEDのピンをPINとしてT_LED_PINを割り当てオープンし、利用できるようにしています。出力をHIGHに設定し、モードを出力ポートに設定します。同様にもう一つのLEDに接続するポートの初期化を行います。プッシュ・ボタンに接続されたボタンは内部プルアップに対応しているピンか調べ、対応しているピンなら内部プルアップを設定します。
private void InitGPIO() { pin = GpioController.GetDefault().OpenPin(T_LED_PIN); pin.Write(GpioPinValue.High); pin.SetDriveMode(GpioPinDriveMode.Output); var gpio = GpioController.GetDefault(); buttonPin = gpio.OpenPin(BUTTON_PIN); ledPin = gpio.OpenPin(LED_PIN); ledPin.Write(GpioPinValue.High); ledPin.SetDriveMode(GpioPinDriveMode.Output); if (buttonPin.IsDriveModeSupported(GpioPinDriveMode.InputPullUp)) buttonPin.SetDriveMode(GpioPinDriveMode.InputPullUp); else buttonPin.SetDriveMode(GpioPinDriveMode.Input); |
次の命令で、キー入力の最初の50msの間チャタリングによる誤入力を防止する期間として設定しています。
buttonPin.DebounceTimeout = TimeSpan.FromMilliseconds(50); buttonPin.ValueChanged += buttonPin_ValueChanged; } |
●ボタンが押されたとき
ボタンの状態が変化したとき、この関数が呼び出されます。キーが押されたときのみLEDの点滅状態を変更します。
private void buttonPin_ValueChanged(GpioPin sender, pioPinValueChangedEventArgs e) { if (e.Edge == GpioPinEdge.FallingEdge) { ledPinValue = (ledPinValue == GpioPinValue.Low) ? GpioPinValue.High : GpioPinValue.Low; ledPin.Write(ledPinValue); } } |
●タイマからの呼び出し
タイマが500msを計時したとき、この関数が呼び出されLEDの点滅状態を変更します。
private void Timer_Tick(ThreadPoolTimer timer) { value = (value == GpioPinValue.High) ? GpioPinValue.Low : GpioPinValue.High; pin.Write(value); } |
次のかっこは、classの終わりとnamespaceの終わりを示すものです。
} } |
以上で、今回作成したプログラムは完成し、デバッグで動作を確認しました。
(2016/4/19 V1.0)
<神崎康宏>
バックグラウンド
for the UWP;さまざまなデバイスで実行できるユニバーサル Windows プラットホーム用です。