はつねの日記

Kinect, Windows 10 UWP, Windows Azure, IoT, 電子工作

Nreal Airを買ったのでアプリを作る準備しよう

Nreal Airは、適合するAndroid端末に繋いで使用するARグラスです。
Amazon.co.jp: Nreal Air /ARグラス/スマートグラス/どこにでも持ち歩ける最大201インチ大画面/TUV認証取得(目に優しい)/ステレオサウンドのデュアルスピーカー/ノイズキャンセリングマイク/3DoF対応/EIS電子式アンチシェイク/専用アプリNebula対応/Type-C (DP ALT MODE)接続 : 家電&カメラ

最近、iPhoneやPCにも接続できるアダプターも販売が開始されました。
Amazon.co.jp: Nreal Adapter/NR-7100AGL / ARグラス/スマートグラス Nreal Air 専用/有線でデータ転送・変換 動画サービスやゲームの視聴をサポート/HDMI接続/iOS対応-Lightning端子はApple社純正Adapter別売 必要 : 家電&カメラ

iPhoneやPCでできるのはミラーリング表示と呼ばれるもので、画面表示そのままがNreal Airに表示されます。
このとき黒は透過されるので背景黒のアプリだと必要な情報が空中に浮かんでいるように見えます。
もちろんAndroid端末でもミラーリング表示は可能です。
この表示方式であれば、Nreal Air用にアプリを作成しなくて、既存のスマホアプリで色味を調整するだけでAR表示なアプリ動作が可能になります。

しかし!!
Nreal Airの実力を100%活用したアプリにするには、Nreal AirSDK(NRSDK)を組み込んだ専用アプリとして仕立て上げたほうがいいでしょう。

準備

Unityの準備

NRSDKはUnityやunrealから使用するので、まずは、Unityの環境を整えます。

Unity Hub

UnityのダウンロードサイトからUnity Hubをダウンロードします。
unity3d.com
ダウンロードしたUnityHub.exeを起動して、Unity Hubをインストールします。

Unityのインストール

Unity Hubを起動すると、まだUnity自体はインストールしていないので、Unityがないと表示されます。

そこでインストールボタンをクリックしてUnityのバージョンとして、2022/11/19現在の最新LTSである「Unity 2021.3.14f1」をインストールします。

必要なモジュールとしては「Android Build Support」となります。

もし、Visual Studioをインストールしていないのであれば、同時にインストールしましょう。すでにインストール済の場合は「Microsoft Visual Studio Community 2019」のチェックは不要です。

NRSDKの準備

入手

2022/11/19現在のNRSDKの最新は、Unity SDK 1.9.5「NRSDKForUnity_Release_1.9.5.unitypackage」となります。
developer.nreal.ai

はじめてのNreal Airアプリ開発

共通の準備

Nreal Airアプリ開発開始時に必要な手順をまず実施します。

新規作成

Unity Hubを起動して[プロジェクト]→[新規作成]をクリックします。

テンプレートの指定

テンプレートとして「3D」を選択して、プロジェクト名「NrealAirHelloWorld」として[作成]をクリックします。

プラットフォームの変更

Unityを起動してUnityの新規プロジェクトが作成されたら、[File]-[Build Settings]メニューから設定画面を開きます。

プラットフォームを「Android」に変更して[Switch Platform]をクリックします。

NRSDKのインポート

[Assets]-[Import Package]-[Custom Package]メニューからダウンロードした「NRSDKForUnity_Release_1.9.5.unitypackage」をインポートします。

インポートするものを選択するダイアログが表示されるので、[All]をクリックしてすべてを選択してから[Import]でプロジェクトにNRSDKを追加します。

インポートに成功していれば、[Project]領域の[Assets]に「NRSDK」が追加されます。

NRSDK実行環境を整える (TipsをFix)

[NRSDK]-[Project Tips]メニューをクリックして、NRSDKを使ったAndroidアプリ作成用の設定を実施します。

表示されたTipsはすべてFixします。

NRSDK実行環境を整える (手動設定)

