西川和久の不定期コラム

「Raspberry Pi3 Model B」で遊んでみよう! Part4

~Windows 10 IoT Coreに挑戦!

 Part1からPart3までいろいろ遊んだが、ベースとなるOSはLinuxだった。しかしRaspberry Piはもう1つの魅力として、Windows 10 IoT Coreに対応していることがあげられる。最終回のPart4は、筆者にとって全て未知の領域でどこまで出来るか分からないが、Windows 10 IoT Coreを起動し簡単なアプリを動作させてみたい。

Raspberry Pi3へWindows 10 IoT Coreをインストールする

 Windows 10 IoT Coreは、Windows Embeddedに置き換わるものとして発表されたWindows 10ファミリーの一種。「Enterprise」、「Mobile Enterprise」、「Core/Core Pro」と3つのエディションがあり、今回使用するのは256MB/2GBから動作するCoreとなる。

 2016年6月現在、Windows 10 IoT Coreに対応しているハードウェアは、Raspberry Pi2、Raspberry Pi3、Dragonboard 410c、Minnowboard Maxの4種類。この中でRaspberry Pi3だけがInsider Preview版となっている。

 インストール方法をネットで調べていると、過去少し違うパターンがあったようだが、現在は「Windows 10 IoT Core Dashboard」に統合され、余計な手間がかからないようになっている。ダウンロードはこちらから行なえる。

 Raspberry Pi2、Dragonboard 410c、Minnowboard Maxは既にRTMとなっており、Windows 10 IoT Core Dashboardでデバイスの種類を選べばmicroSDカードへ書込み可能になっているが(Dragonboard 410cは少し違う)、今回使用しているRaspberry Pi3に関してはまだ未完成のInsider Preview版ということもあり、別途ダウンロードしなければならない。ダウンロードページはここ(Windows Insiderへの参加が必要)。Buildが14342と14328の2種類あり「新しい方がいいだろう」と、14342をダウンロードした。が、これが後述するトラブルの元になろうとは……。

 ISOファイルをダウンロードし、Windows 10でマウントすると、Windows_10_IoT_Core_for_RPi2.msiがあり、ダブルクリック、セットアップを開始する。

 終了後、C:¥Program Files (x86)¥Microsoft IoT¥FFURaspberryPi2にflash.ffuができるので、Windows 10 IoT Core Dashboardの新しいデバイスのセットアップ > デバイスの種類をカスタムへ設定し、[参照]ボタンで先のflash.ffuを指定、書込み先のドライブに間違いなければ[インストール]で書込みが開始される。これをRaspberry Pi3にセットすれば準備完了となる。

 イメージファイルの取得と書込み方法がPart3までとは違うものの、やっていること自体は全く同じだ。特に難しい部分はない。

Windows 10 IoT Core Dashboardのダウンロード
Raspberry Pi 3用のISOファイルをダウンロード。Buildが14342と14328の二種類ある
ISOイメージ中にあるWindows_10_IoT_Core_for_RPi2.msiを使ってflash.ffuを取得
Windows 10 IoT Core Dashboardを使ってmicroSDカードへ書込み

デスクトップ版Windows 10とは随分雰囲気が違うWindows 10 IoT Core

 microSDカードをRaspberry Pi3へ入れ、キーボードとマウス、ディスプレイを接続、電源を投入すると見慣れた窓のロゴとその下でドットがグルグル回るアニメーションが表示される。ここまではデスクトップ版Windows 10と何ら変わらない。しかしその次の画面が出るまでかなり時間がかかる。以下、初期起動までの写真を掲載するので参考にして欲しい。

初期起動中。見慣れた画面だ
初期起動中。「Welcome to Windows 10 IoT Core」の表示
初期起動中。あと一歩
言語の設定。デフォルトは英語
言語の設定を日本語へ変更
Windows 10 IoT Coreが起動。デスクトップ版のようなリッチなUIはない

 Windows 10 IoT Coreが起動したものの、随分デスクトップ版とは雰囲気が違う。設定の一部が全画面になっているような感じだ。ここから操作できる項目は少なく、デバイス情報/Command line/チュートリアル/設定/電源オフ(または再起動)となる。設定もデバイス関連の簡単なものだけ。

 もう1つの操作方法として、Windows 10 IoT Core Dashboardの自分のデバイスからWeb UIのDevice Portalを起動する手がある。こちらの方が操作できる項目も多く、動作もまぁまぁ速いので、主にはこれを扱うことになるだろうか。機能的には掲載した画面キャプチャからも分かるように、ほとんどコントロールパネル的な内容だ。

