つながるULSA – Arduino IoT Cloud(後編)

2023/12/05更新:電源管理ICが変更されたM5Stack Core2 V1.1に対応したArduinoスケッチに更新しました。これまでの無印Core2、V1.1両方でお使いいただけます。

2023/12/03更新:電源管理ICが変更されたM5Stack Core2 "V1.1"が発売されました。本記事で紹介するコードはV1.1に対応しておりません。コードをアップロードすると再起動を繰り返す状態となり、ジャンパーワイヤーを使用した復旧作業が必要となりますので、V1.1には本コードをアップロードしないでください。

前編では、誰でも簡単にIoTシステムを構築できるArduino IoT Cloudの概要を紹介しました。

後編では、超音波風速計ULSAをIoT化する具体的なスケッチやArduino IoT Cloudの設定について紹介していきます。

作業手順が多く見えますが、基本的にコーディングはなく、簡単なキーボード入力とぽちぽちクリックしていくだけの作業になりますので、ぜひトライしてみてください。

Arduino IoT Cloudのセッティング

Arduino IoT CloudやArduino Web Editorを使用するには、まずArduinoアカウントが必要になるので、未取得の方はまずアカウント登録から始めてください。今回は月額無料のFreeプランで試せる内容になっています。

Arduino IoT Cloud

Thingsの登録

Arduino IoT Cloudは"Things"の登録から始まります。"CREATE THINGS"から登録を開始します。

Thingsはその名の通りInternet of ThingsのThingsで、インターネットにつながる「もの」、例えばアクチュエーターやセンサーとなります。この記事におけるThingsはもちろんULSA超音波風速計です。

Freeプランでは2台のThingsを登録することができるので、最低限のマルチデバイス環境の構築に対応しています。本記事ではせっかくなので、ULSAを2台接続して、異なる2箇所の風速をリモート計測できるようにしてみたいと思います。

それではやっていきます!

ULSA M5B(とM5Stack Core2)を2台用意しました。今回はわかりやすくするために、筐体がブラックの通常(販売)バージョンと、白色MJFプリント(PA12W)を使用したホワイト筐体バージョン(非売品)を用意しました。

ブラック筐体には"ULSA_BLACK"、ホワイト筐体には"ULSA_WHITE"とThingの名前をつけることにします。

なお本記事では、"ULSA_BLACK"を登録する手順のみを紹介していきますが、Thingsの追加登録の手順はほとんど違いがなく、ほぼ同じ手順の繰り返しでThingsを登録できますので、ULSA_WHITEの手順は省略します。

もちろん、ULSAが1台だけでも本記事で紹介している手順そのままで構築できますので安心してください。

次に"Associated Device"のアイコンをクリックしてデバイスを登録していきます。

今回は新規登録なので、"SET UP NEW DEVICE"をクリック。

登録するデバイスの種類を選択していきます。Arduino IoT Cloudでは純正Arduinoボードと、ESP32のようなサードパーティ製デバイス双方に対応しています。今回はM5Stack Core2(ESP32)ですので、右側のグレーの"Third party device"をクリック。

※ちなみに下方のMANUAL: Any Deviceはひと月前にはありませんでした。DIYボードも登録できるようになっているのかもしれません。どんどんアップデートされているようですね。

さきほどはThingsに"ULSA_BLACK"と名付けましたが、Device名も"ULSA_BLACK"とし次に進みます。

M5Stack Core2なので"ESP32"を選択し、プルダウンから"M5Stack-Core2"を選び次に進みます。

Deviceの登録が完了し、Arduino IoT Cloudへの識別・接続情報となる"Device ID"と"Secret Key"が付与されました。

あとから情報を参照できるように"download the PDF"からPDFをダウンロードしておいてください。

なおこの段階では、これらの情報は特定のハードェアに紐付けられていません。後述のスケッチをアップロードした段階ではじめて紐付けられることに注意してください。

例えば、ULSA_BLACK用にこれらの接続情報を用意した後に、この接続情報を間違ってULSA_WHITEにアップロードしてしまった場合、ULSA_WHITEはULSA_BLACKとして認識されてしまいます。

ちなみに、純正Arduinoボード(MKR Wi-Fiなど)は、専用のセキュリティチップが基板上に実装されているためこのような取り違いは発生せず、このステップは自動設定されるようになっています(下記YouTube参照)。

専用セキュリティチップを持たないサードパーティ製ボードでは、文字ベースで接続情報を管理する仕様になっているので若干導入手順や機材管理が煩雑になる面があります。

