【メモ】IoT Plug and Playのデバイス実装コード

IoT Plug and PlayのAZ3166向けサンプルコードを調査。

github.com

★ ... Azure IoT SDK for C
☆ ... Azure IoT Device Workbench生成コード

main.ino

setup()
  connectIoTService()
    registerDeviceRetry()
      registerDevice()
        IoTHub_Init()★
        prov_dev_set_symmetric_key_info()★
        prov_dev_security_init()★
        Prov_Device_LL_Create()★
        Prov_Device_LL_Register_Device()★
        Prov_Device_LL_DoWork()★
        IoTHub_Deinit()★
    pnp_device_initialize()☆ ---> pnp_device.h/.c

loop()
  pnp_device_run()☆ ---> pnp_device.h/.c
  is_error_max()☆
  invokeDevKitPeripheral()

pnp_device.h/.c

pnp_device_initialize()
  tickcounter_create()★
  DigitalTwinClientHelper_InitializeDeviceHandle()☆
    IoTHub_Init()★
    IoTHubDeviceClient_LL_CreateFromConnectionString()★
    DigitalTwin_DeviceClient_LL_CreateFromDeviceHandle()★
  DeviceinfoInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
  SensorsInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
  LedsInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
    DigitalTwin_InterfaceClient_SetCommandsCallback()★
  ScreenInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
    DigitalTwin_InterfaceClient_SetCommandsCallback()★
  SettingsInterface_Create()☆
    DigitalTwin_InterfaceClient_Create()★
    DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback()★
  DigitalTwinClientHelper_RegisterInterfacesAndWait()☆
    DigitalTwin_DeviceClient_LL_RegisterInterfacesAsync()★
    DigitalTwin_DeviceClient_LL_DoWork()★
  DigitalTwinClientHelper_Check()☆
    DigitalTwin_DeviceClient_LL_DoWork()★
  DeviceinfoInterface_Property_ReportAll()☆
  tickcounter_get_current_ms()★
pnp_device_run()
  SensorsInterface_Telemetry_SendAll()☆
  DigitalTwinClientHelper_Check()☆
pnp_device_close()

digitaltwin_device_client_ll.h

DigitalTwin_DeviceClient_LL_CreateFromDeviceHandle()
DigitalTwin_DeviceClient_LL_RegisterInterfacesAsync()
DigitalTwin_DeviceClient_LL_DoWork()
DigitalTwin_DeviceClient_LL_Destroy()

digialtwin_interface_client.h

DigitalTwin_InterfaceClient_Create()
DigitalTwin_InterfaceClient_SetPropertiesUpdatedCallback()
DigitalTwin_InterfaceClient_SetCommandsCallback()
DigitalTwin_InterfaceClient_SendTelemetryAsync()
DigitalTwin_InterfaceClient_ReportPropertyAsync()
DigitalTwin_InterfaceClient_UpdateAsyncCommandStatusAsync()
DigitalTwin_InterfaceClient_Destroy()

考察

  • スケッチ -> Azure IoT Device Workbench生成コード -> Azure IoT SDK for C
  • 接続は、Privisoning -> IoTHubDeviceClient -> DigitalTwinDeviceClient
  • 低レベルは従来のIoTHubDeviceClientで、その上にDigitalTwinDeviceClientの模様
  • (Device Capability Modelから)Azure IoT Device Workbenchで生成したコードを使うと、項目毎のコールバック実装になる。(mxchip_iot_devkit_impl.h/.c)

Mbed Studioを使ってみた

前提条件

Windowsの場合は、Gitをインストールしておく必要があります。参照

サポートしているボード

今は、Mbed Enabledのボード全てではなく、一部のボードのみ対応しているようです。参照
何気に、Seeed Wio 3Gも入っていますね!

STMのNucleo/Discoveryシリーズが少ないのは意外でした。

インストール

ここからダウンロードして実行するだけ。
現時点のダウンロードファイルはMbedStudio-0.5.3.exeで、約800MBでした。

Getting Started

使い方をさらっと学ぶために、Getting startedをやってみましょう。

  1. ワークスペースを指定
  2. プログラムを作成(mbed-os-example-blinkyを選択)
  3. ターゲットを選択(FRDM-K64F(K64F)を選択)
  4. プロファイルを選択(Debugを選択)
  5. ビルド
  6. 実行

f:id:matsujirushix:20190824204237p:plain

うーん、GUI快適♪

