Quantcast
Channel: デバイスとITの架け橋
Viewing all 167 articles
Browse latest View live

Flash Air の画像ファイルをLuaでMicrosoft Azure Blobにアップロードする

$
0
0

Flash Airが新しくなって、Luaというスクリプト言語で色々できるようになりました。

じゃぁということで、例えばカメラで写真を撮ってFlash Airに格納し、格納したファイルをLuaで、Microsoft AzureのWebアプリでHTTP RESTで受けてBlobにアップする方法を紹介します。

 

手順は、

  1. Microsoft Azureで画像蓄積用にBlobを作成
  2. Visual Studioで画像アップロード用のWEB APIプロジェクトを作成
  3. Microsoft AzureにWebサイトを作って、WEB APIプロジェクトを発行
  4. Luaスクリプトで画像アップロードプログラムを作成
  5. Microsoft Azure上のBlobの公開

です。

で、その前に、Azureを使うので、Azure Subscription契約が必要です。

http://azure.microsoft.com

から契約をお願いします。手順の詳細は、https://msdn.microsoft.com/ja-jp/windowsazure/ee943806 に書いてあるので、参考にしてください。
※一か月間205000円相当の無料枠があります。一か月の期限が近づくとメールが届きます。無料のサービスだけ使っている場合はお金は一切かからないので、メール、もしくは、ポータルから、ロックを外してください。手続きをしないと、アカウントはロックされて使えなくなりますので、ご注意。

それから、Visual Studio 2013が必要です。持っていない人は、http://www.visualstudio.comから、Community Ediitonをダウンロード&インストールしてください。
Visua Studio 2013のインストールが済んだら、Azure SDKをインストールします。http://azure.microsoft.com/ja-jp/downloads/ を開いて、.NETのVS 2013のインストール(http://go.microsoft.com/fwlink/p/?linkid=323510&clcid=0x411)をクリックしてインストールしてください。

さて、では、早速作業を始めましょう。

1. Microsoft Azureで画像蓄積用のBlobを作成

先ず、http://manage.windowsazure.com をブラウザで開いて、サブスクリプション登録したマイクロソフトアカウントでサインし、ポータルを開きます。