純正Arduinoボードはセキュリティチップを内蔵しているので自動でコンフィグレーションが走る

ネットワーク(Wi-Fi)接続情報の追加

これで、ULSA_BLACKがAssocciated Deviceに追加されました。つづいて、ULSA_BLACKがインターネットに接続できるようにネットワーク情報を追加していきます。"Network"のアイコンをクリックし、Wi-FiのSSIDとパスワードを記入します。一番下の"Secret Key"には先ほどのデバイス登録時に付与されたキーを入力します。

ESP32では5GHzのアクセスポイントには接続できませんので、必ず2.4GHzのSSIDを指定してください。また、2.4GHz / 5GHz共用SSIDでも動作しない可能性があるので注意してください。

これでデバイスとネットワーク情報が揃いました。

クラウド変数の登録

次にArduino IoT Cloudの本丸となるクラウド変数(Cloud Variables)を用意していきます。クラウド変数とは何かについては前編でもご紹介しました。

今回は超音波風速計ULSAの計測情報を受け取りたいので、以下の5つのクラウド変数を追加していきます。

データ [単位]変数名データ型
風速 [m/s]cloudWindSpeedfloat
機首方向対気速度 [m/s]cloudNoseSpeedfloat
風向 [°]cloudWindDirectionint
補正後風向 [°]cloudCorrWindDirectionint
音仮温度 [℃]cloudVirtualTemperaturefloat

Cloud Variablesの"ADD"ボタンから、風速のクラウド変数を追加してみます。まずは変数名を入力し、次にラジオボタンから「浮動小数点(Floating Point Number)」のデータ型を選択します。

次に変数の権限として、「読み取りのみ:Read Only」を選択します。今回は計測値を一方的に受け取るだけなので書き込みができる変数を選ぶ必要はありません。

最後に変数の更新ポリシーを選びます。今回は「定期更新(Periodically):1秒」に設定しました。

低頻度で変化する変数の場合には、値が変化したときだけに更新する"On Change"を選ぶことで省電力にすることができます。

なお、Periodicallyの最短更新周期は現在0.5秒(2Hz)です。

つづいて、風向は整数値になるので、"Integer Number"として登録しました。他は風速値と同じ設定です。

このようにして、5種類の変数を登録してみました。これで1つ目のThingである、ULSA_BLACKの登録は完了しました。
(Freeプランでは、変数の数は5つまでに制限されています)

次に、ULSA_WHITEの設定をしていきますが、デバイスIDとデバイスキーが異なるだけで、他の設定や変数名は全く同じになりますので、ここでは省略します。

Arduinoスケッチの作成

次に、Thingsに書き込むスケッチを準備していきます。
ULSA_BLACKをArduino IoT Cloudに接続するには、対応するArduinoスケッチをプログラミングしていく必要があります。

これまでの作業を終えたところで、Thingsの"Sketch"タブに通知マークのようなものがついていることがわかります。

これは、これまでの登録作業に対応する自動生成スケッチの内容が更新された回数を示しています。「接続情報やクラウド変数の情報はハードウェア側にはまだ登録されていないので新たにスケッチをアップロードしてそれらの情報を書き込む必要があるよ(未対応の項目数)」というわけです。

自動生成されたスケッチを見てみる

Sketch”をクリックすると簡易エディターが開き、スケッチの内容が表示されます。より詳しく中身を見るために"</>Open full Editer"からArduino Web Editorでスケッチを開いてみます。

スケッチの構成は、以下のようになっていました。

ULSA_BLACK_jun30a.ino  (スケッチ本体)
 |- ReadMe.adoc        (自動生成のReadMe)
 |- thingProperties.h  (Thingプロパティヘッダー)
 |- Secret             (接続情報を記したシークレットタブ)

以下は、自動生成されたスケッチです。

setup()とloop()関数に対して、数個の要素が足されただけのシンプルなスケッチですが、これがArduino IoT Cloudに対応させるための最低限のコードになります。

/* 
  Sketch generated by the Arduino IoT Cloud Thing "Untitled"
  https://create.arduino.cc/cloud/things/[Things_Device_ID]

  Arduino IoT Cloud Variables description

  The following variables are automatically generated and updated when changes are made to the Thing

  float cloudNoseSpeed;
  float cloudVirtualTemperature;
  float cloudWindSpeed;
  int cloudCorrWindDirection;
  int cloudWindDirection;

  Variables which are marked as READ/WRITE in the Cloud Thing will also have functions
  which are called when their values are changed from the Dashboard.
  These functions are generated with the Thing and added at the end of this sketch.
*/