感じたこと

  • mbed-cliも簡単にインストールできるようになっているようですが、こちらのほうがツールが別々にインストールされず1パックになっているので良さげ。
  • やっぱGUI使いやすい。
  • mbed-osのインポートやバージョン切り替えがメチャ早。(メニューにLibrary cacheという文字があるが何者か分からず。mbed-cliのrepository cachingのことかな?)
  • VSCodeのExtensionを追加することができない。これは悲しい。

結論は、かなりオススメなツールでした。
しばらく使ってみようと思います。

Jetson Nanoにファン追加

重いプログラムを走らせなくても、結構温度が上がるJetson Nano。

f:id:matsujirushix:20190818095757p:plain

チョー不安なので、ファンを追加することに。

どんなファンが取り付けできるの?

40mm角のファンが取り付けできるようですが、、、
ネットで検索すると、色々とハマりどころがあるらしい。

qiita.com

公式は、NF-A4x20を推奨しています。

noctua.at

12V品とか5V品とか、PWMとか。間違えやすいオプション設定があるので、購入時は注意しましょう。

  • NF-A4x20
  • 5V
  • PWM (4pin)

入手性が悪くて価格が高騰していたので、ネットを探し回って、送料込み2500円くらいで購入しました。

f:id:matsujirushix:20190818101134p:plain f:id:matsujirushix:20190818101225p:plain

ファンの取り付けネジ

ヒートシンクの穴に、3mmのネジが通らないorz
インチサイズなのかなこれ?

2.6mmのネジだと長いのが入手し辛いので、ヒートシンクの穴を(ダイソーの3mmピンバイスで)大きくしました。
アルミくずが基板に降りかかるといけないので、逆さに持って慎重に慎重に。

f:id:matsujirushix:20190818102052p:plain

ネジはこれらを用意。

  • ステンレス トラスねじ M3x25 4本
  • ステンレス ナット M3 4個

近所のロイヤルホームセンターで、計108円でした。

ファンの取り付け

ネジで止めて、ケーブル繋ぐだけ。

f:id:matsujirushix:20190818102513p:plain

ファンのON/OFF

ファンを取り付けただけでは回転しません。(--;)

sudo jetson_clocksコマンドで、ファンスピードが最大になります。

jetson_clocksについてはこちらが参考になります。 より詳しくしりたい人は、vi /usr/bin/jetson_clocks

結果

36℃くらいで安定になりました。(そもそも、部屋が暑い。)
ファンが分厚くて気に入らないので、もうちょっと薄いファンにしたい。

Jetson NanoでAzure IoT Edgeを動かす

Jetson Nanoで、Azure IoT Edgeが動くか確認します。

Jetson NanoにOSをセットアップ

こちらの手順に沿って、OSイメージをマイクロSDに書き込んでブートします。

developer.nvidia.com

現時点のOSイメージファイルはjetson-nano-sd-r32.2-2019-07-16.zipでした。

OSバージョンを確認

/etc/os-releaseuname -aで、OSバージョンを確認。

matsujirushi@jetsonnano:~$ cat /etc/os-release
NAME="Ubuntu"
VERSION="18.04.2 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.2 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
matsujirushi@jetsonnano:~$ uname -a
Linux jetsonnano 4.9.140-tegra #1 SMP PREEMPT Tue Jul 16 17:04:49 PDT 2019 aarch64 aarch64 aarch64 GNU/Linux
matsujirushi@jetsonnano:~$

Ubuntu 18.04.2 LTSaarch64でした。

Azure IoT Edgeのサポート状況

Azure IoT Edgeのサポート状況を確認すると、Ubuntu 18.04 ARM64はTier 1だがPublic preview

f:id:matsujirushix:20190812155313p:plain

Azure IoT Edgeをインストール

Azure IoT Edgeのインストール手順に従って、インストールします。

docs.microsoft.com

Jetson NanoのOSイメージにcurlが入っていなかったのでインストール。

sudo apt update
sudo apt install curl

インストール手順を実施。

curl https://packages.microsoft.com/config/ubuntu/18.04/multiarch/prod.list > ./microsoft-prod.list
sudo cp ./microsoft-prod.list /etc/apt/sources.list.d/
curl https://packages.microsoft.com/keys/microsoft.asc | gpg --dearmor > microsoft.gpg
sudo cp ./microsoft.gpg /etc/apt/trusted.gpg.d/
sudo apt-get update
sudo apt-get install moby-engine

エラー発生。

moby-engine (3.0.6) を展開しています...
dpkg: アーカイブ /var/cache/apt/archives/moby-engine_3.0.6_arm64.deb の処理中にエラーが発生しました (--unpack):
 '/usr/bin/docker-proxy' を上書きしようとしています。これはパッケージ docker.io 18.09.2-0ubuntu1~18.04.1 にも 存在します