Windows 10 IoT Core Dashboard > 自分のデバイス。起動したRaspberry Pi3の項目がある
Device Portal/Home。http://割り当てられたIPアドレス:8080/default.htm。id: Administrator、pw: p@ssw0rdでログインできる
Device Portal/Apps Manager
Device Portal/File Explorer
Device Portal/Running Processes
Device Portal/Performance
Device Portal/Device Manager
Device Portal/Bluetooth
Device Portal/Audio
Device Portal/Networking
Device Portal/Windows Update
Device Portal/IOT Onbording
Device Portal/Remote Server

 ご覧のように普段Windowsを使っているユーザーにとって、見栄えは違えど特に目新しい部分はない。またRemote Serverをオンにすると、リモートデスクトップが使えるようになる。ただしWindows 10 IoT Core接続専用のアプリ、「Windows IoT Remote Client」となり、一般的なWindowsのRemote Clientとは異なるものだ。

アプリストアのWindows IoT Remote Client
デバイス名かIPアドレスを指定して接続
Windows 10 IoT Coreのデバイス情報が表示された

 さらにPowerShellを使い、ローカルのコマンドラインからもログイン可能だ。シャットダウンは“shutdown /r /t 0”といった形で操作できる。

PowerShellからRaspberry Piに接続。パスワードはp@ssw0rd

 動作を確認したものの、これだけではさすがにつまらないので、何かできないか……と探したところ、Windows 10 IoT Core Dashboardのメニューに「サンプルを試す」を発見。開けると、「Network 3D Printer」、「インターネットラジオ」、「Blockly」の3つがあり、Part3と内容的に被るが、お手軽にできる「インターネットラジオ」を試すことにした。

Windows 10 IoT Core Dashboard/サンプルを試す
インターネットラジオ。[展開して実行]する
ブラウザ上でhttp://割り当てられたIPアドレス:8001/home.htmで起動。また同じ画面がディスプレイにも表示されている

 実際の動作は画面キャプチャを参考にして欲しいが、Windowsアプリのイメージとはほど遠い、地味で簡素化されたデザインになっている。終了は、先のApp ManagerのAppsにインターネットラジオの項目が追加されているので、停止ボタン(■)を押せばOKだ。

 Windows 10 IoT Coreに関しては、概要などの記事は多く見かけるものの、画面の詳細はあまりなく、今回多めにご紹介した。もうお分かりだと思うが、Windows 10 IoT Coreは、Win32アプリには非対応、デスクトップ版のリッチなUIにも未対応、UWPアプリのみが動作する環境となっている。

Raspberry Piで「Hello, World!」UWPアプリ

 次はいよいよプログラミング。画面に「Hello, World!」だけを表示する簡単なUWPアプリを作り、ローカル=PC上のWindows 10と、リモート=Raspberry Pi上のWindows 10 IoT Coreで動かしたい。

 準備するものは、Windows 10が動作するPCと、Visual Studio 2015 update 2(今回はCommunityエディションを使用/無償)。ここからダウンロードできるのでインストールする。

 一点、作ったUWPアプリをローカルのWindows 10で動作させるためには、設定 > 更新とセキュリティ > 開発者向けで、“開発者モード”にする必要がある。設定をし忘れてもアプリ実行時に注意が出るのですぐに気付くだろう。

 UWPアプリを作るには、Visual Studio 2015を起動時、ファイル > 新規作成 > プロジェクトを開くと、左側にテンプレートの一覧が表示されるので、テンプレート > Visual C# > Windows > ユニバーサルを選び、右側の一覧にある一番上の「空白のアプリ(ユニバーサルWindows)」を選択、適当な名前(ここではApp1)を付けて[OK]を押す。これによって、テンプレートだけのコードが入った画面が表示される。

 次にプロジェクト > 参照の追加で参照マネージャーを開き、Universal Windows > 拡張でWindows IoT Extensions for UWPを選択する。