#include "thingProperties.h"

void setup() {
  // Initialize serial and wait for port to open:
  Serial.begin(9600);
  // This delay gives the chance to wait for a Serial Monitor without blocking if none is found
  delay(1500); 

  // Defined in thingProperties.h
  initProperties();

  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);
  
  /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();
}

void loop() {
  ArduinoCloud.update();
  // Your code here 
  
  
}

起動時に一回だけ実行されるsetup()関数にはプロパティとArduinoCloudの初期化、

  // Defined in thingProperties.h
  initProperties();
  
  // Connect to Arduino IoT Cloud
  ArduinoCloud.begin(ArduinoIoTPreferredConnection);

そして、デバッグメッセージのレベル設定と出力といった、最低限の呼び出しが行われているのみです。

 /*
     The following function allows you to obtain more information
     related to the state of network and IoT Cloud connection and errors
     the higher number the more granular information you’ll get.
     The default is 0 (only errors).
     Maximum is 4
 */
  setDebugMessageLevel(2);
  ArduinoCloud.printDebugInfo();

ループで実行されるloop()関数には、クラウド変数に格納された値をArduinoのサーバーにプッシュしているだけです。ループ処理されている関数内でクラウド変数に値を格納したあとに、以下を定期的に実行すれば良いということになります。

  ArduinoCloud.update();
  // Your code here 

クラウド変数の最小更新時間は仕様上0.5秒ですので、適宜delay(1000)などで呼び出し頻度を制限すれば良さそうです。

例えば変数hogehogeをクラウドに同期したい場合は以下のようにすればOKです。(クラウド変数をcloudHogehogeとする場合)

loop(){
  cloudHogehoge = hogehoge;
  
  ArduinoCloud.update();
  delay(1000);
}

つづいて、SecretタブにはDevice KeyやWi-Fi接続情報を記入していきます。自動生成の場合にはすでにインプットされています。

Arduino IoT Cloudに接続し、クラウド変数を同期するための最低限のコードは以上になります。特に難しいことはなくとてもシンプルなことがわかりました。

ワンクリックでお試し!ULSA用スケッチ(2023/12/05:Core2 V1.1に対応)

さて、ここからArduino IoT Cloudに対応したスケッチを書いて行きましょう。と言いたいところですが、めんどくさいところは置いておいて、簡単お手軽に試したいという方がほとんどだと思いますので、(料理番組的に)動作するスケッチをここに用意しました。

埋め込みブロックが機能していない場合はコチラのリンクをクリック。

では、具体的な書き込み手順を見ていきましょう。
"OPEN CODE"ボタンをクリックし、"ADD TO MY SKETCHBOOK"をクリックしてあなたのWeb Editorにインポートしてください。

※ここで、ボタン右のスケッチダウンロードは行わないでください。ダウンロードしたZip圧縮スケッチをWeb Editorにインポートしてもライブラリ情報が引き継がれないので、そのままではコンパイルに失敗します。

スケッチのインポートが完了したら、右側メニューから"Secret"タブに移動します。

このSecretタブの記入欄に先ほどArduino IoT Cloudで取得したデバイス情報やWi-Fi接続情報を入力していきます。

このように「出来合いのスケッチ」を外部からインポートして使う場合には、先ほどのようにSecretタブに情報が転記されないので、マニュアルで情報を入力する必要があります。

項目説明
SECRET_DEVICE_IDArduino IoT Cloudで取得したデバイスID
SECRET_DEVICE_KEYArduino IoT Cloudで取得したデバイスキー
SECRET_SSID2.4GHzのWi-FiアクセスポイントSSID
SECRET_OPTIONAL_PASSWi-Fiのパスコード

あとは、M5Stackの接続を確認し、→ボタンを押してスケッチをアップロードします。

スケッチのアップロードが完了したらM5StackがArduinoサーバーに適切に接続されているか確認しましょう。デバイス情報やWi-Fi接続情報が間違っていると、このあとデータを可視化する段階でつまずいてしまいます。

Editorの左カラムからシリアルモニター"Monitor"をクリックして115200bpsでポートを開きます。指定したSSIDに正常に接続され、"Connected to Arduino Cloud IoT"と表示されれば成功です。

M5StackがArduino Cloudサーバーに接続されていれば、先ほど設定したThingsのページで該当のデバイスが"Online"となり、クラウド変数がリアルタイムで更新されていく様子が見えるようになります。