dpkg-deb: エラー: ペースト subprocess was killed by signal (Broken pipe)
処理中にエラーが発生しました:
 /var/cache/apt/archives/moby-engine_3.0.6_arm64.deb
E: Sub-process /usr/bin/dpkg returned an error code (1)

あぁ、なるほど。Dockerが既に入っているので、moby-engineでエラーなのか。

mobyの部分はスルーして継続。(マイクロソフトmoby-engineを推奨しているので、今回は推奨外の構成になります。)

sudo apt-get update
sudo apt-get install iotedge
sudo vi /etc/iotedge/config.yaml
sudo systemctl restart iotedge

とりあえず、Runtimeは動いてる感じ。

サンプルのモジュールを動かす

Simulated Temperature Sensorをデプロイしてみて、Azure IoT Hubにメッセージが送られてくるか確認。

f:id:matsujirushix:20190812165827p:plain

ちゃんと動いています。

Wio Nodeの測定データをAzure IoT Centralで表示する

Azure IoT Centralって、グラフ表示やメール通知がサクッとできて便利ですよね。
このAzure IoT Centralに、Wio Nodeの測定データを送ることができるか試してみました。

コンセプト

いたってシンプル。
タイマートリガーで10分間隔にAzure Functionsを起動して、Wio Nodeから温度・湿度を取得してAzure IoT Centralへメッセージ送信するというもの。

f:id:matsujirushix:20190721214747p:plain

Wio Node

Wio NodeにGrove-BME280を接続、専用アプリでセットアップします。
すると、SeeedのWio LinkサーバーへREST APIで温度・湿度を取得することができます。

www.seeedstudio.com

www.seeedstudio.com

f:id:matsujirushix:20190721215645p:plain

Azure IoT Central

アプリケーションを用意して、デバイステンプレートを追加、温度・湿度に対応する測定を追加します。

項目 フィールド名
温度 temperature
湿度 humidity

f:id:matsujirushix:20190721220019p:plain

Azure Functions

これを放り込みます。

using Microsoft.Azure.Devices.Client;
using Microsoft.Azure.WebJobs;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using System;
using System.Configuration;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace mjcradlefunc
{
    public static class Function1
    {
        [FunctionName("WioNodeToIoTCentral")]
        public static async Task Run([TimerTrigger("0 */10 * * * *")]TimerInfo myTimer, ILogger log)
        {
            var temperatureObject = await GetJObjectFromWioNode(GetEnvValue("WioNodeTempURI"), GetEnvValue("WioNodeToken"), log);
            double temperature = (double)temperatureObject["temperature"];
            log.LogInformation($"temperature is {temperature}");

            var humidityObject = await GetJObjectFromWioNode(GetEnvValue("WioNodeHumiURI"), GetEnvValue("WioNodeToken"), log);
            double humidity = (double)humidityObject["humidity"];
            log.LogInformation($"humidity is {humidity}");

            var msgObject = new JObject();
            msgObject["temperature"] = temperature;
            msgObject["humidity"] = humidity;

            var deviceClient = DeviceClient.CreateFromConnectionString(GetEnvValue("DeviceOfIoTHub"), TransportType.Amqp);
            var eventMessage = new Message(Encoding.UTF8.GetBytes(msgObject.ToString()));
            await deviceClient.SendEventAsync(eventMessage);
        }

        private static async Task<JObject> GetJObjectFromWioNode(string uri, string token, ILogger log)
        {
            var httpClient = new HttpClient();

            var jsonString = await httpClient.GetStringAsync($"{uri}?access_token={token}");
            log.LogInformation($"Got json string is {jsonString}");

            return JObject.Parse(jsonString);
        }

        private static string GetEnvValue(string name)
        {
            return Environment.GetEnvironmentVariable(name, EnvironmentVariableTarget.Process);
        }
    }
}

そして、WioNodeTokenWioNodeTempURIWioNodeHumiURIDeviceOfIoTHubにWio NodeやAzure IoT Central(の中のAzure IoT Hub)の情報を、デバッグ時はlocal.settings.json、実行時はapplication settingsに設定します。

local.settings.jsonの設定例
f:id:matsujirushix:20190721221032p:plain

application settingsの設定例
f:id:matsujirushix:20190721221205p:plain

DeviceOfIoTHubに設定する、Azure IoT Centralの中のAzure IoT Hubのデバイス接続文字列は、dps_cstrコマンドで調べてください。
参考:デバイスからAzure IoT Centralに接続する方法 - matsujirushi’s blog

結果

でた。

f:id:matsujirushix:20190721221644p:plain

費用

1日あたり、0.31円でした。

f:id:matsujirushix:20190721221924p:plain

