IoTデバイスをクラウドに接続する - Wio Terminal
このレッスンのこの部分では、Wio TerminalをIoT Hubに接続して、テレメトリを送信し、コマンドを受信します。
デバイスをIoT Hubに接続する
次のステップは、デバイスをIoT Hubに接続することです。
タスク - IoT Hubに接続する
-
VS Codeで
soil-moisture-sensor
プロジェクトを開きます。 -
platformio.ini
ファイルを開きます。knolleary/PubSubClient
ライブラリ依存関係を削除します。これはパブリックMQTTブローカーに接続するために使用されていましたが、IoT Hubに接続するためには必要ありません。 -
次のライブラリ依存関係を追加します:
seeed-studio/Seeed Arduino RTC @ 2.0.0
arduino-libraries/AzureIoTHub @ 1.6.0
azure/AzureIoTUtility @ 1.6.1
azure/AzureIoTProtocol_MQTT @ 1.6.0
azure/AzureIoTProtocol_HTTP @ 1.6.0
azure/AzureIoTSocket_WiFi @ 1.0.2Seeed Arduino RTC
ライブラリは、Wio Terminalのリアルタイムクロックと対話するためのコードを提供します。残りのライブラリは、IoTデバイスがIoT Hubに接続するためのものです。 -
platformio.ini
ファイルの一番下に次の内容を追加します:build_flags =
-DDONT_USE_UPLOADTOBLOBこれは、Arduino IoT Hubコードをコンパイルする際に必要なコン パイラフラグを設定します。
-
config.h
ヘッダーファイルを開きます。すべてのMQTT設定を削除し、デバイス接続文字列のための次の定数を追加します:// IoT Hub設定
const char *CONNECTION_STRING = "<connection string>";<connection string>
を、以前にコピーしたデバイスの接続文字列に置き換えます。 -
IoT Hubへの接続は時間ベースのトークンを使用します。これは、IoTデバイスが現在の時間を知る必要があることを意味します。Windows、macOS、Linuxのようなオペレーティングシステムとは異なり、マイクロコントローラーはインターネット経由で自動的に現在の時間を同期しません。これにより、NTPサーバーから現在の時間を取得するコードを追加する必要があります。時間が取得されると、Wio Terminalのリアルタイムクロックに保存され、デバイスが電力を失わない限り、後で正しい時間を要求することができます。次のコードを含む
ntp.h
という新しいファイルを追加します:#pragma once
#include "DateTime.h"
#include <time.h>
#include "samd/NTPClientAz.h"
#include <sys/time.h>
static void initTime()
{
WiFiUDP _udp;
time_t epochTime = (time_t)-1;
NTPClientAz ntpClient;
ntpClient.begin();
while (true)
{
epochTime = ntpClient.getEpochTime("0.pool.ntp.org");
if (epochTime == (time_t)-1)
{
Serial.println("NTPエポック時間の取得に失敗しました!再試行まで2秒待ちます。");
delay(2000);
}
else
{
Serial.print("取得したNTPエポック時間は:");
char buff[32];
sprintf(buff, "%.f", difftime(epochTime, (time_t)0));
Serial.println(buff);
break;
}
}
ntpClient.end();
struct timeval tv;
tv.tv_sec = epochTime;
tv.tv_usec = 0;
settimeofday(&tv, NULL);
}このコードの詳細はこのレッスンの範囲外です。これは、NTPサーバーから現在の時間を取得し、それを使用してWio Terminalの時計を設定する
initTime
という関数を定義します。 -
main.cpp
ファイルを開き、PubSubClient.h
ヘッダーファイル、PubSubClient
変数の宣言、reconnectMQTTClient
およびcreateMQTTClient
メソッド、およ びこれらの変数とメソッドへのすべての呼び出しを含むすべてのMQTTコードを削除します。このファイルには、WiFiに接続し、土壌湿度を取得し、それを含むJSONドキュメントを作成するコードのみが含まれている必要があります。 -
IoT Hubライブラリのヘッダーファイルと時間を設定するためのヘッダーファイルを含めるために、
main.cpp
ファイルの先頭に次の#include
ディレクティブを追加します:#include <AzureIoTHub.h>
#include <AzureIoTProtocol_MQTT.h>
#include <iothubtransportmqtt.h>
#include "ntp.h" -
現在の時間を設定するために、
setup
関数の最後に次の呼び出しを追加します:initTime();
-
ファイルの先頭に、インクルードディレクティブのすぐ下に次の変数宣言を追加します:
IOTHUB_DEVICE_CLIENT_LL_HANDLE _device_ll_handle;
これは、IoT Hubへの接続のハンドルである
IOTHUB_DEVICE_CLIENT_LL_HANDLE
を宣言します。 -
これの下に次のコードを追加します:
static void connectionStatusCallback(IOTHUB_CLIENT_CONNECTION_STATUS result, IOTHUB_CLIENT_CONNECTION_STATUS_REASON reason, void *user_context)
{
if (result == IOTHUB_CLIENT_CONNECTION_AUTHENTICATED)
{
Serial.println("デバイスクライアントはiothubに接続されています");
}
else
{
Serial.println("デバイスクライアントは切断されました");
}
}これは、接続ステータスが変わったときに呼び出されるコールバック関数を宣言します。ステータスはシリアルポートに送信されます。
-
これの下に、IoT Hubに接続するための関数を追加します:
void connectIoTHub()
{
IoTHub_Init();
_device_ll_handle = IoTHubDeviceClient_LL_CreateFromConnectionString(CONNECTION_STRING, MQTT_Protocol);
if (_device_ll_handle == NULL)
{
Serial.println("Iothubデバイスの作成に失敗しました。ヒント:接続文字列を確認してください。");
return;
}
IoTHubDeviceClient_LL_SetConnectionStatusCallback(_device_ll_handle, connectionStatusCallback, NULL);
}このコードは、IoT Hubライブラリコードを初期化し、
config.h
ヘッダーファイルの接続文字列を使用して接続を作成します。この接続はMQTTに基づいています。接続に失敗した場合、これはシリアルポートに送信されます - 出力でこれが表示された場合、接続文字列を確認してください。最後に、接続ステータスコールバックが設定されます。 -
setup
関数のinitTime
呼び出しの下にこの関数を呼び 出します:connectIoTHub();
-
MQTTクライアントと同様に、このコードは単一のスレッドで実行されるため、ハブによって送信されるメッセージとハブに送信されるメッセージを処理する時間が必要です。これを行うために、
loop
関数の先頭に次のコードを追加します:IoTHubDeviceClient_LL_DoWork(_device_ll_handle);
-
このコードをビルドしてアップロードします。シリアルモニターに接続が表示されます:
WiFiに接続中..
接続されました!
取得したNTPエポック時間は:1619983687
テレメトリを送信中 {"soil_moisture":391}
デバイスクライアントはiothubに接続されています出力には、NTP時間の取得後、デバイスクライアントの接続が表示されます。接続には数秒かかることがあるため、デバイスが接続されるまでに土壌湿度が出力に表示されることがあります。
💁 NTPのUNIX時間をより読みやすいバージョンに変換するには、unixtimestamp.comのようなウェブサイトを使用できます。
テレメトリを送信する
デバイスが接続されたので、MQTTブローカーの代わりにIoT Hubにテレメトリを送信できます。