左の水色のペインの”ストレージ”を選択して、左下黒帯の”+新規”をクリックします。表示された黒いペインで、”簡易作成”を選択、”URL”には適当な名前(サービスのEndpointのURLとして使われるので使用済みの文字列は使えません:ここでは仮に”photostorage"としておきますね)を入力、”場所”は、”日本(西)”を選択して、右下の”✓”ボタンをクリックします。しばらくたつと、ポータルの左側のペインの”ストレージ”を選択した時に、右側のリストに作成したストレージが表示されます。表示された"photostorage"をダブルクリックして、後で使う、アクセスキーを確認しておきます。

下の黒帯の”アクセスキーの管理”をクリックし、表示されたダイアログの”プライマリーアクセスキー”の値の右のアイコン(赤で括ったやつ)をクリックすると、クリップボードにアクセスキーがコピーされるので、後で”ストレージのアクセスキー”と言われたらこの操作をして使ってください。

ストレージアカウント: ストレージを作成した時につけた名前 - ここでは、”photostorage"

アクセスキー:直前で説明した方法で確認できる文字列

です。あとから出てくるので、念のため。

以上で、写真をクラウド上で格納するためのストレージが出来上がりました。Blobは、次のステップで作成するWeb APIアプリを実行すると自動的に出来上がります。

2. Visual Studioで画像アップロード用のWEB APIプロジェクトを作成

次に、写真をアップするためのサービスを作ります。
Visual Studio 2013 を起動して、メニューの”ファイル”→”新規作成”→”プロジェクト”を選択します。

表示されたダイアログで、”Visual C#"→”Cloud”を選択して、”ASP.NET WEBアプリケーション”を選択します。
名前は、”PhotoUpload”と入力して”OK"をクリックします。

テンプレートは”MVC”を選択します。その下の”Web API”にチェックを入れます。
”クラウド内のホスト”はチェックを外します。”OK"をクリックします。プロジェクトが作成されます。

次にAzure Storageにアクセスするためのライブラリをインストールします。
ソリューションエクスプローラーで、”参照設定”フォルダーを右クリックして”NuGetパッケージの管理”を選択します。

開いたダイアログで、左側で”オンライン”を選択、右上の検索窓に”Azure Storage SDK”と入力します。しばらくたつと中央に”Windows Azure Storage”と表示されるので、その右側の”インストール”をクリックして、ライセンスに同意してインストールを完了します。”Windows Azure Storage”の右側に緑色の”✓”が付いたら、右下の”閉じる”ボタンをクリックしてダイアログを閉じます。

次にプログラムから、Storageにアクセスするための設定をWeb.configに加えます。ソリューションエクスプローラーで”Web.config”をダブルクリックして、<appSetting>...</appSetting>に以下の太字で示した行を追加します。

  <appSettings>
    <add key="webpages:Version" value="3.0.0.0" />
    <add key="webpages:Enabled" value="false" />
    <add key="ClientValidationEnabled" value="true" />
    <add key="UnobtrusiveJavaScriptEnabled" value="true" />
    <add key="StorageConnectionString" value="DefaultEndpointsProtocol=https;AccountName=[photostorage];AccountKey=[access-key]"/>
  </appSettings>

[photostorage][access-key]は、”[”、”]”もろともAzureのポータルで作成したStorageのストレージアカウント名と、アクセスキーで置き換えます。これらの設定は、次に追加するWeb APIのコントローラの中で参照します。

次に、ソリューションフォルダーで、”Controllers”フォルダーを右クリックして、”追加”→”コントローラー”を選択します。

 

表示された”スキャフォールディングの追加”ダイアログで、”Web API 2 コントローラー - 空”を選択し、”追加”をクリック、表示された”コントローラーの追加”ダイアログで”PhotoController”と入力し、”追加”をクリックします。
”Controllers”フォルダーに、”PhotoContoroller.cs"というファイルが出来上がります。

このフォルダーに出来上がっている、PhotoControllerクラスの定義を丸ごと以下のコードで置き換えます。

namespace PhotoUpload.Controllers
{
    using Microsoft.WindowsAzure;
    using Microsoft.WindowsAzure.Storage;
    using Microsoft.WindowsAzure.Storage.Blob;
    public class PhotoController : ApiController
    {
        public HttpResponseMessage Post([FromUri] string fileName)
        {
            var task = this.Request.Content.ReadAsStreamAsync();
            task.Wait();
            var reqStream = task.Result;

            CloudStorageAccount storageAccount = CloudStorageAccount.Parse(CloudConfigurationManager.GetSetting("StorageConnectionString"));
            CloudBlobClient blobClient = storageAccount.CreateCloudBlobClient();
            CloudBlobContainer container = blobClient.GetContainerReference("photos");
            container.CreateIfNotExists();
            CloudBlockBlob blockBlob = container.GetBlockBlobReference(fileName);

            blockBlob.UploadFromStream(reqStream);

            var response = new HttpResponseMessage();
            response.StatusCode = HttpStatusCode.Created;
            return response;
        }
    }
}

ここで追加したクラスのPostメソッドが、これから作成するAzure上のWeb サイトのエンドポイントURLに、/api/Photo?fileName=xxxx.jpg という形式の文字列を加えたHTTP REST APIのPOSTメソッドにマップされます。

3. Microsoft AzureにWebサイトを作って、WEB APIプロジェクトを発行

さて、写真をアップロードする仕掛けが出来たので、Azure上にWebサイトを作って、2で作成したプロジェクトを発行します。
Azureのポータル(http://manage.windowsazure.com を開いているブラウザ)で、早速Webサイトを作成します。

左側の水色のペインで”WEBアプリ”を選択し、左下の”+新規”をクリックします。

”簡易作成”を選択し、”URL”に適切な文字列を入力します。ストレージアカウントと同様、こちらもネットワーク上で一意でなければならないので、適当に決めてください。ここでは、便宜上、”PhotoUpload”としておきます。

 Webアプリが出来上がったら、WEBアプリのリストで、クリックして作成したWEBアプリのページを表示します。

”ダッシュボード”タブをクリックして、右下の”発行プロファイルのダウンロード”をクリックし、拡張子が、PublishSettingsファイルをダウンロードして保存します。これでAzure上の設定は終わり。

Visual Studioに戻ります。ソリューションエクスプローラーで、”PhotoUpload”プロジェクトを右クリックして、”発行”を選択します。

”発行の設定のインポート”ダイアログで、”参照”をクリックし、AzureのポータルからダウンロードしてきたpublishSettingsファイルを選択して”OK"をクリックします。最後に”発行”をクリックします。
Visual Studioでビルド、Azureへの発行が行われ、完了するとブラウザが開きます。

以上で、Azure側の準備は整いました。

 HTTP REST APIは、

http://photoupload.azurewebsites.net/api/Photo?fileName=xxxx.jpg

 という形式で、image/jpeg でバイナリデータをPOSTするとBlobに上がります。

4. Luaスクリプトで画像アップロードプログラムを作成

Flash Airは、Station Modeに設定してインターネット接続可能な状態に設定してください。
やり方は、https://www.flashair-developers.com/ja/ を参考に家てください。

先ずはPC上で、以下のテキスト(posturlのphotouploadの部分は各自のAzure WebサイトのURLに合わせて変更してください)を、http-azure-post-all.lua という名前で保存します。

boundary = "--Flashairboundary2015" -- アップロードするファイルが入っているフォルダ
posturl = "http://photoupload.azurewebsites.net/api/Bitmap"  -- PostするURL
folder    = "/DCIM/101CANON"         -- アップロードするファイルが入っているフォルダ
contenttype = "application/octet-stream; boundary=" .. boundary

for filename in lfs.dir(folder) do
 filepath = folder .. "/"  .. filename
 attr = lfs.attributes(filepath)
 print( "Found " .. attr.mode .. ": " .. filepath .. "->")
-- Don't worry about directories (yet)
    if attr.mode == "file" then
  blen = lfs.attributes(filepath,"size")

  b,c,h = fa.request{url = posturl .. "?filename="..filename, method = "POST", headers = {["Content-Length"] = tostring(blen),["Content-Type"] = contenttype},
   file = filepath,body = "<!--WLANSDFILE-->"
   }
--  print("b:" .. b .. "<BR>")
--  print("c:" .. c .. "<BR>")
--  print("h:" .. h .. "<BR>")
  if c == 201 then
   print("OK<BR>")
  else
   print("Error<BR>")
  end
 end
end
print("' compleat!<BR></HTML>")

FlashAirをPCのSDカードリーダーに挿して、このファイルをFlashAirのルートディレクトリにコピーします。
コピーが終わったら、デジカメに挿して写真を撮ります。
PCからFlashAirにWi-Fiで接続して、ブラウザで表示して、Luaをクリックすると実行してSDカードに入っている画像ファイルがAzureのBlobにアップされます。

FlashAirに関する設定詳細は、東芝から公開されているページを参照してください。

Microsoft Azure 上のBlobを公開する

カメラで写真を撮ったりして画像ファイルをアップロードすると、Blobに溜まっていきます。アップロードされた画像ファイルをネットワーク上でアクセスするには、Azureの管理ポータルで作成したストレージアカウントの”コンテナ”タブをクリックし、photosを選択して、下の黒帯の”編集”をクリックします。

”アクセス”を”パブリックBLOB”に選択して、右下の”✓”をクリックします。
これで、http://photostorage.blob.core.windows.net/photos/xxxxx.jpgというような形式でアクセスできるようになります。


PinKit ( GR Peach )で.NET Micro Frameworkを動かす

$
0
0

ESEC2015で予約販売中のPinKit、勿論、.NET Micro Frameworkが動きます。

セットアップは簡単。

先ず、http://netmf.github.io  からリンクをたどって、.NET Micro Framework SDK 4.3(QFE2-RTM)をダウンロード&インストールします。

次に、http://netmf4mbed.codeplex.com/ の右上の”download"タブから最新版のファームウェアをダウンロードし、適当な場所に保存します。ダウンロードしたZIPファイルは、プロパティでブロックを外してから、解凍しておいてください。

GR PEACHの端のUSBポートにマイクロUSBケーブルをつないでPCに接続します。

すると、ファイルエクスプローラーが開きます。そこに、https://netmf4mbed.codeplex.com/からダウンロードしてきたZIPファイルの解凍後の中身をコピー&ペーストします。

これで完了。Windows 8.1以降のWindows PCならそのまま、GR PEACHの真ん中のUSBポートにつなぎかえれば、Visual Studioを使って、.NET Micro Framework上で動作する、C#、VBのプログラムを動かせます。

Wiindows 8.1より前のOSが入っているPCでは、http://aka.ms/IoTKitHoLPDDからZIPファイルをダウンロードし、ブロックを解除して、ZIPファイルを解凍。中に入っているINSTALL.cmdを実行してから、USBケーブルでPCに接続してください、

簡単ですね。作業が終わったら、http://aka.ms/IoTKitHoLをチャレンジ‼

 

I2Cの温度センサーをWindows 10 IoT Core for Raspberry PI2で使う

$
0
0

今後、http://www.WindowsOnDevices.comから紹介されている、Win10 IoT Core for Raspberry PI2の基本情報は紹介するとして、

http://ms-iot.github.io/content/en-US/win10/samples/I2CAccelerometer.htm

で紹介されているI2Cのセンサー制御サンプルを参考にしながら、I2Cで制御可能な安価な温度センサーTMP102から温度を取得する方法を紹介します。

開発環境やRPI2のROM等の、セットアップ方法は、http://ms-iot.github.io/content/en-US/win10/SetupRPI.htm を参考にしてください。

温度センサー

TMP102 http://www.tij.co.jp/product/jp/tmp102

私が使ったのは、こちら。https://www.sparkfun.com/products/11931 700円ぐらいで購入可能。

これを図の様につないで、

※GNDはRaspberry PI2側の黒いピン(GND)と書かれているピンならどれでもOK)
ADD0はGNDと接続。

 Windows 10 Tech PreviewでVisual Studio 2015RCを起動し、新規プロジェクトで、”C#”→”Universal App”→”Blank App”でプロジェクトを作成します。

ソリューションエクスプローラーで、参照を右クリックし、追加で、

Windows Universal の拡張の”Windows IoT Extension SDK”を追加します。

MainPage.xaml.csを開いて、I2C制御のコードを、以下の様に記述します。

    public sealed partial class MainPage : Page
    {
        private const string I2C_CONTROLLER_NAME = "I2C1";
        private const byte TMP102_I2C_ADDR = 0x48;
        private I2cDevice I2CTMP102;

        private const byte I2CTMP102_REG_READ_TEMP = 0x00;
        private const byte I2CTMP102_REG_CONFIG = 0x01;
        private const byte I2CTMP102_REG_READ_MIN_TEMP = 0x02;
        private const byte I2CTMP102_REG_READ_MAX_TEMP = 0x03;

        private DispatcherTimer periodicTimer;
        private async void InitI2CTemp102()
        {
            try
            {
                string
                    aqs = I2cDevice.GetDeviceSelector(I2C_CONTROLLER_NAME);
                var dis = await DeviceInformation.FindAllAsync(aqs);

                var settings = new I2cConnectionSettings(TMP102_I2C_ADDR);
                settings.BusSpeed = I2cBusSpeed.FastMode;
                I2CTMP102 = await I2cDevice.FromIdAsync(dis[0].Id, settings);
                if (I2CTMP102 != null)
                {
                    double currentTemp = TakeMeasurementTemperature();

                    periodicTimer = new DispatcherTimer();
                    periodicTimer.Interval = TimeSpan.FromMilliseconds(1000);
                    periodicTimer.Tick += PeriodicTimer_TickMeasureTemperature;
                    periodicTimer.Start();
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        private double TakeMeasurementTemperature()
        {
            byte[] writeBuf = new byte[] { I2CTMP102_REG_READ_TEMP };
            byte[] readBuf = new byte[2];
            I2CTMP102.WriteRead(writeBuf, readBuf);
            int valh = ((int)readBuf[0]) << 4;
            int vall = ((int)readBuf[1] >> 4);
            int val = valh + vall;
            double unit = 0.0625;
            if ((val & 0x800) != 0)
            {
                val = 0x1000 - val;
                unit *= -1;
            }
            double reading = val * unit;
            return reading;
        }

        private void PeriodicTimer_TickMeasureTemperature(object sender, object e)
        {
            var currentTemp = TakeMeasurementTemperature();
        }

        public MainPage()
        {
            this.InitializeComponent();
            this.Loaded += MainPage_Loaded;
        }

        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            InitI2CTemp102();
        }
    }

TMP102_I2C_ADDRは、ADD0とGNDをつないでいるので”0x48”です。温度は、0x00のレジスターをwriteBufで指定して読み込むと、12Bitで温度がreadBufに格納されて帰ってきます。1バイト目に12ビットの上位8ビット、2バイト目の上位4ビットに、12ビットの下位4ビットが格納されています。単位が、0.0625℃なので、その値をかければ温度が算出できます。12ビットの最上位が1の場合は、補数表示された負の値です。

センサーの詳細は、http://focus.tij.co.jp/jp/lit/ds/symlink/tmp102.pdfから公開されています。上のコードとこのデータシートを見比べると、他のI2Cセンサーを使う場合の一助になると思います。

 

Windows 10 IoT Core for Raspberry PI2 も IoT ってついているんだから~

$
0
0

はい、IoTってついているので、やっぱり、ネットワークやクラウドにつながないとね。

http://aka.ms/IoTKitHoLから公開中の現状のトレーニングコンテンツは.NET Micro Frameworkデバイスをつなぐのですが、公開されているサンプルや一つ前のポストで、.NET MFの代わりにRaspberry PI2+I2Cセンサーで代替できるわけですね。

ここでは、2015年5月31日現在の手に入る環境で、IoT Kit HoLで扱っているクラウド接続+αを紹介していきます。全て、Visual Studio 2015RCのC#、Windows Universalアプリでの開発を前提です。

先ずは、HTTP REST APIにGETでアクセスする方法。Step 1接続の一番最初でやっている、ヘッダーにDeviceIdとメッセージをセットして、サーバーから戻りのメッセージを受け取るやつです。

       var client = new Windows.Web.Http.HttpClient();
       client.DefaultRequestHeaders.Add("device-id", deviceId.ToString());
       client.DefaultRequestHeaders.Add("device-message", "Hello from RPi2");
       var response = client.GetAsync(new Uri("http://egiotkitholservice.azurewebsites.net/api/DeviceConnect"), HttpCompletionOption.ResponseContentRead);
       response.AsTask().Wait();
       var responseResult = response.GetResults();
       if (responseResult.StatusCode == Windows.Web.Http.HttpStatusCode.Ok)
       {
           result = true;
           var received = await responseResult.Content.ReadAsStringAsync();
           Debug.WriteLine("Recieved - " + received);
       }

   はい、Web HTTP RESTでアクセスするには、Windows.Web.Http名前空間のHttpClientを使います。ヘッダーに値を設定するには、DefalutRequestHeadersプロパティにAddすればできます。GETでアクセスするので、GetAsyncをコールします。ここで一つポイント。GetAsyncメソッドをコールする際、いつものノリで、awaitとかやっちゃうと、そこで処理がブロックされます。これ、Raspberry PI2での実行に限った話ではなく、Universal Apps系全般でそうです。なので、そのまま戻り値を受けて、AsTask().Wait()というメソッドをコールしてください。これで、GetAsyncでサーバーにアクセスしに行き、サーバー側での処理が終わって、戻りメッセージを受け取るという一連の流れが終わって復帰します。HTTP RESTアクセスの結果は、GetResultsメソッドで取出し。ステータスやサーバーからの応答メッセージは、GetResultsメソッドで取り出した変数のStatusCodeプロパティや、ContentからReadAsStringAsyncメソッドで取出し可能。

次に、HTTP REST APIのPOST。JSONでメッセージを送信する方法です。

温度とデバイスID、計測時間を送信するとしましょう。先ずは、送信データパケットのフォーマットを規定するデータモデルクラスを定義します。ソースコードの先頭の方に、System.Runtime.Serialization をusing宣言加えてください。

    [DataContract]
    public class SensorPacket
    {
        [DataMember]
        public string DeviceId { get; set; }
        [DataMember]
        public double Temperature { get; set; }
        [DataMember]
        public DateTime MeasuredTime { get; set; }
    }

これを使って、POSTするコードは、

            var packet = new SensorPacket()
            {
                DeviceId = deviceId.ToString(),
                Temperature = temperature,
                MeasuredTime = DateTime.Now
            };
            var serializer = new DataContractJsonSerializer(typeof(SensorPacket));
            MemoryStream ms = new MemoryStream();
            serializer.WriteObject(ms, packet);
            ms.Position = 0;
            StreamReader sr = new StreamReader(ms);
            var content = new Windows.Web.Http.HttpStringContent(sr.ReadToEnd(), Windows.Storage.Streams.UnicodeEncoding.Utf8, "application/json");

            var client = new Windows.Web.Http.HttpClient();
            client.DefaultRequestHeaders.Accept.Add(new Windows.Web.Http.Headers.HttpMediaTypeWithQualityHeaderValue("text/json"));
            var response = client.PostAsync(new Uri(webApiEndPoint + "/api/Win10IoT"), content);
            response.AsTask().Wait();
            var responseResults = response.GetResults();

こんな感じ。DataContractJsonSerializerというクラスを使って、SensorPacketクラスのインスタンスをJSON形式にシリアライズします。シリアライズした文字列を、HttpClientインスタンスで送るため、HttpStringContent(別の名前空間にも同一名のクラスがあるので注意)インスタンスに変換します。
POSTメソッドで送るので、PostAsyncメソッドで送付。後はGetAsyncと同じようにハンドリングします。
送られるデータは、{"DeviceId":"....","Temperature":24.354, "MeasuredTime":"2015/06..."} というようなJSONです。ヘッダーのメディアタイプへの設定はデフォルトで既に用意されているので、DefaultRequestHeaders の AcceptプロパティにAddします。

簡単ですね。お、これができれば、Mobile Apps(旧Mobile Service)への接続も簡単だ!なにしろ、ヘッダーにX-ZUMO-APPLICATIONにアクセスキーセット等すればいいからね…いやそんなめんどくさいことしなくていいです。

Mobile Appsにつなぎたい場合は、ソリューションエクスプローラーで参照を右クリック⇒Nugetパッケージの管理を選択し、”Mobile Service”と検索窓に入力して、WindowsAzure.MobileServiceをInstallすればOK。後は、普通のUniversal Windows Appsと同じように、App.xaml.csのAppクラスに、

        public static MobileServiceClient MobileService = new MobileServiceClient("url","accesskey");

と追加して

            var table = App.MobileService.GetTable<SensorData>();

でテーブル参照取得して、登録レコードの取出しは、

            var records = await table.ToEnumerableAsync();
            foreach (var record in records)
            {
                var deviceId = recored.DeviceId;
                ...
            }

とか、新しい行を追加したければ、

            await table.InsertAsync(new SensorData() { DeviceId= deviceId.ToString(),... });

とかすればいい。

次はSignalR。これも、Nugetで、SignalRを検索して、Microsoft.AspNet.SignalR.Client をインストール。…すればいいはずなのだが、現時点では、一部、CPUアーキテクチャ依存の部分があるらしく、そのアセンブリを置き換えないと動かない。

http://dotnetbyexample.blogspot.jp/2015/05/getting-signalr-clients-to-work-on.html
https://github.com/LocalJoost/SignalRFix

この辺を参考にしてほしい。後は普通に

                var hubConnection = new HubConnection("HUBが実装されたWebサイトのURL”);
                var ledProxy = hubConnection.CreateHubProxy("LEDHub");
                await hubConnection.Start();
                var updateSubscribe = ledProxy.Subscribe("Update");
                updateSubscribe.Received += UpdateSubscribe_Received;

とか書けば、SignalRのメッセージは受信できる。

じゃぁ、後は、Event Hubね…ということなのだが、残念ながら、Event HubのNugetパッケージのWindowsAzure.ServiceBusは、Windows 10未対応。このライブラリ使うのが一番簡単なのだが、現時点ではAMQPNetLiteでがまん(あれ?IoT Kit HoLで公開しているStep1のやりかたそのまま使えるね)ってことで、よろしく。


 



IoTやりたい人向け、Windows 10 IoT Core for Raspberry PI2の開発環境セットアップ

$
0
0

Win10 IoT Core+AzureでIoTをやってみたいという方で、 http://www.WindowsOnDevices.comに従ってセットアップしたけどなんか変という方、参考にしてください。

※こちら、あくまでも2015年6月1日現在のセットアップに関するTIPSです。最新の情報が無いかチェックしてから試みてください。

全般

先ずは、以下のURLで解説されているページをよく読んでください。

http://ms-iot.github.io/content/en-US/win10/SetupPC.htm

 

Visual Studio 2015 RCのインストール

エディションは、Enterprise の選択をお勧めします。

インストーラを起動したときに表示されるダイアログで、“カスタム”を選択してください。

“インストールするオプション機能”で、“Microsoft Web Developer Tool”と“ユニバーサル Windows アプリ開発 ツール”にチェックを入れてください。

 

※  既に“標準”でインストール済みの方は、Installerをもう一度起動して、“変更”をクリックして、上記の二つに✓を入れてインストールし直してください。

 

Visual Studio 2015 RCへのIoT Core Extensionインストール

“Windows 10 IoT Core Insider Preview image
for Raspberry PI 2.zip”ファイルに入っている、WindowsDeveloperProgramForIoT.msiを実行してください。

 

Azure SDK のインストール

http://azure.microsoft.com/ja-jp/downloads/ の左上、.NETカテゴリの“VS 2015のインストール”のリンク(http://go.microsoft.com/fwlink/?linkid=518003&clcid=0x411)をクリックし、VS2015AzurePack.exe をダウンロード&インストールします。

 

開発用PCのデベロッパーモード設定

Raspberry PI2でUniversal Windows アプリを開発するには、開発用のWindows 10 PCが、開発者モードに設定されていなければなりません。

先ず、コマンドプロンプトを管理者モードで起動します。左下のWindowsボタンを右クリックすると“コマンドプロンプト(管理者)(A)”と表示されるので、それを選択します。

開いたコマンドプロンプトで、“Gpedit.msc”と入力し、Enterキーを押します。

表示された“ローカルグループポリシーエディター”の左側のペインで“コンピューターの構成”→“管理者用テンプレート”→“Windowsコンポーネント”→“アプリパッケージの展開”まで開きます。以下の二つの項目をダブルクリックし、ラジオボタンの“有効”を選択して“OK”をクリックします。

  • ”Allows development of Windows Store apps and installing them from an integrated development environment(IDE)“
  •  “信頼できる全てのアプリのインストールを許可する”

 

各自のボードの名前変更

事前にRaspberry PI2でWindows 10を起動可能なら、以下の手順で、自分の好きな名前に変更しておくことをお勧めします。Windows 10 IoT Core Watcherから自分のボードのIPアドレスを見つけやすくなります。

http://ms-iot.github.io/content/en-US/win10/samples/PowerShell.htm

開発用PCとRaspberry PI2を同一ネットに接続し、Raspberry PI2に電源をつなぎます。ネットにつなぐRaspberry PI2は一台のみにしましょう。Raspberry PI2にHDMIモニターをつなぐか、あるいは、Windows 10 IoT Core Watcherで、IPアドレスを確認し、開発用PCでPowerShellを管理者モードで起動します。

 PS
C:\> net start WinRM

調べたIPアドレス(<IP Address>の部分を置き換えてね)を使って、以下を入力します

PS C:\> Set-Item WSMan:\localhost\Client\TrustedHosts -Value <IP Address>

Yを入力し、以下を入力します。

 PS
C:\> remove-module psreadline -force

<IP Address>の部分を各自のIPアドレスに変えて、以下を入力します

PS C:\> Enter-PsSession -ComputerName
<IP Address> -Credential <IP Address or localhost>\Administrator

パスワードを入力します。デフォルトは、“ p@ssw0rd”です。この接続は30秒ほどかかります。気長に待ってください。

接続が確立されたら、名前を変更しましょう。

名前の変更は以下のコマンドで行います。

[xxx.xxx.xxx.xxx]: PS C:\> setcomputername <new-name>

名前の変更を有効にするにはリブートが必要です。以下のコマンドでリブートしてください。

[xxx.xxx.xxx.xxx]: PS C:\> shutdown /r /t 0

Windows 10 IoT Core Watcherが表示されない‼

この症状に悩まされている人、結構多いのでは?

左下のWindowsアイコンを左クリックし、”すべてのアプリ”をクリック、VS2015の下にある、”開発者コマンドプロンプト For VS2015”を右クリックして”管理者で起動”してください。コマンドプロンプトが表示されたら、

cd "\Program Files\Microsoft IoT"  ※Windows 10がx86の場合

cd "\Program Files(x86)\Microsoft IoT"  ※Windows 10がx64の場合

と入力し、

sn -Vr WindowsIoTCoreWatcher.exe

と入力します。オプションはVが大文字、rは小文字です。

これで大体のケースで表示可能になります。

 

Windows IoT Coreで複数のI2Cセンサーを使う

$
0
0

以前のポストで幾つか、I2CセンサーをWindows 10 IoT Coreで制御する方法を紹介しました。I2Cに詳しい方はご存知のはずですが、I2Cでは、一つのバスに複数のセンサーデバイスの接続が可能です。
詳しくは、http://www.i2c-bus.org/を見ていただくことにして、同一のI2Cにバスに接続されたセンサーデバイスは、1バイトのアドレスをそれぞれ持っているので、一つのアプリから複数のセンサーデータ取得が可能です。

各センサーのアドレスの値は、メーカーが公開しているデータシートに記載されています。例えば、WindowsOnDevices.comのサンプルとして紹介されている、ADXL345(加速度)は0x53、BoschのBME280(温度・湿度・大気圧)は0x76といった具合です。

このADXL345とBME280を同時にRaspberry PI2に接続する方法は、図の通り。

Raspberry PI2にあるGND、VDDはどれを使っても構いません。後は、

string aqs = I2cDevice.GetDeviceSelector("I2C1");
var dis = await DeviceInformation.FindAllAsync(aqs);
var settings = new I2cConnectionSettings(I2C_ADDR);
settings.BusSpeed = I2cBusSpeed.FastMode;
var sensor = await I2cDevice.FromIdAsync(dis[0].Id, settings);

 の3行目の、I2C_ADDRに使いたいセンサーのアドレスをセットすれば、センサー計測値を取得するための、I2cDeviceを取り出せます。
データの読み取り方法は、メーカーから公開されている、データシートを参考にしてくださいね。

Node.jsでWindows 10 IoT Coreのセンサーを使う

$
0
0

いやぁ…私がこのブログでJavaScriptとかNode.jsの事を書く時代が来るとはね…

Raspberry PI2で動く、Windows 10 IoT Coreでは、C#、VB、VC++に加えて、Node.js、PythonでUniversal Windows Applicationの開発が可能です。

Node.jsを使うには、http://ms-iot.github.io/content/en-US/win10/samples/NodejsWU.htmで紹介されているように、Visual Studio 2015 RC に IoT Core用のMSIツールをインストール後、追加で、NTVS(Node.js Tools for Visual Studio)Bundle VS2015を更にインストール。
このツールを使うと、Node.js用のプロジェクトテンプレートが出現します。

プロジェクトの作成は、

と、プロジェクトテンプレートで、カテゴリを”JavaScript”→”Node.js”を選択して表示されたテンプレートの”(Windows Universal)”と名前の後ろについているテンプレートを使います。

npmを使うには、ソリューションエクスプローラーで、プロジェクト直下のnpmアイコンを右クリックして、”Install New npm Packages... を選択すれば、所望のパッケージをインストール可能です。

更に、実機(例えば、Raspberry PI2)で動かすには、ソリューションエクスプローラーでプロジェクトを右クリックし、”プロパティ”を選択し、表示されたページの、”Remote Machine”の項目にWindows IoT CoreデバイスのIPアドレスを入力すればOK。

では、センサーのデータを取得するJavaScriptコードをお見せしましょう。センサーは、加速度センサーのADXL345を使います。http://ms-iot.github.io/content/en-US/win10/samples/I2CAccelerometer.htm や、私の以前のポストを参照して、配線してください。

おっと、元々私は、JavaScriptやNode.jsはまるっきり素人なので、どれぐらい素人かというと、Node.jsがサーバーサイド向けのライブラリだと知ったのがこれを書いているつい最近(でもNode.jsと知らないうちから使ってはいましたが)知ったというぐらい、素人です。だから、「普通JavaScriptだったら、そんな風に書かねぇよ」とかいう方がいたら、「この方が楽よ」と、コメント頂ければ幸い。

現状のサンプルには、Node.jsでI2Cセンサーを使うサンプルは公開されていないのと、ま、私がジャバスク素人で普段はC#使いでもあるので、ロゼッタストーン的にC#と並べて、紹介することにします。早速ロゼッタストーンです。

C#JavaScript Node.js






string aqs = I2cDevice.GetDeviceSelector("I2C1");


var dis = await DeviceInformation.FindAllAsync(aqs);

var settings = new I2cConnectionSettings(0x53);
I2CAccel = await I2cDevice.FromIdAsync(dis[0].Id, settings);        










byte[] WriteBuf_DataFormat = new byte[] { 0x31, 0x01 };
byte[] WriteBuf_PowerControl = new byte[] { 0x2d, 0x08 };
I2CAccel.Write(WriteBuf_DataFormat);
I2CAccel.Write(WriteBuf_PowerControl);

// Universal Windows Platform 用パッケージの取得
var uwp = require("uwp");
uwp.projectNamespace("Windows");

// メンバー名は最初の文字が小文字に
var aqs = Windows.Devices.I2c.I2cDevice.getDeviceSelector("I2C1");
var i2cAccel = null;

// 非同期のawait は、done(func(result){...});で受ける
Windows.Devices.Enumeration.DeviceInformation.findAllAsync(aqs).done(function (dis) {        
    var settings = new Windows.Devices.I2c.I2cConnectionSettings(0x53);
    settings.BusSpeed = Windows.Devices.I2c.I2cBusSpeed.FastMode;
    var disI2C;
    for (var i=0; i < dis.length; i++) {
        if (dis[i].id.indexOf("I2C1") != -1) {
            disI2C = dis[i];
            break;
        }
    }
    Windows.Devices.I2c.I2cDevice.fromIdAsync(disI2C.id, settings).done(
        function (i2cdev) {
            i2cAccel = i2cdev;
            var writebuf_dataFormat = [0x31, 0x01];
            var writebuf_powerControl = [0x2d, 0x08];
            i2cAccel.write(writebuf_dataFormat);
            i2cAccel.write(writebuf_powerControl);
        });
});

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

左と右を見比べるとだいたいパターンは判りますね?JavaScript側は名前空間込なのでちょっと文字が多めに見えますね。DeviceInformationクラスのfindAllAsyncメソッドは、C#の場合には戻り値として1項目だけ返ってくるのに対し、2015年6月中旬時点では、JavaScriptは(多分)全部のデバイス情報が返ってきてしまうので(多分不具合)、I2C1という文字列を持っている項目を検索してます。

加速度情報の取出し部分は、

C#JavaScript

byte[] RegAddrBuf = new byte[] { 0x32 };
byte[] ReadBuf = new byte[6];
I2CAccel.WriteRead(RegAddrBuf, ReadBuf);        
short rx = BitConverter.ToInt16(ReadBuf, 0);
short ry = BitConverter.ToInt16(ReadBuf, 2);
short rz = BitConverter.ToInt16(ReadBuf, 4);









double accelX = (double)rx / (1024.0/8.0);
double accelY = (double)ry / (1024.0/8.0);
double accelZ = (double)rz / (1024.0/8.0);

var readbuf_addr = [0x32];
var readbuf_rcvd = [0, 0, 0, 0, 0, 0];
i2cAccel.writeRead(readbuf_addr, readbuf_rcvd);
var rx = readbuf_rcvd[0] + (readbuf_rcvd[1] << 8);        
var ry = readbuf_rcvd[2] + (readbuf_rcvd[3] << 8);
var rz = readbuf_rcvd[4] + (readbuf_rcvd[5] << 8);
if ((rx & 0x80) != 0) {
    rx = rx | 0xffff0000;
}
if ((ry & 0x80) != 0) {
    ry = ry | 0xffff0000;
}
if ((rz & 0x80) != 0) {
    rz = rz | 0xffff0000;
}
  
var ax = rx /( 1024.0 / 8.0);
var ay = ry / (1024.0 / 8.0);
var az = rz / (1024.0 / 8.0);

 

 

 

 

 

 

 

 

 

 

 

 

WriteReadメソッドを0x32という1バイトでコールすると、X、Y、Z方向の加速度の値が2バイトずつ入って返ってきます。これそれぞれ符号付の16ビット整数なので、C#の場合はBitConverterというクラスを使って変換をかけてます。JavaScriptでこのクラスに相当するものを知らなかったので、ここでは、ビットシフトや論理和演算で書いてます。もっとスマートな書き方ご存知の方、教えてくれるとありがたい。
最後に1024.0/8.0で割っているのは、返ってくるのがこの値で割り算すると、地球の重力を基準にした値が得られるから。

こんな感じで、C#のサンプルを置き換えていけば、JavaScript、Node.jsでもコードが書けるはず。インテリセンスが利かないのと、JavaScript不慣れなため、ちゃんと動くコードを作るのにかなり時間がかかりました。インテリセンスが利いて、ある程度デファクトのパッケージやライブラリ知っていれば、そこそこ私にも書けそう。

他に、”request”パッケージを使うと、HTTP REST APIへのアクセスはかなりシンプルに書けることはわかりました。
言語の選択は適材適所で。

PinKitセンサーボードの加速度センサーをラズパイにつなぐ

$
0
0

あ、そういえば、PinKitのセンサーボードにADXL345が載ってるね…ってこで、Windows 10 IoT Core For Raspberry PI2で、PinKitセンサーボードの加速度センサーを使う方法を紹介します。

ADXL345のピンは、PinKitセンサーボードのピンに

  • D15 → SCL
  • D14 → SDA
  • VDD → VDD
  • GND → VDD

の様に対応しているので、Raspberry PI2のピンに図の様につなげばよい。

ちょっと余計なものが写っているのだが、ブレッドボードを使って、

こんな風につなげばよい。

後は、http://ms-iot.github.io/content/en-US/win10/samples/I2CAccelerometer.htmのサンプルのACCEL_I2C_ADDRの値を、0x1dにセットすれば、加速度読み取れます。

PinKitとRaspberry PI2の両方を持っている人は試してみてくださいね。以上、ひつまぶし、あ、暑さのために間違いました、ひまつぶしのTips投稿でした。


MVAのIoT植物栽培コンテンツ修正のお知らせ

$
0
0

今年の2015年6月に行ったキャンペーンの

https://msdn.microsoft.com/ja-jp/dn859234

こちら、IoTの世界に植物栽培で踏み込もう、試された複数の皆様からの内容に誤りがあるとフィードバックをいただきました。かなり間違っていました。ごめんなさい。私の動作確認環境から、公開環境に編集する過程で、いろいろと間違ってしまっていたようです。昨日可能な限り修正いたしました。なにぶん、手作業でやっている関係上、もしかするとまだ誤りが残っているかもしれません。もし、不具合がありましたらお手数ですが、MVAのフォーラム(ページの下のほうにリンクがあります)に書き込みをお願いいたします。

フォーラムで、私の代わりに回答していただいていた、Tatsuo Sajiki様、ご迷惑をおかけしました。ご対応いただきありがとうございました。

ここで紹介されている学習キット、8月1日2日に開催されたMAKER FAIRE TOKYOのマイクロソフトブースで展示したところ、大好評をいただきました。
今後、蓄積データの分析・活用に関するものや、Windows 10 IoT Core等他のプラットフォームでの実施方法など、コンテンツの追加を計画しておりますので、また、よろしくお願いいたします。

Windows 10 IoT Core for Raspberry PI2でAzure Event Hubに接続する

$
0
0

こちらは、2015年8月14日現在の状況をもとに書いています。

Windows Runtime API上のアプリでAzure Event Hubに接続する場合、3つの方法があります。

  1. Windows Azure Service Bus SDKを使う
  2. AMQL Liteを使う
  3. HTTPSでSASTokenを作成してヘッダーに埋め込むコードを書く

Windows系なら1番目が一番簡単ですが、8/14現在、まだ対応するSDKが公開されていないので使えません。
※ソリューションエクスプローラーで、参照フォルダーを右クリックし、NuGetパッケージの管理を選択し、”Windows Azure Service Bus SDK”を検索し、インストールしてみてください。インストールがうまくいったらこれ以上読む必要はありません。

2番目ですが、AMQP Liteは、Windows系だけでなく、.NET Micro Framework、Monoでも使えるので、マルチプラットフォームな組込み機器開発の場合でソースコードを共通化したい時などに便利です。こちらは現時点で使うことができます。
使い方は、ソリューションエクスプローラーで、参照フォルダーを右クリックし、NuGetパッケージの管理を選択し、”AMQP Lite”で検索し、インストールボタンをクリックすれば、インストール完了です。http://aka.ms/IoTKitHoLから公開中のハンズオンコンテンツのStep1接続編に具体的なコードが紹介しているのでそちらも参照してほしいのですが、この投稿でも基本的な使い方を紹介しておきます。

まず、Event Hubへの接続ですが、 

conststring sensorName = "win10iotrpi2";
conststring ehName = "[event hub name]";
conststring accessKey = "[Access Key]";
conststring ehNamespace = "Service Bus Namespace]";
conststring policyName = "[Access Policy Name]";
conststring partitionId = "2";
string amqpAddress = "amqps://[PolicyName]:[Access Key]k=@[Service Bus Namespace].servicebus.windows.net";

privatevoid SetupAMQP()
{
     amqpAddress = "amqps://" + policyName + ":" + accessKey + "@" + ehNamespace + ".servicebus.windows.net";
    Address address = new Address(amqpAddress);
    Connection connection = new Connection(address);
   
Session session = new Session(connection);
     amqpSender = new SenderLink(session, "send-link" + ehName, ehName + "/Partitions/" + partitionId);
}

で、可能です。ここで作成したamqpSenderでデータの送信が可能。ただし、[Access Key]はAzureの管理ポータルから取得した文字列をURLエンコーディングした文字列に置き換える必要があるのでご注意。
送信は、

privatevoid SendData()
{
    var now = DateTime.Now;
  
string payload = "{\"dspl\":\"" + sensorName + "\",\"Subject\":\"wthr\",\"temp\":" + lastPacket.Temperature + ",\"hmdt\":" + lastPacket.RelativeHumidity + ",\"pres\":" + lastPacket.Pressure + ",\"time\":\""
               + now.ToString("yyyy-MM-ddThh:mm:ss.fffZ") + "\"}";
   
var encodedTextData = System.Text.Encoding.UTF8.GetBytes(payload);
  
var message = new Message()
  
{
          BodySection = new Data()
 
         {
              Binary = encodedTextData
           },
           Properties = new Properties()
 
          {
               CreationTime = now,
               ContentType = "text/json"
 
         }
      };
      message.ApplicationProperties = new ApplicationProperties();
      message.MessageAnnotations = new MessageAnnotations();
   
  amqpSender.Send(message, OutcomeCB, null);
   
Debug.WriteLine("send");
}

private void OutcomeCB(Message message, Outcome outcome, object state) {  }

これで、Event Hubの指定したパーティションにデータをJSON形式で送信可能です。

さて、3番目ですが、https://gallery.azureml.net/Tutorial/6f95aeaca0fc43b3aec37ad3a0526a21 から公開されているSensor Data Analytics with ASA and PowerBIというサンプルのソースコード(https://github.com/Azure/azure-stream-analytics/tree/master/Samples/SensorDataAnalytics/SensorTagToEventHub/DeploymentFiles)内で、実際に行われているので、それを参照してください。SendDataToEHLibraryプロジェクトの、SendDataToEventhub.csというファイルの、SendMessageメソッドと、ServiceBusSASAuthenticationメソッドです。そちらみてくださいね。

2015年9月、10月開催予定のIoTハンズオンセミナー受講時の事前準備について

$
0
0

表題の件、明日9月15日からIoTハンズオンセミナーが開催されます。

このセミナーは、.NET Micro Frameworkで制御する組込み機器とマイクロソフトのクラウドAzureの、Event Hub、Stream Analytics、Machine Learning、Storage、Web Apps、WebJob、Mobile Serviceといった各種PaaS、そして、データを可視化するPower BIを使い、開発環境はVisual Studio 2015で、IoT(Internet of Things)の基本的な実装方法を1日かけて学ぼうという、チャレンジングなセミナーです。各地での開催予定は、http://aka.ms/IoTKitHoLのトレーニング概要でご確認いただくとして…

実際に1日でこなす技術・実装の量としては半端なく多いのではないかと、見た感じ思われる方、大勢いらっしゃると思います。

はい、もたもたやっているとたぶん7割ぐらいしかできません。このセミナーの募集時に参加予定の皆さんにお願いしている、事前の実習向けの準備が、最後までスムーズにセミナーが進められるかの命綱でもあります。

この投稿で、事前準備についてより詳しく、説明をさせていただきます。準備完了と思われている方も、是非、以下の説明をご確認いただければと思います。

実習用PC

Windows 7、8、8.1,10のいずれかのOSがインストールされたPCをご用意ください。
.NET Micro Frameworkデバイスを使って作業を行うので、USBポート付きのPCでかつ、Windows環境からアクセス可能な機種をご用意ください。
また、インターネットへの接続が必須なので、Wi-Fiに接続可能な機種をご用意ください。
実習では、Visual Studio 2015を4つ同時に起動して作業を行うので、非力なPCハードウェアの場合、操作性が落ちる可能性があるので、ご留意ください。。

Visual Studio 2015のインストール

Visual Studioは、有償版でも、無償版のCommunity Editionでも構いません。
ただし、インストールの際、Web Developer Tools機能のインストールを忘れないでください。この機能がインストールされていないと、Azure SDKはインストールできません。
インストールの際、機能の選択オプションでWeb Developer Toolsに✔を入れてインストールを行ってください。
既にインストール済みだという方で、Azure SDKがインストールできない場合は、以下の手段でインストール済みのVisual Studioに機能を追加してください。

コントロールパネルを起動し、「プログラムのアンインストールまたは変更」を選択し、検索窓で「Visual Studio 2015」と入力、検索結果が表示されたら選択して、”変更”をクリック。

Visual Studioの設定ダイアログが開いたら、Web Developer Toolsに✔を入れて更新をクリック

後から機能を追加するのにとてつもない時間がかかります。セミナー開始から始めると、最悪の場合、セミナー終了ぐらいまでかかることがあるので、遅くともセミナー参加の前々日までには、開発環境が正しくインストールされているかご確認を。

.NET Micro Framework SDKのインストール

Visual Studio 2015をインストール後、http://netmf.codeplex.com をブラウザで開き、右上の”download"ボタンをクリックします。

クリックすると、”netmf-v4.3.2-SDK-QFE2-RTM.zip"というファイルのダウンロードが始まります。そのまま開かないで、どこか(ダウンロードフォルダーあたり)に保存してください。保存したらZIPファイルを解凍し、中に入っているファイルを実行します。実行順序は、

  1. MicroFrameworkSDK.msiを実行
  2. netmfvs14.vsixを実行

です。2番目のVSIXファイルの実行を忘れずにお願いします。事情により、有償版も、Community Editionも使えず、Express Editionしか使えない場合は、Express for Desktopをお使いください。その場合、クラウド側の開発はExpress for Webで行うので、そちらもインストールが必要になります。

Azure SDKのインストール

http://azure.microsoft.com/ja-jp/downloads/を開き、.NETのVS2015をクリックして、VWDOrVs2015AzurePack.exe をダウンロード&実行してください。


冒頭で説明したVisual Studio 2015のインストール時の注意点を守っていればインストールは成功するはずです。

Azure Subscription契約

http://azure.microsoft.comを開き、右上の”無償評価版”を右クリックして開いたページの”今すぐ試す”をクリックしてください。サブスクリプション契約にはクレジットカードが必要です。1か月間の無料評価期間があります。この期間、20500円相当が利用可能です。無料評価期間終了が近づくとメールが来ます。1か月経つとご契約いただいたアカウントは凍結されます。各自の責任において、契約を継続する場合には、受け取ったメールを参照して手続きを行ってください。継続設定した際に、有料のサービスを利用していた場合は、その利用内容に従って課金が始まりますのでご注意ください。そのまま何もせず、契約更新作業をしなければ、支払いは発生しません。
MSDN Subscription付きのVisual Studioをご利用の方は、MSDN SubscriptionのポータルからAzureをActivationして利用可能です。Editionにより、月々の無償利用枠もあるので、そちらのご利用をお勧めします。また、ベンチャー系企業の方は、BizSparkという支援プログラムもありますので、http://www.microsoft.com/ja-jp/ventures/BizSpark.aspx からご利用ください。

さて、SDKのインストールが正しくできたかどうかの確認方法を最後に紹介します。

.NET Micro Framework SDK

Visual Studio 2015を起動し、メニューの”ファイル”→”新規作成”→”プロジェクト”を選択します。

プロジェクトが作成されたら、デバッグ実行します。

エミュレーターが起動して図のような表示がでればインストールは完了です。

デバッグ実行時、”MMP : error MMP0000: 0x80131700” と表示される場合、http://netmf.codeplex.com/workitem/221 を参考に、このページから、MetaDataProcessor.exe.config をダウンロードし一旦適当な場所に保存します。このファイルを、C:\Program Files (x86)\Microsoft .NET Micro Framework\v4.3\Tools にコピーしてください。コピー実行後、再度、デバッグ実行すれば、問題は解決します。

Azure SDK

Visual Studioを起動し、メニューの”ファイル”→”新規作成”→”プロジェクト”を選択し、Azureプロジェクト作成に必要なテンプレートが表示されるか確認してください。

図に示されているプロジェクトテンプレート群が表示されなければ、SDKのインストールを再度確認してください。

さて、Visual Studio 2015のインストールから始めると非常に時間がかかります。なるべく早めの準備を行って、万全の態勢で、当日お越しください。お待ちしてます‼

Azure Storage SDKについて

$
0
0

本日2015年9月15日に行ったIoTハンズオンセミナーで、参加者の方に指摘を受けた、Azure Storage SDKに関する解決策です。

https://azure.microsoft.com/en-us/documentation/articles/storage-dotnet-how-to-use-tables/

にAzure Storage SDKでTableにアクセスする方法が記載されています。ここでは、NuGetパッケージでAzure Storage SDKのみインストールすればよいと書かれていますが、執筆時点では、CloudConfigrationManagerが入っているアセンブリーがインストールされないようです。

NuGetパッケージの管理で、検索窓に”Azure Configuration Manager”と入力すると見つかる、”Microsoft.WindowsAzure.ConfigurationManager”をインストールしてください。これで、問題は解決です。

 

 

Windows 10 IoT Core+WebCam+Azureで簡単定点観測カメラ

$
0
0

Windows 10 IoT Core on Raspberry PI2のWebCam接続が確認できたので、一筆。
PCとUSBで接続可能なWebCamがあれば、定期的に画像を記録する仕掛けは簡単にできますね。しかしそのためにずっとPCを一台動かしているのはなんだか無駄。じゃあRaspberry PI2使おう…しかし、ずっと画像を蓄積続けるためにはストレージが足りないね…ということで、Microsoft AzureのBlob ストレージに貯めよう。そうすればセキュアに遠隔から画像も取り出せるし…

ということで、やり方をざっくり紹介。

まず、Visual Studio 2015で、新規プロジェクトを作成します。テンプレートは、Visual C#→Windows→ユニバーサル→空白のアプリを使います。プロジェクトができたら、MainPage.xamlの<Grid>...</Grid>を

<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
   
<Canvas Grid.Row="1" x:Name="canvasPicture" Margin="5">
       
<CaptureElement x:Name="previewElement"/>
   
</Canvas>
</Grid>

のように、CanvasとCaptureElementタグを追加します。WebCamの画像はいったんこのCaptureElementに割り付けます。

次に、AzureのBlobにアクセスするために、Azure Storage SDKをインストールします。ソリューションエクスプローラーで参照を右クリックして、NuGetパッケージの管理を選択、Azure Storage SDKと検索窓に入力し、表示されたらインストールしてください。

そして、MainPage.xaml.csを開き、

publicsealedpartialclassMainPage : Page
{
    public MainPage()
     {
         this.InitializeComponent();
      
this.Loaded += MainPage_Loaded;

     }
      MediaCapture mediaCaptureManager;
    StorageFile photoStorageFile;
   
string capturedPhotoFile = "CapturedPhoto.jpg";
   
   
privateasyncvoid MainPage_Loaded(object sender, RoutedEventArgs e)
 
    {
            mediaCaptureManager = new MediaCapture();
       
try
            {
                await mediaCaptureManager.InitializeAsync();
                previewElement.Source = mediaCaptureManager;
                await mediaCaptureManager.StartPreviewAsync();

                InitializeTimer();
                uploadTimer.Start();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
        DispatcherTimer uploadTimer;
     
     
privatevoid InitializeTimer()
        {
            if (uploadTimer == null)
            {
                uploadTimer = new DispatcherTimer();
         
int intervalMin = 15;
                uploadTimer.Interval =TimeSpan.FromMinutes(intervalMin);
                uploadTimer.Tick += (o, s) =>
                {
                    UploadPhoto();
                };
            }
        }
        privatestring storageAccountName = "[storage name]";
     
privatestring storageAccountKey = "[storage access key]";
    
privateasyncvoid UploadPhoto()
        {
            uploadTimer.Stop();
            photoStorageFile = await Windows.Storage.KnownFolders.PicturesLibrary.CreateFileAsync(capturedPhotoFile, Windows.Storage.CreationCollisionOption.GenerateUniqueName);
       
ImageEncodingProperties imageProperties = ImageEncodingProperties.CreateJpeg();
       
try
            {
                  await mediaCaptureManager.CapturePhotoToStorageFileAsync(imageProperties, photoStorageFile);
           
var cloudStorageAccount = CloudStorageAccount.Parse("DefaultEndpointsProtocol=https;AccountName=" + storageAccountName + ";AccountKey=" + storageAccountKey);
           
var blobClient = cloudStorageAccount.CreateCloudBlobClient();
           
var container = blobClient.GetContainerReference("photos");
           
await container.CreateIfNotExistsAsync();
           
var fileName = "photo" + DateTime.Now.ToString("yyyyMMdd-hh:mm::ss-fff") + ".jpg";
           
var blockBlob = container.GetBlockBlobReference(fileName);
           
await blockBlob.UploadFromFileAsync(photoStorageFile);

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            uploadTimer.Start();
        }

と、MainPageクラスの内容を書き換えます。名前空間が一部足りないのでusing宣言を適宜加えてください。storageAccountNameとstorageAccountKeyは、AzureのポータルでStorageを作成して取得してください。

あとは、Package.appxmanifestをコードで開くで開き(もしソリューションエクスプローラーで開けなければ、メモ帳などで開いてください。)、以下のように<Capability>タグに使用する機能を追加宣言します。

  <Capabilities>
    <Capability Name="internetClient"/>
   <uap:Capability Name="picturesLibrary" /> 
   <DeviceCapability Name="microphone" /> 
   <DeviceCapability Name="webcam" /> 
  </Capabilities>

これでOK.すべて完了。15分ごとにAzureのBlobストレージにアップロードします。センサーで計測しながら画像を蓄積しておけば、センサーがある値を記録した時に何が起こっていたかを記録することができるわけです。ちなみにこのコード、ユニバーサルアプリで作っているので、Windows10 の普通のPCでも動きます。WebCam持っている人ぜひお試しを。
※WebCamの中にはWin10IoTCore Raspberry Pi2に対応していない機種もあるのでご注意。

なおこの投稿の詳細な手順は、今後、http://aka.ms/IoTKitHoLにて公開しますんで、ご期待ください。

Azure IoT Hub、IoTデベロッパーセンター始まりした

$
0
0

昨年来、AzureにIoTサービスを加えますよ!とアナウンスしておりましたが、ついに2015年9月30日にAzure IoT Suite、及び、IoT Hubのプレビューが公開されました。加えて、IoTデベロッパーセンターというページも出来上がっています。
この投稿では、これらの概要を紹介します。

まず皆さん、ブラウザで、http://azure.microsoft.com  を開いてみてください。そして、ドキュメントタブをクリックしてみてください。

はい、”モノのインターネット”、という項目が追加されてます!ここからIoT関連はたどっていってくださいね。先ずは、一番下の”IoT Hub”を選択してみましょうか。
https://azure.microsoft.com/ja-jp/documentation/services/iot-hub/

というページが開きます。このページの”チュートリアルの開始”という緑色のボタンを押すと、Windows 7以上のPC、Visual Studio 2013以上で、直ぐにこのIoT Hubを試すプログラミング方法が解説されています。ちょっとね、まだプレビューなんで書かれている通りに動かなかったりする部分もあるのですが、まずは、お試しください。

IoT Hubの中では、既に正式版が公開されている、メッセージを高速に送受信可能なブローカーサービスである、Event Hubが使われています。Event Hubは、IoTと似たような細かいデータがばらばらと高速に飛んでくるようなシステムで利用可能で、Event Hubへの接続数、データ転送量、スループットなどで、性能や金額が管理されるのに対して、IoT Hubは接続する組込み機器を単位として、性能や課金が決められています。IoT Hubの機能紹介を兼ねて、ざっと一般的な利用シナリオを紹介すると、

  • 組込み機器をIoT Hubに登録
  • 組込み機器をIoT Hubに接続
  • 組込み機器からIoT Hubにデータを送信
  • IoT Hubにサブスクライブしたサービス側でデータを受信
  • サービス側からIoT Hubを通じて組込み機器にデータを送信
  • 組込み機器がIoT Hubを通じて、コマンドを受信
  • 組込み機器がコマンドを受信したことを、サービス側でAckとして通知を受ける
  • 登録された組込み機器情報の取得

ざっと、こんな感じです。Event Hubと同様、Stream Analyticsにも簡単につなげられるので、例えば、組込み機器に装備されたセンサーデータをIoT Hubで受信してStream Analyticsに連結することが簡単にできて、そのままPowerBIにつないでダッシュボード表示をしたり、定義済みのルールに従ってデータを変換したり、通知を上げたり、バックエンドのWebJobを起動したりといった構成が簡単に組めます。


接続の管理は、Event Hubと同じように、ロールベースのトークンです。あらかじめ管理用、デバイス用、サーバーバックエンド用、デバイス管理用といったロールが定義されていて、それぞれにセキュリティトークンが提供されています。

使えるプロトコルは、HTTPSとAMQPです。最近、MQTTの問い合わせが多いですが、MQTTは今後何らかの形でExtensionとして提供される見込みです。(※あくまでも著者見解ですがMQTTのセキュリティレベルだと、IoT HubやEvent Hubが想定しているセキュリティレベルを満たせないので、IoT HubそのものにMQTTが使えるようになるのはちょっと難しいのかなと感じます)
今後、もっと微に入り細に入り、IoT Hubは解説していきますが、まずは、 https://azure.microsoft.com/ja-jp/documentation/articles/iot-hub-what-is-iot-hub/や、https://azure.microsoft.com/ja-jp/documentation/articles/iot-hub-devguide/をご覧くださいね。

IoT Hubに接続する組込み機器向けに、GitHubで、SDKが提供されています。現在提供されているのは、

  • C# - .NET Framework系
  • C# - WinRT系
  • C言語 - 色々な組込み系OS向け
  • Java - ま、組込みでもJava使っている人いますよね?
  • JavaScript

の五種類です。SDKは、

https://github.com/Azure/azure-iot-sdks/

から公開されています。
先ほど紹介したURLには、IoT Hubのつなぎ方に関する情報も書かれているので、この五種類以外の場合にも、それを参考にしてトライしてみてください。うまくいったら、このブログで紹介しますので、是非ご一報を。

私が今、作成&公開中のIoTハンズオンコンテンツ http://aka.ms/iotkitholv2onも、もう少ししたら、IoT Hubを取り入れますので、こうご期待。

さて、次はIoTデベロッパーセンターです。組込み機器のハードウェアやOS、ミドルウェアは千差万別です。様々な組込み機器の接続を支援する、ページとしてIoTデベロッパーセンターができました。
Azureのポータルサイトの”ドキュメント”→”モノのインターネット”→”IoTデベロッパーセンター”を選択して、表示されたページの”デバイスを接続する”という緑色のボタンをまずはクリックしてみてください。ボード、プラットフォーム、言語別に、サンプルコードが表示できるようになっています。お手持ちのハードウェアがあれば、是非、試してみてください。それから、モノを作っている皆さんは、Azure Certified IoTというプログラムも始まっているので、是非、こちらも検討していただければと。
https://azure.microsoft.com/ja-jp/marketplace/certified-iot-program/

現在、続々と新しいコンテンツが追加中です。

https://azure.microsoft.com/ja-jp/documentation/articles/?service=iot-hub

を是非定期的に見てくださいね。

IoT HubにWindows 10 IoT Coreでつなぐ

$
0
0

さてと…

※この投稿は、2015/10/22現在の公開情報を元に記載しています。最新の情報がないか確認してくださいね。

IoT Hubのプレビューが9/30に公開されました。タイミング的にちょっと遅い気もしますが、Raspberry Pi2で動作するWindows 10 IoT CoreデバイスをIoT Hubに接続する方法を説明します。とりあえず試す方法が、https://azure.microsoft.com/ja-jp/documentation/articles/iot-hub-csharp-csharp-getstarted/ に書かれています。この説明は、.NET Framework上でC#を使ったサンプルで、Windows 10 IoT Coreの場合はWindows RT上で動くUniversal Windows Applicationという違いがあって、そのままでは、動かすことができません。更に、プレビュー状態のため、説明通りにいかない部分もあるので、ここで解説しておきます。

※IoT Hubにつなぐ部分、送受信する部分は、通常のWindows 10のUWAでも利用できます。

折角なので、加速度センサー(ADXL345)、温度センサー(BME280)を使ってIoT Hubに送ってみましょう。基本の部分は、https://doc.co/4dEWrJを見てください。ハードウェアの構成は、このドキュメントに記載の

これに加えて、LEDも追加します。

 

 

 

 

次に、センサーやLEDをI2CやGPIOで制御するために、IoT Extensionを参照に加えます。

そして、https://doc.co/4dEWrJに記載に従って、MainPage.xaml.csのProgramクラスにdeviceId(Guid値)と、プロジェクトにSensorクラスを追加してください。

次は、IoT Hubへのアクセス用ライブラリの追加です。本来ならNuGetを使ってインストールできるのですが、本投稿を書いている時点でははうまくいかないので、ブラウザで、

https://github.com/Azure/azure-iot-sdks/

を開き、表示されたページの右横にある、”Download ZIP”をクリックし、どこかにZIPファイルを保存、ZIPファイルのプロパティでブロックを外し(必ずやってくだいね)、適当な場所に保存します。
csharp/Microsoft.Azure.Devices.Client.WinRTに入っているMicrosoft.Azure.Devices.Client.WinRT.csprojをプロジェクトに参照追加します。

ソリューションエクスプローラーで、ソリューションを右クリックし、”追加”→”既存のプロジェクト”を選択し、Microsoft.Azure.Devices.Client.WinRT.csproj を選択し、ソリューションに追加してください。
次に、追加したSDKのプロジェクトを、作成中のプロジェクト参照として追加します。これで、NuGetで組み込んだのと同じ状態になります。

 これで、IoT Hubにアクセスする準備は完了です。

後は、Modelsという名前でフォルダーをプロジェクトに作成し、そのフォルダーにSensorReadingという名前でクラスを作成し、

public class SensorReading
 {

     public string deviceId { get; set; }
   public double temp { get; set; }
  
public double accelx { get; set; }
  
public double accely { get; set; }
   
public double accelz { get; set; }
  
public DateTime time { get; set; }
  
public string msgId { get; set; }
}

と、コーディングしてください。このクラスを使ってセンサー計測値をJSONに変換します。

さて、MainPage.xaml.csのnamespaceの中身を以下の様に編集します。

namespace Win10IoTDevice
{
    using Windows.Devices.Gpio;
    using Microsoft.Azure.Devices.Client;
    using System.Threading.Tasks;
    using System.Diagnostics;
    using Newtonsoft.Json;
    using System.Text;

    /// <summary>
    /// それ自体で使用できる空白ページまたはフレーム内に移動できる空白ページ。
    /// </summary>
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
            this.Loaded += MainPage_Loaded;
        }

        Guid deviceId = new Guid(/* your device guid */);

        static string iotHubUri = "[your iot hub].azure-devices.net";
        static string deviceKey = "[your device key for your device guid]";

        private void MainPage_Loaded(object sender, RoutedEventArgs e)
        {
            InitLEDGPIO();
            InitializeSensor();
            InitializeUploadIoTHub();
        }

        DeviceClient deviceClient;
        DispatcherTimer uploadTimer;
#pragma warning disable 4014
        private void InitializeUploadIoTHub()
        {
            try
            {
                deviceClient = DeviceClient.Create(iotHubUri, AuthenticationMethodFactory.CreateAuthenticationWithRegistrySymmetricKey(deviceId.ToString(), deviceKey), TransportType.Http1);

                uploadTimer = new DispatcherTimer();
                uploadTimer.Interval = TimeSpan.FromMinutes(2);
                uploadTimer.Tick += UploadTimer_Tick;
                uploadTimer.Start();

                ReceiveCommands();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

        private async void UploadTimer_Tick(object sender, object e)
        {
            uploadTimer.Stop();
            await SendEvent();
            uploadTimer.Start();
        }

        async Task SendEvent()
        {
            List<SensorReadingBuffer> currentReadings = new List<SensorReadingBuffer>();
            lock (this)
            {
                foreach (var r in lastSensorReading)
                {
                    currentReadings.Add(new SensorReadingBuffer()
                    {
                        AccelX = r.AccelX,
                        AccelY = r.AccelY,
                        AccelZ = r.AccelZ,
                        Temperature = r.Temperature,
                        Timestamp = r.Timestamp
                    });
                }
                lastSensorReading.Clear();
            }
            Debug.WriteLine("Device sending {0} messages to IoTHub...\n", currentReadings.Count);

            try
            {
                List<Models.SensorReading> sendingBuffers = new List<Models.SensorReading>();
                for (int count = 0; count < currentReadings.Count; count++)
                {
                    var sensorReading = new Models.SensorReading()
                    {
                        msgId = deviceId.ToString() + currentReadings[count].Timestamp.ToString("yyyyMMddhhmmssfff"),
                        accelx = currentReadings[count].AccelX,
                        accely = currentReadings[count].AccelY,
                        accelz = currentReadings[count].AccelZ,
                        deviceId = deviceId.ToString(),
                        temp = currentReadings[count].Temperature,
                        time = currentReadings[count].Timestamp
                    };
                    sendingBuffers.Add(sensorReading);
                }
                var payload = JsonConvert.SerializeObject(sendingBuffers);
                Message eventMessage = new Message(Encoding.UTF8.GetBytes(payload));
                Debug.WriteLine("\t{0}> Sending message: {1}, Data: [{2}]", DateTime.Now.ToLocalTime(), currentReadings.Count, payload);

                await deviceClient.SendEventAsync(eventMessage);
            }
            catch (Exception ex)
            {
                Debug.Write(ex.Message);
            }
        }

        async Task ReceiveCommands()
        {
            Debug.WriteLine("\nDevice waiting for commands from IoTHub...\n");
            Message receivedMessage;
            string messageData;

            while (true)
            {
                receivedMessage = await deviceClient.ReceiveAsync();

                if (receivedMessage != null)
                {
                    messageData = Encoding.ASCII.GetString(receivedMessage.GetBytes());
                    Debug.WriteLine("\t{0}> Received message: {1}", DateTime.Now.ToLocalTime(), messageData);
                    var command = messageData.ToLower();
                    if (command.StartsWith("gpio:"))
                    {
                        var order = command.Split(new char[] { ':' });
                        switch (order[1])
                        {
                            case "0":
                                LedControl(0);
                                break;
                            case "1":
                                LedControl(1);
                                break;
                            case "2":
                                LedControl(2);
                                break;
                        }
                    }
                    await deviceClient.CompleteAsync(receivedMessage);
                }

                await Task.Delay(TimeSpan.FromSeconds(10));
            }

        }
#pragma warning restore 4014

        IoTDevice.IoTKitHoLSensor mySensor;
        DispatcherTimer measureTimer;
        private void InitializeSensor()
        {
            mySensor = IoTDevice.IoTKitHoLSensor.GetCurrent(IoTDevice.IoTKitHoLSensor.TemperatureSensor.BME280);
            lastSensorReading = new List<SensorReadingBuffer>();
            measureTimer = new DispatcherTimer();
            measureTimer.Interval = TimeSpan.FromMilliseconds(1000);
            measureTimer.Tick += MeasureTimer_Tick;
            measureTimer.Start();
        }

        private void MeasureTimer_Tick(object sender, object e)
        {
            var reading = mySensor.TakeMeasurement();
            lock (this)
            {
                lastSensorReading.Add(new SensorReadingBuffer()
                {
                    AccelX = reading.AccelX,
                    AccelY = reading.AccelY,
                    AccelZ = reading.AccelZ,
                    Temperature = reading.Temperature,
                    Timestamp = DateTime.Now
                });
            }
        }

        List<SensorReadingBuffer> lastSensorReading;

        void LedControl(int onLedId)
        {
            for (int i = 0; i < LED_PIN.Length; i++)
            {
                ledPin[i].Write(GpioPinValue.High);
            }
            ledPin[onLedId].Write(GpioPinValue.Low);
        }

        GpioPin[] ledPin = new GpioPin[3];
        int[] LED_PIN = { 5, 6, 13 };
        // GPIO5 - 29
        // GPIO6 - 31
        // GPIO13 - 33
        // 5V - 2
        private void InitLEDGPIO()
        {
            var gpio = GpioController.GetDefault();
            for (int i = 0; i < LED_PIN.Length; i++)
            {
                ledPin[i] = gpio.OpenPin(LED_PIN[i]);
                if (ledPin[i] != null)
                {
                    ledPin[i].Write(GpioPinValue.High);
                    ledPin[i].SetDriveMode(GpioPinDriveMode.Output);
                }
            }
        }

    }

    class SensorReadingBuffer
    {
        public double Temperature { get; set; }
        public double AccelX { get; set; }
        public double AccelY { get; set; }
        public double AccelZ { get; set; }
        public DateTime Timestamp { get; set; }
    }
}

コードの中で、deviceId、iotHubUri、deviceKeyという変数がありますが、まずはGuid生成ツールで新規にGuidを作成して設定し、

https://azure.microsoft.com/ja-jp/documentation/articles/iot-hub-csharp-csharp-getstarted/

に記載のCreateDeviceEntryアプリでDevice Keyを作成して、deviceKeyの値とし、作成したIoT HubのURLにあわせてiotHubUri変数を編集すれば動きます。チュートリアルと上のコードを見比べてみてください。IoT Hubとの送受信の部分は基本同一です。

1秒ごとにセンサー計測値を貯めて、2分ごとにIoT Hubに貯めたデータを一括送信します。チュートリアルのReadDeviceToCloudMessagesを起動しておくと送信したデータを確認できます。また、

https://azure.microsoft.com/ja-jp/documentation/articles/iot-hub-csharp-csharp-c2d/

に記載の、SendCloudToDeviceSendCloudToDeviceMessageAsyncメソッド

private async static Task SendCloudToDeviceMessageAsync(string command)
{
   
var commandMessage =new Message(Encoding.ASCII.GetBytes(command));
    await serviceClient
.SendAsync("device id guid", commandMessage);
}
と変更し、7のMainメソッドを
Console.WriteLine("Send Cloud-to-Device message\n");
serviceClient
=ServiceClient.CreateFromConnectionString(connectionString);
Console.WriteLine("Press any key to send a C2D message.");
var string command = Console.ReadLine();
SendCloudToDeviceMessageAsync(command).Wait();
Console.ReadLine();
と変更して、実行して、コンソールで、gpio:0、とか、gpio:1とか、gpio:2とか入力すると、Raspberry Pi2側でデータを受信し、対応するLED(0の場合はGPIO5、1の場合はGPIO6、2の場合はGPIO13に、つながっているLEDが光ります。
以上、かなりはしょって説明しましたが、機材が手元にある人はやってみてくださいね。まだ、プレビューなので、結構落ちたりしますが、フィードバックもよろしくお願いします。
安定したころを見計らって、https://doc.co/M7uGBDにIoT Hubシナリオを追加予定です。
新しい技術を獲得する唯一の早道は、実際にやってみることです。是非チャレンジしてみてくださいね

.NET Micro Framework 4.4 リリース

$
0
0

.NET Micro Framework の最新バージョン、4.4のRC版がリリースされました

http://blogs.msdn.com/b/netmfteam/archive/2015/10/21/net-micro-framework-4-4-is-now-available.aspx

ネットワークの安定性向上、いくつかのモダンなCPU向けの参照実装、Windows 10のUWPのAPIに似せたAPI(Device制御系)の追加等が含まれています。対応するVisual Studioは、2015の有償版、Community Editionです。
※2015 Expressには対応していないようです。

SDKインストールのためのファイル群(MicroFrameworkSDK.msi、NetMFVS14.vsix)は、
https://github.com/NETMF/netmf-interpreter/releases

からダウンロードできます。

現状では色々と不具合があるようなので、特にNETMF4.3をインストール済みの皆さんは、使う場合には注意が必要です。
https://yseosoft.wordpress.com/2015/10/24/netmf-net-micro-framework-v4-4-%e3%81%8c-rtw-%e3%81%97%e3%81%be%e3%81%97%e3%81%9f%e3%80%82%e3%81%8c%e3%80%81v4-3-%e9%96%8b%e7%99%ba%e8%80%85%e3%81%af-visual-studio-%e3%81%ae%e6%9b%b4%e6%96%b0/
に説明があるので、参考にしてください。

特に、Visual Studio 2015で、.NET Micro Framework 4.3を使っている皆さん、Visual Studio 2015からは、VSIXでインストールした機能にアップデートがあった場合、自動的に更新を適用する機能が入っているので、デフォルトではいつの間にか.NET Micro Framework 4.4にバージョンアップされて、コンパイルエラーになったり、デバッグできなかったりするようになるので、上の瀬尾さんの説明を読んで、.NET Micro Framework 4.3の再インストールを行った後、メニューの”ツール”→”拡張機能と更新プログラム”を選択し、

".NET Micro Framework project system"を選択して、”この拡張機能を自動的に更新する”のチェックボックスのチェックを外してください。

他のトピックスとして、.NET Micro Frameworkではそれ以外にも新しい取組みが始まっています。LLILUMです。
http://blogs.msdn.com/b/netmfteam/archive/2015/10/04/llilum-roadmap-and-latest-additions.aspx

既に初期バージョンのLLILUM SDKがVisual Studio向けに出ています。https://github.com/NETMF/llilum を読んでも今一つLLILUMとは何かがよくわからない感じですが、従来の.NET Micro Frameworkより、更に小さく、かつ、ハイパフォーマンスなバイナリを生成する技術と思ってください。
現在は、C#ですが、PythonやJavaScriptのサポートやUWPアプリも対応予定のようです。https://github.com/NETMF/llilum/wiki/roadmap もう少し簡単に使えるようになったらまたこのブログで紹介しますね

 

 

IoTハンズオンコンテンツVer2公開中

$
0
0

9月から初めて先週土曜日(10/24)に終わった、IoTハンズオンセミナー、参加された皆さん、お疲れ様でした。

誤字脱字、わかりにくい部分を見直した資料をネット上で公開中です。

http://aka.ms/iotkitholv2on

構成を説明しておくので、参加された皆さんは復習を兼ねて、「え?そんなセミナーやってたの?」とか「時間が合わなくて参加できなかった…」という方は、是非チャレンジしてみてくださいね。

上のURLを開くと、ハンズオンコンテンツ全体を説明した資料が表示されます。このコンテンツは、GR-PEACH+センサーボードのPinKitという、.NET Micro FrameworkでC#でアプリをかけるボードを使っています。現在種々の事情で入手が困難な状況です。
PinKitのほかに、Windows 10 IoT Core for Raspberry PI2や、ハードウェアを一切使わないPCだけで実習が可能なコンテンツも用意しています。

Windows 10 IoT Core for Raspberry PI2で実習したい方は、ハンズオンコンテンツ全体を説明した資料と、上のURLを開いたときに左側に表示されている「IoTKitHoLV2_Win10IoTCore for Raspberry PI2」というコンテンツを組み合わせて実習してくださいね。

PCしかない(Windows 7、Windows 8.1、Windows 10で実習可能)方は、ハンズオンコンテンツ全体を説明した資料と、「IoTKitHoLV2_WPFEmulator」というコンテンツを組み合わせて実習してください。まぁ、やっぱり、なんといっても、実際のセンサーで計った値のほうがリアルで面白いんですけどね。

どちらも、ハンズオンコンテンツ全体を説明した資料の、.NET Micro Frameworkの部分を抜き出して置き換えた文書になっています。
他に「IoTハンズオン事前準備手順書」というドキュメントも用意したので、実習する場合には、このドキュメントを見て環境のセットアップなど行ってください。

なお、2015/9/30にプレビュー公開されたIoT Hubは、2015/10/26時点の内容では対応していません。Event Hubを使った内容になっております。もう少ししたら、IoT Hub対応を追加する予定です。ん…待てない!!という方は、現在公開中のコンテンツと、http://blogs.msdn.com/b/hirosho/archive/2015/10/22/iot-hub-windows-10-iot-core.aspx のコンテンツを組み合わせると、とりあえずは、実践できるのでチャレンジしてみてくださいね。
他にも、今後は、AllJoynによるローカルネット連携+クラウドや、クラウドからデバイスへのコマンド送信のシナリオも追加予定です。今後、http://aka.ms/IoTKitHoL側にも反映していく予定です。

このコンテンツを解説する、動画付きのコンテンツも作成して公開予定なので、公開した暁にはよろしくお願いします。

それから、本コンテンツで取り上げているハードウェア、OS、ミドルウェア、言語以外のハードウェアをつなぐ試みも、大歓迎ですので、そんな拡張をされた方は是非ごれんらくくださいませ。

Windows 10 IoT Core for Raspberry Pi2 と周辺機器をシリアル通信(RS232c)でつなぐ

$
0
0

このポストでは、Windows 10 IoT Coreで動くRaspberry Pi2を、大昔からの定番、RS232cシリアル通信で周辺機器と接続する方法を解説します。

※本ポストは、http://ms-iot.github.io/content/en-US/win10/samples/SerialSample.htmを元に書いています。
※本ポストは、2015/10/30現在の情報を元に記載しています。OSの機能サポートの状況など、適宜確認してくださいね。

昔からPCや制御用コンピュータと周辺機器をつないで装置を開発していた皆さんなら全員ご存じのはずのRS232Cによるシリアル通信で、かつ、評価ボード系の周辺デバイスをリード線等でつなぐケースを解説します。

まずはつなぎ方です。

図の様に、

  • GND ‐ Pin 6
  • TX - Pin 8
  • RX - Pin 10

でつなぎます。TXは送信、RXは送信なので、接続先の周辺機器はつなぎ方が逆になります。
この接続で、Windows 10 IoT Coreは、URT0というポートでシリアル接続されたと認識します。

※この投稿を実際に試すには、10/30現在、http://ms-iot.github.io/content/en-US/Downloads.htmから公開中のInsider Previewのほうをダウンロードして作成したOSイメージを使ってくださいね

プログラムの大まかな流れは、

  • シリアルポートを探す
  • シリアルポートを開く
  • データ送信・受信を行う

です。アプリケーションは、Windowsのユニバーサルアプリ形式で開発してください。
※GPIOやI2Cを使ったアプリを組むのに必要だった、IoT Extensionの参照追加は必要ありません。

まず、シリアルポートを探すロジックですが、

        List<DeviceInformation> listOfDevices = new List<DeviceInformation>();
  
        private async void ListAvailablePorts()
        {
            try
            {
                string aqs = SerialDevice.GetDeviceSelector();
                var dis = await DeviceInformation.FindAllAsync(aqs);
                for(int i = 0; i < dis.Count; i++)
                {
                    listOfDevices.Add(dis[i]);
                }
            }
            catch(Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }

Windows.Devices.SerialCommunicationという名前空間にあるSerialDeviceクラスを使って、Windows.Devices.Enumerationという名前空間のDeviceInforamtionクラスで定義されたシリアル通信のデバイス情報を取り出します。名前空間のusing宣言は適宜追加してくださいね。
※例えば、DeviceInformationという文字列にマウスカーソルを持って行ったときに表示される豆電球のようなアイコンをクリックすると、using宣言を追加する項目が表示され、選択するとソースコードに追加されます。

冒頭の図のような接続で、かつ、USB接続によるシリアルデバイスがつながっていなければ、URT0ポートに関する情報が一つだけ、listOfDevicesに格納されます。
※ここで説明されている内容は、Windows 10 IoT Coreだけでなく、通常のWindows 10でも使えるコードです。

次にシリアルポートを開くコードです。RS232c由来のシリアル通信では、通信のボーレート、パリティ、ストップビット、データビット、ハンドシェークを指定する必要があります。ここでは、9600bps、パリティ無し、ストップビット1ビット、データビット8ビット、ハンドシェークなしのコードを紹介しています。

        private async Task OpenPort()
        {
            DeviceInformation entry = (DeviceInformation)listOfDevices[0];
            serialPort = await SerialDevice.FromIdAsync(entry.Id);
            serialPort.WriteTimeout = TimeSpan.FromMilliseconds(1000);
            serialPort.ReadTimeout = TimeSpan.FromMilliseconds(1000);
            serialPort.BaudRate = 9600;
            serialPort.Parity = SerialParity.None;
            serialPort.StopBits = SerialStopBitCount.One;
            serialPort.DataBits = 8;
            serialPort.Handshake = SerialHandshake.None;

            dataWriteObject = new DataWriter(serialPort.OutputStream);
            dataReaderObject = new DataReader(serialPort.InputStream);

        }

途中でタイムアウト設定もしています。1000msecなので、1秒でタイムアウトと設定されています。ボーレートやパリティも含め、それぞれのケースに応じて適切な値を設定してください。
SerialDevice.FromIdAsync(entry.Id)で取得されたserialPortのプロパティを覗いてみると、UART0とポート名が格納されています。最後の二行は、データの送信、受信を行うためのWriterとReaderです。

データを送信するには、

            string data = "Hello - from RPI2";
            dataWriteObject.WriteString(data);
            Task<UInt32> storeAsyncTask = dataWriteObject.StoreAsync().AsTask();
            UInt32 bytesWritten = await storeAsyncTask;

こんな風にコードを書きます。実際にデータが周辺機器に送信されるのは、最後の行です。Writerに書き込んで、ストアして、送信完了を待つ、というステップを踏みます。最後の行で、実際に送信されたデータ長(バイト)がbytesWrittenに格納されます。このコード例では文字列を送信していますが、組込みアプリっぽく、バイト列のデータを送信することももちろん可能です。バイト列の場合は、

            byte[] sendBuffer = バイト列データの格納
            dataWriteObject.WriteBytes(sendBuffer);
            storeAsyncTask = dataWriteObject.StoreAsync().AsTask();
            bytesWritten = await storeAsyncTask;

という形式をとります。sendBufferの配列長分を全て送信するので、適切な配列長のByte列を用意してくださいね。WriterにはStringやBytes以外の型のデータを送信するメソッドが用意されているので適宜選択してお使いください。

残りは、データ受信です。

            uint readBufferLength = 1024;
            cancellationToken.ThrowIfCancellationRequested();
            dataReaderObject.InputStreamOptions = InputStreamOptions.Partial;
            Task<UInt32> loadAsynctask = dataReaderObject.LoadAsync(readBufferLength).AsTask();
            UInt32 bytesRead = await loadAsynctask;
            if (bytesRead > 0)
            {
                var buffer = new byte[bytesRead];
                dataReaderObject.ReadBytes(buffer);
            }

受信の場合は、周辺機器が送ってくるデータ長に合わせて(この場合は1024バイト以下のデータを送ってくると想定)、ReaderのLoadAsync()メソッドを使って読込みを行います。それに続くコードで、実際にデータが受信されるまで待ちます。
※ポートを開くときに設定したTimeout期間が過ぎれば制御が戻ります。
受信が完了したら、受信するデータの型に合わせてReadXXXでデータを読み込みます。上のコードは、バイト列の読込みです。文字列が送られてくる場合には、ReadString()メソッドを使って読み込むことが可能です。

説明したフラグメントを組み合わせて、

await ListAvailablePorts();
await OpenPort();

とコール後に、データの送受信ロジックを組めば、周辺機器とのデータ送受信が可能です。どんなフ��ーマットのデータがどんな順序で送受信されるかは、周辺機器とのプロトコル次第です。全二重通信なので、

  • 双方送りっぱなしで、お互い受信しあう
  • どちらかがデータを送信して相手が受信した旨Ackを返す
  • 決められた手順、タイミングに従ってデータの送受信を行う

といった形態が考えられます。非同期プログラミングをうまく使いながら、上に説明した送受信ロジックを組み立てれば、どの形態での実装も可能です。
通信相手の周辺機器も自作の場合、機器間通信のプロトコルは自分で自由に決められるわけですが、下手なプロトコルを定義すると、実装が複雑になったり、システム全体のパフォーマンスが悪くなったりするので、じっくりと考えて定義をしてみてくださいね。

Azure IoT Suiteを試してみよう

$
0
0

2015/9/30にIoT Hubのプレビュー版が公開され、http://azure.microsoft.comのドキュメントに”モノのインターネット”が追加されていますが、同時にAzure IoT Suiteもプレビュー公開されています。
Azure IoT SuiteはAzureの様々なサービスを駆使して、リモートセンシングや予兆診断など一般的なIoTシナリオに沿ったサービスを簡単に構築可能です。現在公開しているhttp://aka.ms/IoTKitHoLや、http://aka.ms/IoTKitHoLV2Onで紹介しているのはAzureの個々のPaaSサービスを組合わせてIoTソリューションを構成していくための基本テクニックですが、IoT Suiteを使えば、個々のPaaSサービスを意識せずに、デバイス接続、蓄積、分析、表示といった一連のIoTサービスを含んだIoTソリューションを手軽に作成可能です。
現在は、リモートセンシングのサンプルを実際に動かしてみることができるので、ぜひお試しを。

http://www.InternetOfYourThings.comを開き、表題の”Internet of Things”のすぐ下の黒帯にある”Azure IoT Suite”をクリックします。開いたページの右上の”Get Started”という青いボタンをクリックしてください。ここから先は、Azure Subscriptionの契約が必要になります。
まだ契約していない人は、http://azure.microsoft.comから1か月間の試用を申し込んでください。

表示されたページで”Create a new solution”という”+”記号が付いたタイルをクリックしてください。2015/11/14現在、”Remote Monitoring”を試すことができます。このソリューションのタイルの”Select”をクリックします。ソリューション名(サービスのURL名)、地域等を指定すると、ソリューションが作成されます。しばらく時間がかかりますので、ちょっと一服して…

ソリューション一式の準備が出来上がると、”Create a new solution”タイルの横に追加されて表示されます。”Launch”ボタンをクリックすると、ソリューション名のURLのサイトが開きます。

こんなダッシュボードが表示されます。位置情報付きのシミュレーターデバイスが4つあり、湿度と温度を送り続けていて、現在情報が表示されています。これ、シミュレータデバイスを増やしたり、実デバイスを追加したりできます。ほかにも一定ルールを満たすと通知する機能も入っています。左側の黒帯のボタンをクリックしていろいろお試しを。

気軽に参照可能なデモもあります!

https://www.microsoft.com/en-us/server-cloud/remotemonitoring/Index.htmlhttps://www.microsoft.com/en-us/server-cloud/Predictivemaintenance/Index.html、も、IoTソリューションを考えるうえで参考になるので、ぜひご一読を

 

Windows 10 IoT Core+WebCam+Azureで簡単定点観測カメラ

$
0
0

Windows 10 IoT Core on Raspberry PI2のWebCam接続が確認できたので、一筆。
PCとUSBで接続可能なWebCamがあれば、定期的に画像を記録する仕掛けは簡単にできますね。しかしそのためにずっとPCを一台動かしているのはなんだか無駄。じゃあRaspberry PI2使おう…しかし、ずっと画像を蓄積続けるためにはストレージが足りないね…ということで、Microsoft AzureのBlob ストレージに貯めよう。そうすればセキュアに遠隔から画像も取り出せるし…

ということで、やり方をざっくり紹介。

まず、Visual Studio 2015で、新規プロジェクトを作成します。テンプレートは、Visual C#→Windows→ユニバーサル→空白のアプリを使います。プロジェクトができたら、MainPage.xamlの<Grid>…</Grid>を

<Grid Background=”{ThemeResource ApplicationPageBackgroundThemeBrush}”>
   
<Canvas Grid.Row=”1″ x:Name=”canvasPicture” Margin=”5″>
       
<CaptureElement x:Name=”previewElement”/>
   
</Canvas>
</Grid>

のように、CanvasとCaptureElementタグを追加します。WebCamの画像はいったんこのCaptureElementに割り付けます。

次に、AzureのBlobにアクセスするために、Azure Storage SDKをインストールします。ソリューションエクスプローラーで参照を右クリックして、NuGetパッケージの管理を選択、Azure Storage SDKと検索窓に入力し、表示されたらインストールしてください。

そして、MainPage.xaml.csを開き、

publicsealedpartialclassMainPage : Page
{
    public MainPage()
     {
         this.InitializeComponent();
      
this.Loaded += MainPage_Loaded;

     }
      MediaCapture mediaCaptureManager;
    StorageFile photoStorageFile;
   
string capturedPhotoFile = “CapturedPhoto.jpg”;
   
   
privateasyncvoid MainPage_Loaded(object sender, RoutedEventArgs e)
 
    {
            mediaCaptureManager = new MediaCapture();
       
try
            {
                await mediaCaptureManager.InitializeAsync();
                previewElement.Source = mediaCaptureManager;
                await mediaCaptureManager.StartPreviewAsync();

                InitializeTimer();
                uploadTimer.Start();
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
        }
        DispatcherTimer uploadTimer;
     
     
privatevoid InitializeTimer()
        {
            if (uploadTimer == null)
            {
                uploadTimer = new DispatcherTimer();
         
int intervalMin = 15;
                uploadTimer.Interval =TimeSpan.FromMinutes(intervalMin);
                uploadTimer.Tick += (o, s) =>
                {
                    UploadPhoto();
                };
            }
        }
        privatestring storageAccountName = “[storage name]”;
     
privatestring storageAccountKey = “[storage access key]”;
    
privateasyncvoid UploadPhoto()
        {
            uploadTimer.Stop();
            photoStorageFile = await Windows.Storage.KnownFolders.PicturesLibrary.CreateFileAsync(capturedPhotoFile, Windows.Storage.CreationCollisionOption.GenerateUniqueName);
       
ImageEncodingProperties imageProperties = ImageEncodingProperties.CreateJpeg();
       
try
            {
                  await mediaCaptureManager.CapturePhotoToStorageFileAsync(imageProperties, photoStorageFile);
           
var cloudStorageAccount = CloudStorageAccount.Parse(“DefaultEndpointsProtocol=https;AccountName=” + storageAccountName + “;AccountKey=” + storageAccountKey);
           
var blobClient = cloudStorageAccount.CreateCloudBlobClient();
           
var container = blobClient.GetContainerReference(“photos”);
           
await container.CreateIfNotExistsAsync();
           
var fileName = “photo” + DateTime.Now.ToString(“yyyyMMdd-hh:mm::ss-fff”) + “.jpg”;
           
var blockBlob = container.GetBlockBlobReference(fileName);
           
await blockBlob.UploadFromFileAsync(photoStorageFile);

            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
            }
            uploadTimer.Start();
        }

と、MainPageクラスの内容を書き換えます。名前空間が一部足りないのでusing宣言を適宜加えてください。storageAccountNameとstorageAccountKeyは、AzureのポータルでStorageを作成して取得してください。

あとは、Package.appxmanifestをコードで開くで開き(もしソリューションエクスプローラーで開けなければ、メモ帳などで開いてください。)、以下のように<Capability>タグに使用する機能を追加宣言します。

  <Capabilities>
    <Capability Name=”internetClient”/>
   <uap:Capability Name=”picturesLibrary” /> 
   <DeviceCapability Name=”microphone” /> 
   <DeviceCapability Name=”webcam” /> 
  </Capabilities>

これでOK.すべて完了。15分ごとにAzureのBlobストレージにアップロードします。センサーで計測しながら画像を蓄積しておけば、センサーがある値を記録した時に何が起こっていたかを記録することができるわけです。ちなみにこのコード、ユニバーサルアプリで作っているので、Windows10 の普通のPCでも動きます。WebCam持っている人ぜひお試しを。
※WebCamの中にはWin10IoTCore Raspberry Pi2に対応していない機種もあるのでご注意。

なおこの投稿の詳細な手順は、今後、http://aka.ms/IoTKitHoL にて公開しますんで、ご期待ください。

Viewing all 167 articles
Browse latest View live


<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>