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+側 |
1 | GPIO#26 |
2 | GPIO#19 |
3 | GND |
4 | GPIO#13 |
5 | GPIO#6 |
6 | GPIO#5 |
7 | GPIO#11 |
8 | GND |
9 | GPIO#9 |
10 | GPIO#10 |
RaspberryPi 3のピン配置は、こんな感じになってます。
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デバイスを制御する開発を行っていきます。
スポンサーリンク
最後までご覧いただきありがとうございます。