ファイル > 新規作成 > プロジェクト。テンプレート > Visual C#> Windows > ユニバーサル、「空白のアプリ(ユニバーサルWindows)」を選択、適当な名前を付けて[OK]
テンプレートだけのコードが入った画面が表示される
プロジェクト > 参照の追加で参照マネージャーを開き、Universal Windows > 拡張でWindows IoT Extensions for UWPを選択

 これで準備は整ったので、「Hello, World!」に相当する「Hello Windows 10 IoT Core!!」の文字を入れる。

 方法は、MainPage.xamlを開き、画面サイズを適当に選択(ここでは10“IoT Device 1,024×768 100%スケール)、左側のツールボックスからTextBlockを白い画面の中にドラッグ・アンド・ドロップする。この時、必要であれば文字の表示位置を調整。共通のTextをHello Windows 10 IoT Core!!と入力すれば(1行も書いてないが)ソースコードが自動でできあがる。

 ローカルでの実行は、上のツールバーから「Debug|x86|ローカルコンピューター」の再生ボタンを押すとビルドが始まり終了後、アプリが起動する。

MainPage.xamlを開き、ツールボックスからTextBlockをドラッグ・アンド・ドロップ。表示位置を調整し、共通のTextをHello Windows 10 IoT Core!!と入力
上のツールバーから Debug|x86|ローカルコンピューター の再生ボタンを押すと実行され、無事白バックにHello Windows 10 IoT Core!!を表示
Raspberry Piで実行するには、プロジェクトのプロパティ、デバッグの部分をARMとし、ターゲットデバイスをリモートコンピューター、リモートコンピューターを自動検出でセットする

 次にRaspberry Pi上で実行してみよう。プロジェクトのプロパティ、デバッグの部分をARMとし、ターゲットデバイスをリモートコンピューター、リモートコンピューターを自動検出でセット。上のツールバーから「Debug|ARM|リモートコンピューター」の再生ボタンを押すと実行できる……はずだったが、エラーで動かなかった。

 具体的なエラー内容は、プログラムをロードする前に、実行に必要なMicrosoft.NET.CoreRuntime.1.0.appxをインストールされるのだが、そのインストールに失敗する。何をどうやっても同じ症状であり、現象的に考えても(多分)筆者は悪くなく、システム側の問題だ。「Part4のこのネタは没かな……」と落胆していたところ、buildが2つあったのを思い出した。

 駄目もとで古い14328をインストール。同じ処理をしたところ……何事もなかったかのように、Raspberry Pi上でUWPアプリが起動した。

Raspberry Pi上で起動したUWPアプリ
サンプルコードのBlinkyをローカルで実行。GPIOがないので画面は点滅しない
サンプルコードのBlinkyをリモートで実行。500ms毎に画面の表示とLEDが点滅する

 と、ここまで動けば基本はOK。ここにサンプルコードなどがあるので、好きなのを選び(英語であるが)チュートリアルを見ながらビルドすればいい。

 中でも「UI Blinky App」は、Part2で試したLEDのオン/オフと同じだ。サンプルコードをダウンロードし展開、中にあるプロジェクトをVisual Studio 2015で開けば、即試すことができる。メインのコードをそのまま掲載するので参考にして欲しい。

// Copyright (c) Microsoft. All rights reserved.

using System;
using Windows.Devices.Gpio;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Controls.Primitives;
using Windows.UI.Xaml.Media;

namespace Blinky
{
  public sealed partial class MainPage : Page
  {
    private const int LED_PIN = 12; // Part2と同じにするには5から書き換える
    private GpioPin pin;
    private GpioPinValue pinValue;
    private DispatcherTimer timer;
    private SolidColorBrush redBrush = new SolidColorBrush(Windows.UI.Colors.Red);
    private SolidColorBrush grayBrush = new SolidColorBrush(Windows.UI.Colors.LightGray);
    public MainPage()
    {
      InitializeComponent();

      timer = new DispatcherTimer();
      timer.Interval = TimeSpan.FromMilliseconds(500);
      timer.Tick += Timer_Tick;
      InitGPIO();
      if (pin != null)
      {
        timer.Start();
      }
    }

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

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