ただし、今回のバージョン構成だとどうしても1つだけTipsがFixできません。
それが「OpneGLES3」を有効にするTipsです。
このTipsは、[Build Settings]の中の[Player Settings]の[Android]-[Other Settings]の項目への設定なので、[Auto Graphics API」チェックを外して、「ES3.1」「ES3.1+AEP」「ES3.2」のチェックを付けると、「OpneGLES3」のTipsもリストから消えます。

これをやっておかないと実機でオブジェクトが表示されないので確実にやっておきましょう。

プレハブ追加

[Project]からAssets > NRSDK > Prefabsを開きます。

「NRCameraRig」と「NRInput」を「Hierarchy」にドラッグ&ドロップします。

「MainCamera」は不要なので削除します。

Cubeを表示する

共通設定が完了したら、ARグラスアプリのHello Worldともいえる空中に浮かんだCubeを表示するアプリを作ります。

Cubeを追加

「Hierarchy」を右クリックして、[3D Object]-[Cube]メニューをクリックしてCubeを追加します。

Cubeの位置と大きさを調整

初期位置ではカメラと重なってしまうので、「Hierarchy」で「Cube」を選択して、その「Inspector」でPositionを(0, 0, 3)=3m先の位置、Rotationを(30, 30, 0)、Scaleを(0.5, 0.5, 0.5)にして配置します。

これでNreal Airを付けた時に目の前の空中に立方体が浮かぶことになります。

実機デバッグ

実機準備

Android実機側では、まずは「開発者モード(Developer mode)」に変更して、さらに「USBデバッグ」ができるようにしておきます。

実機接続

Android実機側の準備ができたらUSBにて接続します。
準備がうまくできていると、ここで「USBデバッグを開始する」のようなダイアログが表示されるので、かならず「OK」をクリックします。

Unity側設定

[Run Device]には接続した実機を選択します。
[Development Build]と[Script Debugging]にもチェックをいれておきます。

実機実行

[Build And Run]をクリックして、ビルドと実機転送、そして実行を行います。
ただし、転送まで成功してもそのままデバッグ実行にはならず、Android端末には「Nebulaを利用するには、Nrealグラスと接続してください」と表示されます。

Nreal Airを付けての実行

そこで、PCと接続されているUSBケーブルを外してNreal Airに繋ぎ変えて実行するとUnityの[Game]で表示されていた表示とそっくりな表示が空中に浮かびあがります。

次回はポインタ操作など操作にチャレンジする予定です。
hatsune.hatenablog.jp

Microsoftの製品ドキュメントはdocsからlearnへ

Microsoftの製品ドキュメントは、docs.microsoft.com~というサイトで参照できましたが、learn.microsoft.comと先頭がlearnに変わっています。

learnといえば今までは学習コンテンツが充実していて、認定試験対策などでよく使っていて、以前は、docsのなかにlearnがあったと思うのですが、これからはlearnの中にdocs(というカテゴリ自体なくなっていますが)という形になりますね。

ほんの些細なことかもしれませんが、学習体験というものを重視するという心意気の現れなのかもしれませんね。
learn.microsoft.com

いよいよMicrosoft Ignite 2022が来週に迫ってきました。

北米現地時間で10/12~13、日本時間で10/13~10/14にMicrosoft Ignite 2022が開催されます。
ignite.microsoft.com
シアトル現地とオンラインのハイブリット開催となっています。
現地開催は、本当に久しぶりですね。
まずは、日本時間の10/13 01:00からの基調講演が楽しみです!
日本時間での再放送もあるようなので、オンラインでもぜひ皆さん情報収集を!

M5StickC Plusで.NET nanoFrameworkからGROVE端子を使ってみた

前回

hatsune.hatenablog.jp
前回はNTPを使った時刻合わせと表示の方法について紹介しました。
今回は、HY2.0-4P(GROVE端子)を.NET nanoFrameworkから使う方法について紹介します。

事前準備

センサーについて

この記事で使用するセンサーは、M5StackユニットのENV-IIIを使います。
GROVE規格なのでM5StickC PlusのHY2.0-4P端子に接続できます。
ENV-IIIは、気圧センサーとしてQMP6988、気温と湿度のセンサーとしてSHT30を内蔵したユニットとなります。
ENV-IIIとM5StickC Plusを接続し、更にM5StickC PlusをUSBでPCに接続して、準備完了です。

Install the nanoFramework firmware

M5StickC PlusにはnanoFrameworkは標準インストールされていないので、nanoFrameworkをインストールします。

接続ポート番号の確認

USBでM5StickC PlusをPCに接続したら、USB Serial Portのポート番号を確認します。今回の環境では「COM6」が該当しました。

Flasherアプリケーションのインストール

OSの[スタート]メニューから「Developer PowerShell for VS2022」を起動します。

dotnet tool install --global nanoff

nanoFrameworkfファームウェアをインストール

M5StickC Plusをターゲットにして「COM6」経由でnanoFrameworkをアップロードします。

nanoff --target M5StickCPlus --update --serialport COM6

Visual Studioの準備

Visual Studioを機能拡張する

Visual Studioには.NET nanoFramework Extensionをインストールして機能拡張しておきます。
この機能拡張によりnanoFrameworkアプリのテンプレートが追加されます。
このテンプレートで作成したプロジェクトには、NuGetから自動的に「nanoFramework.CoreLibrary」ライブラリが追加されています。

「nanoFramework.M5StickCPlus」ライブラリを追加する

M5StickC Plusの画面などハードウェアにアクセスするために、M5StickC Plus用のライブラリを追加します。

ここまでが、M5StickC Plusを使うアプリ開発を行う上での共通の事前準備となります。

M5StickC Plusで気温と湿度の表示(SHT30)

ライブラリの追加

.NET nanoFrameworkにはSHT30用のライブラリである「nanoFramework.Iot.Device.Sht3x」がNuGetで提供されています。
.NET nanoFramrworkアプリケーションテンプレートで新規プロジェクトを作成したら、NuGetでSht3xライブラリを追加します。

SHT30から気温と湿度を取得して画面に表示するC#コード

ENV-IIIのI2Cアドレスを調べる

I2Cシリアル通信では、端子につながっている機器から特定のセンサーを指定するために「アドレス」を指定します。
ENV-IIIの中のSHT30と接続するためにアドレスに指定する値は、ENV-IIIの仕様書をみると書かれています。
ENV III Unit with Temperature Humidity Air Pressure Sensor (SHT30+QMP6988) | m5stack-store

I2C interface (SHT30:0x44 , QMP6988:0x70)

このアドレスを指定してI2C通信を行うことでSHT30より気圧値を取得できます。
Grove端子との通信では次のようなコードでI2C通信経路を確立できます。
gist.github.com

センサー値を取得する

センサー値を取得するためには次のようなコードになります。

WriteLine($"Temperature:{Sht.Temperature.DegreesCelsius:F} C");
WriteLine($"Humidity:{Sht.Humidity.Percent:F} %");

単位ごとのメソッドが用意されているので、℃で気温を得たいときは「Temperature.DegreesCelsius」メソッド、湿度を%で多いときは「Humidity.Percent」メソッドを使います。

M5StickC Plusで気圧表示(QMP6988)

SHT30から温と湿度を無事取得できたので、次は、QMP6988から気圧を取得します。

ENV-IIIのライブラリを調べる

SHT30については「nanoFramework.Iot.Device.Sht3x」ライブラリが使えますが、QMP6988を使うためのライブラリは2022年8月現時点ではNuGetに公開されていません。
そこで自作でQMP6988用のクラスを作成しました。
IoT.Devices.Qmp6988.cs · GitHub
詳しくは、以前の記事を参照してください。
hatsune.hatenablog.jp

ENV-IIIのI2Cアドレスを調べる

ENV-IIIのQMP6988のアドレスは仕様書から「0x70」なのでそれを指定して通信を確立します。

Qmp = new(M5StickCPlus.GetGrove(0x70))

センサー値を取得する

全体的なコードは次のようになります。
gist.github.com
センサー値の取得部分は次のところです

Console.WriteLine($"DateTime:{DateTime.UtcNow:yyyyMMdd HHmmss}");
Console.WriteLine($"Pressure:{Qmp.CalcPressureHectopascals():F} hPa");
Console.WriteLine($"Temperature:{Sht.Temperature.DegreesCelsius:F} C");
Console.WriteLine($"Humidity:{Sht.Humidity.Percent:F} %");

M5StickC Plusでの動作

ENV-IIIから気圧、気温、湿度を取得するコードが完成したので、Visual Studioで[デバッグ]-[デバッグの開始]メニューでM5StickC Plusへの転送と実行を行います。
時間とセンサー値が1秒ごとに更新表示されます。

.NET nanoFramework ExtensionとVisual Studio 2022をすぐに更新して最新にしよう!

北米8/16(日本時間で8/17)に「Visual Studio 2022 version 17.3.1」がリリースされました。
同時に.NET nanoFramework Extensionも「.NET nanoFramework VS Extension v2022.2.0.33」に更新されました。
ここ数日、実は.NET nanoFrameworkのプロジェクトをVisual Studioで読み込むと、予期しないエラーが発生するようになりました。
gist.github.com
一応はビルドやデプロイもできるのですが、インテリセンスなどが効かないなど不具合は発生していました。

Visual Studio側を17.3に上げたのが原因だとは思っていたのですが、アンインストールして意図的に1つ前のバージョンをいれてとか少々面倒に感じでインテリセンスなしでコードをかいていました。
でも、インテリセンス……ないとすんごく不便ですね。

そんな悩みを抱えていたのですが「Visual Studio 2022 version 17.3.1」が本日
リリースされました。
docs.microsoft.com
こちらを提供して更に「.NET nanoFramework VS Extension v2022.2.0.33」に更新すれば、プロジェクトファイル読み込み時の予期せぬエラーも解消されて、インテリセンスが戻ってきました。

よかった~。

.NET nanoFrameworkでM5StickC Plusの時刻合わせをしてみる

前回

hatsune.hatenablog.jp

前回は7セグメントでの数字表示の最適化について説明しました。
今回は、その最適化を活用して「時刻合わせ」および「時刻表示」について説明します。

事前準備

Install the nanoFramework firmware

M5StickC PlusにはnanoFrameworkは標準インストールされていないので、nanoFrameworkをインストールします。

接続ポート番号の確認

USBでM5StickC PlusをPCに接続したら、USB Serial Portのポート番号を確認します。今回の環境では「COM6」が該当しました。

Flasherアプリケーションのインストール

OSの[スタート]メニューから「Developer PowerShell for VS2022」を起動します。

dotnet tool install --global nanoff

nanoFrameworkfファームウェアをインストール

M5StickC Plusをターゲットにして「COM6」経由でnanoFrameworkをアップロードします。

nanoff --target M5StickCPlus --update --serialport COM6

Visual Studioの準備

Visual Studioを機能拡張する

Visual Studioには.NET nanoFramework Extensionをインストールして機能拡張しておきます。
この機能拡張によりnanoFrameworkアプリのテンプレートが追加されます。
このテンプレートで作成したプロジェクトには、NuGetから自動的に「nanoFramework.CoreLibrary」ライブラリが追加されています。

「nanoFramework.M5StickCPlus」ライブラリを追加する

M5StickC Plusの画面などハードウェアにアクセスするために、M5StickC Plus用のライブラリを追加します。

ここまでが、M5StickC Plusを使うアプリ開発を行う上での共通の事前準備となります。

横表示

.NET nanoFrameworkでは画面の回転(ローテート)は、まだサポートされていないのでコードで対応します。

コードの変更部分は「Screen.Write」メソッドで描画するushort配列への格納時のこの図にあるような縦横変換を実施します。

バッファへの格納の縦横変換対応

Buffer[x + y * Width] = color;

となっているところを次のようにします。

Buffer[(Height - y) + x * Height] = color;

スクリーンへの描画の縦横変換対応

Screen.Write((ushort)x, (ushort)y, Width, Height, Buffer);

となっているところを次のようにします。

Screen.Write((ushort)(135 - Height - y), (ushort)x, Height, Width, Buffer);

実行結果

www.youtube.com

4桁表示

今回のサンプルは「分秒」の4桁を表示します。
そこで「描画の最適化」「横表示」に加えて「4桁表示の最適化」についても検討します。

4桁表示の最適化

1桁の7セグメント表示を位置をずらしながら4回描画すれば4桁表示は可能です。
しかしその方法では1桁ずつ描画しているのがやはり分かってしまいます。
そこで1桁の時と同様に「1桁」「余白」「1桁」「余白」「1桁」「余白」「1桁」のような感じでushort配列の中に描画してからScreenWriteで4桁分の矩形に描画します。

数値を4桁化して描画する

gist.github.com
今回、余白は5dotとしているので、余白込みの幅は次のように定数設定しています。

const int DigitsWidth = Width + 5;

ここをかえれば余白の変更が可能です。

ushort配列にずらしながら格納する

ループの中でOffsetを「DigitsWidth * Height」ずつ増分していますがこの「Offset」はushort配列に描画するときの位置決めに使用しています。
gist.github.com
これで、1桁描画するごとに「DigitsWidth * Height」の領域をスキップした位置に描画開始位置がずれてくれます。

対策済の動作

www.youtube.com

時刻合わせ

.NET nanoFrameworkを使った時刻合わせは非常に簡単です。
Wi-Fi経由でインターネットに接続すれば数秒と待たずに自動的にNTP(Network Time Protocol)を使って時刻合わせを実施してくれます。

Wi-Fiに接続する

ライブラリ追加

Wi-Fiへの接続方法ですが、まずは、NuGetからWi-Fi用のライブラリを追加します。

コード記述

ライブラリ追加が終われば、以前、M5Stack Core 2でAzure IoT Centralに接続したときのWi-Fi接続部分がそのまま使えます。
hatsune.hatenablog.jp
該当部分のコードをみてみましょう。
gist.github.com

明示的に時刻合わせを実行する

改めて時刻合わせを行いたいときは

nanoFramework.Networking.Sntp.UpdateNow();

を実行します。
今回のサンプルではM5ボタンをクリックすると時刻合わせを実行するようになっています。
www.youtube.com
起動した直後でまだ自動時刻合わせが完了していないタイミングで「急いで」M5ボタンをクリックしています。
Wi-Fi接続が完了したら猶予は数秒しかありませんでした。もたもたしているとすぐに自動的に時刻があってしまいます。

次回

今回の記事は如何でしたでしょうか。
.NET nanoFrameworkでの時刻合わせは非常に簡単で「Wi-Fiにつなぐコードだけ」で実現できます。
今回の記事でも記事の大半は7セグメント表示など表示に関する部分が大半でした。
このあたりライブラリ化したりNuGetから取得できる描画ライブラリが拡充すると更に手軽につくることができるようになります。

さて次回ですが、GROVE端子関係について確認していきます。
hatsune.hatenablog.jp