Maixduino ブロック図

タイトルのとおり。

回路図を見るついでに、ブロック図を書きました。

ブロック図

f:id:matsujirushix:20190714131931p:plain

考察

  • CH552Tは8051互換8bitマイコン。FTDIを模擬しているっぽい。
  • M1とESP32の間はUART。で、CHT552Tも結線されている。
  • M1が凄そう。
  • Arduino Compatible Pin HeadersはM1とESP32に繋がっている。使い方ややこしそう。どこかに資料あるのかな?
  • SPIがどういう感じなのか調べ切れていない。
  • Speakerのコネクタが1.25mmピッチだった...orz
    molex 51021が使えるのかな。

参考

Maixduino セットアップ手順メモ(MaixPy)

twitter見てて、なんとなーく面白そうだったので事前調査せずに買ってみました。
Maixduino。

f:id:matsujirushix:20190712222542p:plain

販売ページ:Sipeed Maixduino Kit for RISC-V AI + IoT

RISC-Vにニューラルネットワークプロセッサ、Wi-FiBluetooth、カメラにLCD
まぁ、とにかくテンコ盛り製品w

開発環境は?

Arduino IDE or MaixPy(MicroPython)が用意されているようです。

ざっとググった感じだと、MaixPyのほうが手軽な感じ。

MaixPy

専用ファームウェアをMaixduinoに入れれば、シリアルコンソールやMaixPy IDEからPythonを実行できるというものです。

ドキュメントはココ。 maixpy.sipeed.com

現時点では、セットアップの方法がいまひとつ分からず、いくつかのサイトを徘徊して分かってきたので、メモすることにしました。

MaixPyのセットアップ

大まかには、次の作業になります。

  1. 必要なファイルをダウンロード
  2. Maixduinoを組み立て
  3. MaixduinoをPCに接続
  4. ファームウェアを転送
  5. ファームウェア動作を確認
  6. MaixPy IDEをインストール

1. 必要なファイルをダウンロード

これらのファイルが必要です。

  1. kflash_gui_vX.X.X_windows.7z ... ファームウェアを転送するのに使用
  2. maixpy_vX.X.X_full.bin ... MaixPyのファームウェア(詳しくはココ
  3. maixpy-ide-windows-X.X.X.exe ... MaixPy IDE

1.はkflash_gui githubReleasesページからダウンロードできます。
他は、MaixPy githubReleasesページからダウンロードできます。
過去バージョンも載っているので、上の方にあるものをダウンロードしましょう。

2. Maixduinoを組み立て

Maixduinoの箱を開梱すると、本体とLCDが接続されていません。

f:id:matsujirushix:20190713145812p:plain

慎重にLCDのフィルムケーブルをコネクタに取り付けます。

向きは、、、よく見ると、ケーブルと基板の双方に1番ピンのマーキングがあるので、それを参考にして接続します。

f:id:matsujirushix:20190713150357p:plain f:id:matsujirushix:20190713150305p:plain

接続するとこんな感じ。

f:id:matsujirushix:20190713150647p:plain

LCDがブラブラして、フィルムケーブルやコネクタが破損すると怖いので、わたしはLCDを両面テープで本体基板に貼り付けました。

3. MaixduinoをPCに接続

Type-C USBケーブルでPCに接続します。
(ケーブルは同封されていないので、、、メッチャ探した。)

シリアルポートが2個増えればOKです。

f:id:matsujirushix:20190712230811p:plain

1つはRISC-Vモジュール、もう1つはESP32に繋がっています。
どっちがどっちか区別できませんが、、、わたしの場合は、小さい番号の方が、RISC-Vモジュールでした。

4. ファームウェアを転送

kflash_gui_vX.X.X_windows.7zを解凍して、中に入っているkflash_gui.exeを実行して、ファームウェアをMaixduinoへ転送します。

指定はこんな感じ。
Downloadをクリックすると、転送を開始します。

f:id:matsujirushix:20190713151852p:plain

5. ファームウェア動作を確認

TeraTermなどで、RISC-Vモジュールのシリアルポートに115200,8,N,1で接続して、Ctrl+Dを押したときに、下記バナーが表示されれば正常です。

f:id:matsujirushix:20190713152251p:plain

6. MaixPy IDEをインストール

maixpy-ide-windows-X.X.X.exeを実行して、MaixPy IDEをPCにインストールします。

MaixPy IDEを起動して、左下のチェーンみたいなアイコンをクリックすると、Maixduinoと接続します。
さらに、左下の再生アイコンをクリックして、フレームバッファにカメラの映像が表示されれば正常です。

f:id:matsujirushix:20190713152604p:plain