single.php

LEDデジタル数字を制御するアプリを開発してみる(C#編)

Raspberry Pi3 Model B+ の電子工作の記事です。先回は7セグメントLEDを点滅させる実験を行いました。今回はC#で作ったアプリを動作させてLEDで数字を表示するプログラムを開発してみました。

カソードとLEDの準備

Raspberry PiとWindows10だけでは実験できないので、最低限でもLEDとジャンパーケーブル、ブレッドボードの3点が必要になります。

先回の7セグメントLEDを使った実験や、LEDの配線やブレッドボードについては、過去記事をご覧ください。

また、LEDには電気の極性が違う「アノード」と「カソード」の2種類があります。プログラムで制御する場合、電流を流す側(つまり+極側)で処理をした方が楽なので、私は「カソード」のLEDを使いました。

そんなに高価な部品でもないので、両方持っていた方が今後の工作の幅が広がります(笑)

Amazonで購入したんですが、中華の国から3週間くらいで届きました。

ポストから出した時に、嫌な予感がしましたが、封筒の中にはビニール袋に発泡スチロールに刺さってLEDが10個まとめて入っています。

衝撃の発泡スチロールが、これ。商売だからケチるのは分かりますが、もう少し発泡スチロールをください(笑)

当初の予想通り、ピンはグニャグニャです。(笑)まぁ気にしませんが…

アノードとカソードの違い

LEDには極性(マイナスとプラス)があり、点灯させるために電気を流す方向が決まっています。

図に示すと、アノードの場合はこんな感じで

カソード型のLEDの場合は、こんな感じで電気を流します。

「どっちでもええやろ」と思いますが、実際の7セグLEDに置き換えてみると、アノード型のLEDの場合は、3番PINから電流を流して、4番PINを接地させると、LEDが点灯するのに対して

カソード型の場合は4番PINから電流を流して、3番PINを接地させるとLEDが点灯します。

C#からLEDを操作する場合、GND側よりもGPIO側の処理をする方が簡単なので、アプリから操作する場合には、アノードよりも、カソード型の方が楽に配線が組めるので、今回はカソード型のLEDを実装しています。

ブレッドボードに部品を配置

今回は、次のように結線しました。本来なら抵抗を使いますが実験レベルで長時間LEDの点灯をしなければ、直接つないでも大丈夫です。

LED側RaspberryPi3 ModelB+側
1GPIO#26
2GPIO#19
3GND
4GPIO#13
5GPIO#6
6GPIO#5
7GPIO#11
8GND
9GPIO#9
10GPIO#10

RaspberryPi 3のピン配置は、こんな感じになってます。

Raspberry Pi 2 & 3 Pin Header

RaspberryPiとの接続は、ジャンパーケーブルで行いました。結構グチャグチャしてますが、ニンジャーゴーのミニフィグにも手伝ってもらいました(笑)

UWPアプリ作成

1. 「ファイル|新規作成|プロジェクト」メニューを選択して、表示された画面で「Visual C#|Windows ユニバーサル」で表示される一覧から「空白のアプリ」を選択して名前を付けて「OK」ボタンをクリックします。

2. ターゲットプラットフォームを選択する画面が表示された場合は、既定値のまま「OK」ボタンをクリックして続行します。

3. プロジェクトが新規作成され「ソリューション エクスプローラー」にファイルの一覧が表示されます。

4. 「プロジェクト|参照の追加」メニューを選択して、表示された画面で「Universal Windows|拡張」内の「Windows IoT Extension for the UWP」を追加(左側のチェックを付ける)して「OK」ボタンをクリックします。

5. 「ソリューション エクスプローラー」から「MainPage.xaml」を開き、デザイン画面の上側のプルダウンリストから「4” IoT Device(569 x 320)」を選択します。

6. 「ツールボックス」から「Button」を選択して、MainPage.xamlのデザイン画面にドロップします。

7. 画面上の適当な場所に移動して、「Button」コントロールを貼り付けます。今回は0から9までの点灯を行うので、対応するボタンを量産します。消灯用に、「Clear」ボタンも配置しました。

8. ボタンを選択した状態で「プロパティ」を表示して、「イベント」タブ内の「Click」イベント部分をダブルクリックして対応するハンドラーを追加します。

9. 「MainPage.xaml.cs」に追加されたイベントコードに、LED点灯用のコードを追加します。(実際のコードは、この記事の最後にまとめて掲載しています)

9. ツールボタンのデバック先のCPUを「ARM」に変更して「Device」部分を「リモート コンピューター」に変更します。(下の画面の右上の部分)

10. リモート接続先(RaspberryPi)の検出画面で、Windows10 IoT Coreがセットアップされているデバイスを選択します。

11. デバイス内にアプリが配置され、デバッグ用の画面に切り替わります。

12. Windows10 IoT Core(RaspberryPiデバイス)では、アプリが起動し各ボタンが表示されます。

13. ボタンをクリックすると、ブレッドボード上のLEDが点灯します。

実際に点灯する様子を動画で編集したので、興味のある方はご覧ください。

ソースコード

MainPage.xaml.csに追加したコードは、こんな感じです。長いソースコードになっていますが、「DisplayLed」で実際にボード上のPIN操作をしています。

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.Devices.Gpio;


namespace WUApp1
{
  /// <summary>
  /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
  /// </summary>
  public sealed partial class MainPage : Page
  {
    //LEDに電流を送るピン番号
    private const int LED_PIN1 = 26;
    //ピンの定義
    private GpioPin led_pin1;
    //LEDをオンオフにする時のフラグ
    private bool check_led1 = false;

    private const int LED_PIN2 = 19;
    private GpioPin led_pin2;
    private bool check_led2 = false;

    private const int LED_PIN4 = 13;
    private GpioPin led_pin4;
    private bool check_led4 = false;

    private const int LED_PIN5 = 6;
    private GpioPin led_pin5;
    private bool check_led5 = false;

    private const int LED_PIN6 = 5;
    private GpioPin led_pin6;
    private bool check_led6 = false;

    private const int LED_PIN7 = 11;
    private GpioPin led_pin7;
    private bool check_led7 = false;

    private const int LED_PIN9 = 9;
    private GpioPin led_pin9;
    private bool check_led9 = false;

    private const int LED_PIN10 = 10;
    private GpioPin led_pin10;
    private bool check_led10 = false;

    public MainPage()
    {
      this.InitializeComponent();

      setup(ref led_pin1, LED_PIN1);
      setup(ref led_pin2, LED_PIN2);
      setup(ref led_pin4, LED_PIN4);
      setup(ref led_pin5, LED_PIN5);
      setup(ref led_pin6, LED_PIN6);
      setup(ref led_pin7, LED_PIN7);
      setup(ref led_pin9, LED_PIN9);
      setup(ref led_pin10, LED_PIN10);
    }

    private void DisplayNumber1()
    {
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led6 = DisplayLed(led_pin6, check_led6);
    }

    private void DisplayNumber2()
    {
      check_led1 = DisplayLed(led_pin1, check_led1);
      check_led2 = DisplayLed(led_pin2, check_led2);
      check_led6 = DisplayLed(led_pin6, check_led6);
      check_led7 = DisplayLed(led_pin7, check_led7);
      check_led10 = DisplayLed(led_pin10, check_led10);
    }

    private void DisplayNumber3()
    {
      check_led2 = DisplayLed(led_pin2, check_led2);
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led6 = DisplayLed(led_pin6, check_led6);
      check_led7 = DisplayLed(led_pin7, check_led7);
      check_led10 = DisplayLed(led_pin10, check_led10);
    }

    private void DisplayNumber4()
    {
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led6 = DisplayLed(led_pin6, check_led6);
      check_led9 = DisplayLed(led_pin9, check_led9);
      check_led10 = DisplayLed(led_pin10, check_led10);
    }

    private void DisplayNumber5()
    {
      check_led2 = DisplayLed(led_pin2, check_led2);
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led7 = DisplayLed(led_pin7, check_led7);
      check_led9 = DisplayLed(led_pin9, check_led9);
      check_led10 = DisplayLed(led_pin10, check_led10);
    }

    private void DisplayNumber6()
    {
      check_led1 = DisplayLed(led_pin1, check_led1);
      check_led2 = DisplayLed(led_pin2, check_led2);
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led7 = DisplayLed(led_pin7, check_led7);
      check_led9 = DisplayLed(led_pin9, check_led9);
      check_led10 = DisplayLed(led_pin10, check_led10);
    }

    private void DisplayNumber7()
    {
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led6 = DisplayLed(led_pin6, check_led6);
      check_led7 = DisplayLed(led_pin7, check_led7);
    }

    private void DisplayNumber8()
    {
      check_led1 = DisplayLed(led_pin1, check_led1);
      check_led2 = DisplayLed(led_pin2, check_led2);
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led6 = DisplayLed(led_pin6, check_led6);
      check_led7 = DisplayLed(led_pin7, check_led7);
      check_led9 = DisplayLed(led_pin9, check_led9);
      check_led10 = DisplayLed(led_pin10, check_led10);
    }

    private void DisplayNumber9()
    {
      check_led2 = DisplayLed(led_pin2, check_led2);
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led6 = DisplayLed(led_pin6, check_led6);
      check_led7 = DisplayLed(led_pin7, check_led7);
      check_led9 = DisplayLed(led_pin9, check_led9);
      check_led10 = DisplayLed(led_pin10, check_led10);
    }

    private void DisplayNumber0()
    {
      check_led1 = DisplayLed(led_pin1, check_led1);
      check_led2 = DisplayLed(led_pin2, check_led2);
      check_led4 = DisplayLed(led_pin4, check_led4);
      check_led6 = DisplayLed(led_pin6, check_led6);
      check_led7 = DisplayLed(led_pin7, check_led7);
      check_led9 = DisplayLed(led_pin9, check_led9);
    }

    private void ClearLed()
    {
      led_pin1.Write(GpioPinValue.Low);
      led_pin2.Write(GpioPinValue.Low);
      led_pin4.Write(GpioPinValue.Low);
      led_pin5.Write(GpioPinValue.Low);
      led_pin6.Write(GpioPinValue.Low);
      led_pin7.Write(GpioPinValue.Low);
      led_pin9.Write(GpioPinValue.Low);
      led_pin10.Write(GpioPinValue.Low);

      check_led1 = false;
      check_led2 = false;
      check_led4 = false;
      check_led6 = false;
      check_led5 = false;
      check_led7 = false;
      check_led9 = false;
      check_led10 = false;
    }

    private bool DisplayLed(GpioPin pin, bool check)
    {
      if (check == false)
      {
        //ピンに電流を流す(LED点灯)
        pin.Write(GpioPinValue.High);
        return true;
      }
      else
      {
        //ピンに電流を止める(LED消灯)
        pin.Write(GpioPinValue.Low);
        return false;
      }
    }

    private void setup(ref GpioPin pin, int n)
    {
      //とりあえず既定値で初期化
      var gpio = GpioController.GetDefault();
      if(gpio == null)
      {
        pin = null;
        return;
      }

      //ピンの呼び出し
      pin = gpio.OpenPin(n);
      //最初は消灯
      pin.Write(GpioPinValue.Low);
      //ピンを出力モードに設定
      pin.SetDriveMode(GpioPinDriveMode.Output);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber1();
    }

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber2();
    }

    private void Button_Click_2(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber3();
    }

    private void Button_Click_3(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber4();
    }

    private void Button_Click_4(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber5();
    }

    private void Button_Click_5(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber6();
    }

    private void Button_Click_6(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber7();
    }

    private void Button_Click_7(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber8();
    }

    private void Button_Click_8(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber9();
    }

    private void Button_Click_9(object sender, RoutedEventArgs e)
    {
      ClearLed();
      DisplayNumber0();
    }

    private void Button_Click_10(object sender, RoutedEventArgs e)
    {
      ClearLed();
    }
  }
}


Window10 IoT Coreで動作するアプリ開発も慣れてきたので、次回は、LED以外のパーツを使ったIoTデバイスを制御する開発を行っていきます。

スポンサーリンク

最後までご覧いただきありがとうございます。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です