2015年5月3日日曜日

Windows IoT for Raspberry Pi 2 で Lチカ

 今回は Windows IoT ネタです。以前に GalileoでWinIoT を試したことがありましたが、先日、Windows IoT for Raspberry Pi 2 のプレビュー版が公開されたので、早速、試してみることにしました。
 やることは、サンプルプログラムを元にLチカを最も簡単なプログラムでかつ新しいプロジェクトの作成から試してみることです。すぐに出来るだろうと思って調べ始めたところ、とんでもなく面倒でした。書くのも面倒なので・・・全ては書く気にもならないですが、手順の一部を載せておこうと思います。

 まず、Get Start のページで必要環境を確認したところで、心が折れます。開発する側の環境として、 Windows 10 Insider PreviewVisual Studio 2015 RC が必要になります。Visual Studio 2015 RC はいいとして、Windows 10 のプレビュー版をインストールできる端末の余分がないとできないわけです。自分は幸か不幸か仕事柄も最新のOSの動向などは知っておく必要があるので、思い切って現用端末の内の一台をWindows8→Windows10Previewへのアップグレードインストールを行って、環境を用意しました。
 次に Windows IoT for Raspberry Pi 2 Preview をダウンロード してzipファイルを解答すると、microSDに書き込むためのOSイメージとVisual StudioにWinIoTの開発機能を拡張するためのインストーラが展開されます。

 イメージ展開用のmicroSDをWindows10にマウントして、コマンドプロンプトで
   diskpart
   list disk
   exit
としてドライブ番号をリスト表示させて確認します。(例えば、ディスク N だったとします)
 OSイメージ Flash.ffu のあるフォルダに移動して、以下のコマンドを実行します。
   dism.exe /Apply-Image /ImageFile:flash.ffu /ApplyDrive:\\.\PhysicalDriveN /SkipPlatformCheck
 PhysicalDriveN のNは実際にはディスク番号の数字です。
 これで展開されたmicroSDをRPi2に挿して起動すればOKです。初回起動時は時間がかかるので気長に待ちましょう。うまく起動すれば、先の拡張ツールと一緒にインストールされた検出ツールで minWin というPC名で検出されるはずです。自分はモニタは使っていませんが、モニタを接続しておけば、以下の様な画面が確認できるそうです。



 つぎは、Lチカプログラムです。ここにあるように GPIO5(29ピン)と3.3VをLEDと抵抗で接続します。(下の画像は前述のここのものをそのままコピーさせてもらいました)




 Visual Studio 2015 RC でC#の新しいプロジェクトを作成して、空のWindows Universalアプリ(Blank App(Windows Universal))を選択します。


 プロジェクトへの参照の追加で「Windows IoT Extension SDK」を追加します。


 MainPage.xaml.cs を編集します。まず、using Windows.Devices.Gpio; を追加します。


 Lチカのソースは次のような感じにしました。Arduinoのような単純な待ち時間を取らせる方法がわからなかったので、サンプルプロジェクトを参考にしてタイマでLチカ動作するような方法としました。
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using Windows.Foundation;
using Windows.Foundation.Collections;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Input;
using Windows.UI.Xaml.Media;
using Windows.UI.Xaml.Navigation;
using Windows.Devices.Gpio; // 追加。
// The Blank Page item template is documented at http://go.microsoft.com/fwlink/?LinkId=402352&clcid=0x409
namespace HelloWinIoT
{
/// <summary>
/// An empty page that can be used on its own or navigated to within a Frame.
/// </summary>
public sealed partial class MainPage : Page
{
private const int PIN_LED = 5; // LEDをGPIO5ピンに220Ω抵抗付きでVccと接続。
private bool LEDStatus = false; // LED点灯状態。
private GpioPin led; // LEDのピンのGPIO変数。
private DispatcherTimer timer; // 周期処理用タイマ。
public MainPage()
{
this.InitializeComponent();
// タイマ作成と周期とハンドラ設定。
timer = new DispatcherTimer();
timer.Interval = TimeSpan.FromMilliseconds(500);
timer.Tick += Timer_Tick;
// アンロード時ハンドラ。使わないか?
this.Unloaded += MainPage_Unloaded;
// GPIOピンを出力に設定。
var gpio = GpioController.GetDefault();
led = gpio.OpenPin(PIN_LED);
led.SetDriveMode(GpioPinDriveMode.Output);
// タイマ開始。
timer.Start();
}
// タイマイベントハンドラ。
private void Timer_Tick(object sender, object e)
{
// LED点滅処理をコール。
TurnLEDStatus();
}
// アンロード時のハンドラ(呼ばれないかも)。
private void MainPage_Unloaded(object sender, object args)
{
// ピンの廃棄。
led.Dispose();
}
// LED点滅処理。タイマでコールされる。
private void TurnLEDStatus()
{
if (LEDStatus)
{
LEDStatus = false;
led.Write(GpioPinValue.High);
}
else
{
LEDStatus = true;
led.Write(GpioPinValue.Low);
}
}
}
}

 プロジェクトのプロパティのビルドタグでプラットフォームタイプでARMを選択します。


 DebugタブでプラットフォームをARM、Start optionsのTarget device をリモートコンピュータにして、Remote machineにRPi2のPC名(デフォルトだとminWin、下記の画像の例だとWinIoTPiに変えてあります)かまたはIPアドレスを指定、Use authenticationのチェックを外します。


 ビルドの構成がARMになっていることを確認して、ビルド・実行します。


 プロジェクトがビルドされて、リモートコンピュータ(RPi2)にダウンロードされて実行されます。


 なんか、Lチカやるだけで、すごく大掛かりになってしまったんだけど・・・。