以上のステップでついにULSAがクラウドにつながり、クラウド変数の内容がリアルタイムで更新されるようになりました!

ダッシュボードの構築

次にULSAから受け取った計測値を視覚的に表示するダッシュボードを構築していきます。ダッシュボードはドラッグ・アンド・ドロップの完全ノーコードで作成することができます。

メニューの"Dashboards"をクリックしてダッシュボードの名前をつけます。

まずは、風速値をゲージ(メーター)形式で配置したいと思います。

"ADD"から、"Gauge"をクリックしてウィジェットを追加します。

ゲージの設定画面が出てくるので、表示する名前をつけます。

次にこのゲージに対応するクラウド変数を割り当てるため、"Link Variable"ボタンをクリックします。

※さらにゲージではオプションで最小・最大値が決められるようになっているので適宜設定します。

クラウド変数は左から、(対象の)Things -> Variablesと選択していきます。Things(ここではULSA_BLACK)に対してクラウド変数が結びついていますので、Thingsが増えても同じ変数名を使い回すことができます。

通常のローカル変数やグローバル変数では同じ変数名をスコープ内で複数使用することはできませんが、Arduino IoT CloudではあくまでThingsに対してクラウド変数が結びついているということになります。

内部的な実装としては、上記で取得したDevice IDと同じようにクラウド変数を登録したときに一意にIDが割り振られており、同じ変数名でも区別できるようになっています。

このように、データの種類に応じて、ポチポチとウィジェットを追加していきます。
さらに、もう一台のULSA_WHITE分も追加していくと、以下のようなダッシュボードが完成しました。

グラフ表示ではリアルタイムデータの表示から、時間、日単位などに切り替えることができ、細かいデータを見たいときには特定の領域もズームすることができます。

さらに、この画面からスマホ用縦長画面のレイアウトも個別に設定できる用になっており、簡単にスマホ用ウィジェットを構築することが可能です。

付録

ローカルにデータをダウンロードする

以前の記事ではSDカードにデータをロギングする方法とスケッチをご紹介しましたが、Arduino IoT Cloudを実装すれば、ローカルにデータをダウンロードできるようになります。

データの更新頻度は毎秒1回ですので、SDデータロギング(10Hz)よりは粗いデータとなりますが、通常の用途では十分である上に、遠隔に設置したULSAのデータをPCやスマホでモニタリングしながら、適宜ローカルにデータを落とすことができるので、より効率的なデータ収集が可能になります。

データの保持期間はFreeプランだと24時間、Entryで15日間、Makerで3ヶ月間、Maker Plusで1年間と長期間のデータ収集が可能になります。

選択したクラウド変数、または一括でデータをダウンロードできる
データはタイムスタンプ付きで提供される

大規模システムのためのArduino Cloud CLI

大量のThingsの管理にはArduino Cloud CLIが有用

今回はGUIベースのArduino IoT Cloudを使って2台のULSA超音波風速計を使ってリモート計測する事例を紹介しました。しかし、実際の場面ではより多くのThingsを使用することも考えられます。そのような場合、GUIでは操作が煩雑になってしまうので、コマンドライン経由でThingsやクラウド変数の編集、OTAアップロードなどが行えるArduino Cloud CLIがツールとして提供されています。

Getting Started / Arduino Cloud CLI

最後に

IoTといえば、「どこから手を付ければいいのかわからない」「バックグラウンドとなる知識が多すぎて実装まで一向にたどり着けない」ということが起こりがちでした。しかし、Arduino IoT Cloudは様々なデザインの工夫でIoTのハードルを格段に下げることに成功し、インターネットを通じた高度な組み込みアプリケーション作成の仕組みを開放してくれました。

今回はULSAから計測値を読み取るという単純なアプリケーション例を示しましたが、Arduino IoT CloudはThingどうしのクラウド変数の共有・同期やダッシュボードからThingsへのコマンド送信による遠隔制御もサポートしています。

また今後機会があれば、Arduino Cloud CLIを使った大規模IoTシステムの構築や、Arduino IoT Cloud以外の更に高度なIoTプラットフォームを活用したシステム構築などにも挑戦できればと考えています。

みなさまにも本記事を参考に、ぜひULSAのIoT化にチャレンジしていただき、研究や実用用途にULSAをどしどしご活用いただければ幸いです。

前編記事はこちら


注意・免責事項

コメントする

Your email address will not be published. Required fields are marked *

© All Copyrights 2023 STRATOVISION

Index