      pin = gpio.OpenPin(LED_PIN);
      pinValue = GpioPinValue.High;
      pin.Write(pinValue);
      pin.SetDriveMode(GpioPinDriveMode.Output);

      GpioStatus.Text = "GPIO pin initialized correctly.";

    }

    private void Timer_Tick(object sender, object e)
    {
      if (pinValue == GpioPinValue.High)
      {
        pinValue = GpioPinValue.Low;
        pin.Write(pinValue);
        LED.Fill = redBrush;
      }
      else
      {
        pinValue = GpioPinValue.High;
        pin.Write(pinValue);
        LED.Fill = grayBrush;
      }
    }

  }
}

 要点としては、

1)MainPage()は、初期化後、GPIOがあればタイマーを500msにセットしスタート
2)InitGPIO()は、GPIOが無ければ「There is no GPIO controller on this device.」とメッセージを表示しGPIOを初期化しない。あれば「GPIO pin initialized correctly.」と表示しつつ初期化する
3)Timer_Tick()は、500msの都度呼び出され、LEDがオンならオフへ、画面の表示をグレーへ。LEDがオフならオンへ、画面の表示を赤へ

 となる。比較的読みやすいコードなので、プログラミングを知らなくても、何となく分かるのではないだろうか。

 さらにUWPアプリの特徴として、Windows 10なら、デスクトップでもMobileでも、IoTでも(デバイス依存がなければ)、同じコードで動作するメリットがある。

 実際、Windows Phone Emulatorを使い、「Hello, World!」の1文字もコードを触らず実行させたところ、ご覧のように動作した(Windows Phone Emulatorがターゲットにない場合は、ここからダウンロードする)。このように、小型デバイスからモバイル、デスクトップ/サーバーと幅広いレンジを同じコードでカバーできる点がWindows 10とUWPアプリの最大の魅力と言えよう。

全くコードを触らずターゲットだけ変更して、Windows Phone Emulatorで「Hello, World!」UWPアプリを起動

 Part1からPart4通して「Raspberry Pi3 Model B」を使った感想は、性能もそれなりに出て快適なのだが、最近出たばかりと言うこともあり、Volumio2が未完成だったり、Windows 10 IoT CoreがInsider Previewだったり、まだ環境が完全に整ってない状況だ。何かトラブルが発生した時に、どこが悪いのか問題を切り分けるのが難しい(後半2回の連載もこれでかなり時間を費やしている)。

 そう言った意味で安定性を求めるなら「Raspberry Pi2 Model B」となるだろうか。ただこれは時間が解決することなので、新規購入するなら「Raspberry Pi3 Model B」を選びたいし、動作速度、標準搭載デバイスなど、それだけの魅力を「Raspberry Pi3 Model B」は持っている。


 以上、6月はいつもとは趣向を変え「Raspberry Pi3 Model B」を使って、Part1では紹介とLAMPを使ったWordPress、Part2はGPIOでLEDのオン/オフとステータス取得、Part3ではI2SにDACを接続してミュージックサーバー、そして今回はWindows 10 IoT Coreで簡単なUWPアプリを動かしてみた。

 このほかにもCamera interface (CSI)、Display interface (DSI)などを搭載しており、まだまだ試せることはいっぱいある。

 余談になるが、ちょうどPart3を入稿した直後に、LED、スイッチ、ハイレゾ対応DAC、LCD、温度/湿度/気圧センサーなどを搭載した、Raspberry Piのドーターボード「Apple Pi」が発表された。タイミング良いのか悪いのか微妙であるが(笑)、これを使えば、Part2からPart4は簡単に試すことができる。筆者も既に注文済なので、機会があれば書くことがあるかも知れない。

 普段使っているPCとアーキテクチャが異なるマシンで、試したり遊んだりするのは楽しいものだ。この連載を期に興味を持って頂ければ幸いである。