LoginSignup
3
0

More than 5 years have passed since last update.

最初のLチカができたので、次は物理的なボタンをつけてみましょう。
Lチカの場合は、電流の出力系で、物理ボタンの場合は、電流の入力系なのでワンセットで試しておきます。

ボタンのサンプル

Push button | Windows IoT

物理ボタンを押したら、LED が光るサンプルがあります。ここでは、えらいきちんとしたボタンを使っていますが、30円のタクトスイッチとか、そもそもボタンを使わずにジャンパワイヤー同士を接触させるだけでも構いません。

ちょっと高めですが、千石電子 せんごくネット通販 に行くとアーケードゲーム用のボタンを売っているので、これを使うこともできます。

配線はこんな感じで、

  • 5番ピンにボタン
  • 6番ピンにLED

をつけます。例によって、ジャンパーワイヤーの色は自由に決めて構いません。

001.jpg

コードを見る

参照設定で「Windows IoT Extension SDK」を追加しておくところは同じで、先頭の行に「Windows.Devices.Gpio」を追加。

using Windows.Devices.Gpio;

初期化は起動時に InitGPIO メソッド内で行っています。

private void InitGPIO()
{
    var gpio = GpioController.GetDefault();

    // Show an error if there is no GPIO controller
    if (gpio == null)
    {
        GpioStatus.Text = "There is no GPIO controller on this device.";
        return;
    }

    buttonPin = gpio.OpenPin(BUTTON_PIN);
    ledPin = gpio.OpenPin(LED_PIN);

    // Initialize LED to the OFF state by first writing a HIGH value
    // We write HIGH because the LED is wired in a active LOW configuration
    ledPin.Write(GpioPinValue.High); 
    ledPin.SetDriveMode(GpioPinDriveMode.Output);

    // Check if input pull-up resistors are supported
    if (buttonPin.IsDriveModeSupported(GpioPinDriveMode.InputPullUp))
        buttonPin.SetDriveMode(GpioPinDriveMode.InputPullUp);
    else
        buttonPin.SetDriveMode(GpioPinDriveMode.Input);

    // Set a debounce timeout to filter out switch bounce noise from a button press
    buttonPin.DebounceTimeout = TimeSpan.FromMilliseconds(50);

    // Register for the ValueChanged event so our buttonPin_ValueChanged 
    // function is called when the button is pressed
    buttonPin.ValueChanged += buttonPin_ValueChanged;

    GpioStatus.Text = "GPIO pins initialized correctly.";
}
  1. GpioController.GetDefault で gpio を取得
  2. gpio.OpenPin で BUTTON_PIN(5) をオープン
  3. gpio.OpenPin で LED_PIN(6) をオープン
  4. ledPin.SetDriveMode で、LED をアウトプットモード(出力モード)に設定
  5. buttonPin.SetDriveMode でボタンをインプットモード(入力モード)に設定。ピンによってプルアップなどの設定があるので、これを IsDriveModeSupported 自動判別しています。
  6. buttonPin.DebounceTimeout でチャタリングの時間間隔を設定。物理ボタンの場合、ボタンを押した瞬間は ON/OFF が交互に現れるチャタリングという現象が起こります。このために、50msec ON/OFF の状態が続いたらボタンが変化したという設定になります。これは、スマートフォンやディスプレイでは起こらない現象(実は内部的に起こっているけど、ソフトウェア的に回避している)ので、物理ボタン特有の面白いところです。
  7. buttonPin.ValueChanged で、ボタンの変更時にイベントを発生させます。ここは、Windows アプリケーションを作ったときのイベント処理と同じです。

次に、ボタンの状態が変更したときのイベントを作ります。

private void buttonPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e)
{
    // toggle the state of the LED every time the button is pressed
    if (e.Edge == GpioPinEdge.FallingEdge)
    {
        ledPinValue = (ledPinValue == GpioPinValue.Low) ?
            GpioPinValue.High : GpioPinValue.Low;
        ledPin.Write(ledPinValue);
    }

    // need to invoke UI updates on the UI thread because this event
    // handler gets invoked on a separate thread.
    var task = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => {
        if (e.Edge == GpioPinEdge.FallingEdge)
        {
            ledEllipse.Fill = (ledPinValue == GpioPinValue.Low) ? 
                redBrush : grayBrush;
            GpioStatus.Text = "Button Pressed";
        }
        else
        {
            GpioStatus.Text = "Button Released";
        }
    });
}
  1. ボタンの状態は、e.Edge でチェックをします。GpioPinEdge.FallingEdge は、状態が変化したという印です。
  2. Dispatcher.RunAsync でスレッドを切り替えているのは、物理ボタンの変更イベント(ValueChangedイベント)は UI スレッドではないからです。通常の Windows アプリのボタンは Click イベントで直接テキストボックスのTextプロパティの値を変更できますが、Windows IoT Core の場合は画面に出力するときは、Dispatcher.RunAsync でスレッドを切り替えます。

これを Raspberry Pi 上で動かすと、ボタンを押したときに LED が光るようになります。もうちょっと工夫すれば、Amazon Dush Button のように、ボタンを押したらインターネット経由で Amazon に注文ができるようにできそうですよね。

3
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
0