LoginSignup
12
10

More than 5 years have passed since last update.

AzureとArduinoでIoT連携(IoTHub+StreamAnalytics+BlobStorage)

Posted at

こんにちわ。

昨今のIoTシーンにおいて、猫も杓子もEspressifありきなのが納得行かない捻くれ者です。

概要

Microsoft AzureArduino を連携させて、IoT環境構築にチャレンジしてみました。
今回は、AzureとArduinoの双方向メッセージングまでを試したいと思います。

使用するAzureサービス

IoTHub

IoTデバイスを纏めて管理出来るサービスです。
主な内容は以下となります。

  • デバイスの登録/削除
  • 通信する際の認証
  • データの送信/受信
  • 状態監視

StreamAnalytics

データストリームをリアルタイム処理してくれるサービスです。

今回は、IoTHubが受信したデータを受け取り、後述のBlobStorageへ書き込む、仲介役的な動作をしています。

なお、StreamAnalyticsの代わりに Azure EventHubsAzure Function を使う方法もあるそうです。
が、使ってみたら結構難しかったので、今回は一番簡単だったStreamAnalyticsを使う事にしました。

BlobStorage

ストレージサービスです。

BlobStorageは、リアルタイム性の高いストリームデータを保存するのに向いてるそうです。

Azureのストレージサービスは他にも何種類か存在し、OneDriveのようにファイル単位の操作を得意とする FileStorage や、SQL的なテーブルデータを扱える TableStorage などがあります。


Azureはホントに沢山のサービスが存在して、違うサービスでも実装によっては同じような事が出来たりします。
なので、やりたい事に対してどのサービスを使うのがベストか、と言うのは悩み所だと感じました。

使用するデバイス

Arduino

互換ボードでも問題ありません。

ただ、Mega328PMega32u4 搭載ボードは、RAMが少ないので動かないかも知れません。
SAMD21/51 搭載ボードなら確実だと思います。

僕は Feather M4 Express を使っています。

WINC1500

WiFiモジュールです。

Arduinoとの接続は SPI となっています。
TLS1.2に対応しており、メジャーな証明書は出荷時に登録済なので、セキュア通信を手軽に実装出来ます。

僕は WINC1500 Breakout を使っています。

捻くれ者なのでESP8266は意地でも使いません。

仕様

通信方式

MQTT over TLS を使用します。

MQTTは、IoT向けに開発された通信プロトコルです。
HTTPと比較してヘッダサイズがとても小さい為、1回あたりの通信量が少なく、かつ頻繁にやり取りするIoT用途に丁度良いとされています。

ただ、HTTPと同様でMQTT自体に暗号化の概念は無いので、暗号化にTLSを用いた、MQTToverTLS(MQTTS)と言うプロトコルが主流となっています。

今回の通信方式は以下の通りです。

項目 内容
通信プロトコル MQTTS
暗号化方式 TLS1.2
ポート番号 8883
MQTT Version 3.1.1
最大送信パケットサイズ 1280 Byte

データフォーマット

ここは皆大好き JSON で行きましょう。

僕はJavaScriptおじさんなので、XMLとか言う脂身だらけの肉みたいな見辛いフォーマットは苦手なのです、悪しからず。
(正直ArduinoもJavaScriptで書けたら良いのにとか思ってます。JerryScript...?そのうちね...)

Azure側の構築

ログイン

Microsoftアカウントで ログイン します。

初回ログイン時は、課金時のクレジットカード情報など、幾つかの追加情報を求められます。

なお、Azureの階層構成は以下の通りです。

階層 名称 内容
1 ActiveDirectory 最上層, アカウントが所属する範囲
2 Subscription 課金プランが適用される範囲
3 ResourceGroup リソースが所属するグループ
4 Resource 最下層, 各種サービス(IoTHubなど)

ちなみに、僕のトップページはこんな感じになっています。
az-01.png

言葉で説明するとややこしくなるので、スクリーンショットを交えて解説して行きます。

IoTHubの作成

1. リソースを作成する

[リソースの作成]から[IoT Hub]を選択します。
iothub-01.png

初期設定画面が表示されるので埋めて行きます。
まずは[Basics]タブ。

入力項目 内容
Subscription 現在のサブスクリプション名
Resource Group 既存or新規作成どちらでも
Region 東日本or西日本の近い方
IoT Hub Name 外部公開されるので機密情報や被りはNG

iothub-02.png

次は[Size and scale]タブ。

入力項目 内容
Pricing and scale tier F1: FreeTier

iothub-03.png

終わったら、下の[Review + create]を押すと、数分間デプロイ処理の後、リソースが作成されます。

2. デバイスを登録する

作成したIoTHubリソースへ移動し、[IoT devices]から[Add]を選択します。
iothub-04.png

デバイス名などの設定をしていきます。

入力項目 内容
Device ID リソース内で被らなければOK
Authentication type 初期値(Symmetric key)
Primary key (自動入力)
Secondary key (自動入力)
Auto-generate keys チェック入れる(上2つのキーを自動生成してくれる)
Connect this device to an IoT hub Enable
Parent device よく分からんのでノータッチ

iothub-05.png

終わったら、下の[Save]を押すと、登録完了です。

3. 接続キーを確認する

登録したデバイス名を選択します。
iothub-06.png

キーが沢山並んでますが、デバイスとの通信に必要なのは1個だけです。

確認項目 内容
Connection string (primary key) 後述のArduinoスケッチ内String azurekeyに貼り付ける

iothub-07.png

これでIoTHubの準備は完了です。

BlobStorageの作成

1. リソースを作成する

[リソースの作成]から[ストレージアカウント]を選択します。
bs-01.png

初期設定を埋めて行きます。
まずは[基本]タブ。

入力項目 内容
サブスクリプション 現在のサブスクリプション名
リソースグループ 既存or新規作成どちらでも
ストレージアカウント名 外部公開されるので機密情報や被りはNG
場所 東日本or西日本の近い方
パフォーマンス Standard
アカウントの種類 Storage(汎用v1)
レプリケーション ローカル冗長ストレージ(LRS)

bs-02.png

次は[詳細]タブ。

入力項目 内容
安全な転送が必須 有効
仮想ネットワーク すべてのネットワーク
DATA LAKE STORAGE GEN2 よく分からんので初期値(無効)

bs-03.png

終わったら、下の[確認および作成]を押すと、数分間デプロイ処理の後、リソースが作成されます。

これでBlobStorageの準備は完了です。

StreamAnalyticsの作成

1. リソースを作成する

[リソースの作成]から[Stream Analytics job]を選択します。
sa-01.png

初期設定を埋めて行きます。

入力項目 内容
job name 外部公開されるので機密情報や被りはNG
Subscription 現在のサブスクリプション名
Resource Group 既存or新規作成どちらでも
Region 東日本or西日本の近い方
Hosting environment Cloud
Streaming units (1 to 120) 1

sa-02.png

終わったら、下の[作成]を押すと、数分間デプロイ処理の後、リソースが作成されます。

2. 言語設定

作成したStreamAnalyticsリソースに移動し、[Locale]を選択します。

入力項目 内容
Data locale 日本語(日本)

sa-03.png

終わったら、上の[Save]で保存完了です。

3. データ入力先を作成する

[Inputs]から[Add stream input]内の[IoT Hub]を選択します。
sa-04.png

入力先設定を行います。

入力項目 内容
Input alias リソース内で被らなければOK
Provide IoT Hub settings manually チェック外す
Select IoT Hub from your subscriptions チェック入れる
サブスクリプション 現在のサブスクリプション名
IoT Hub 入力先のIoTHub名
Endpoint Messaging
Shared access policy name iothubowner
Shared access policy key (自動入力)
Consumer group よく分からんので初期値($Default)
Event serialization format 皆大好きJSON(CSVもあるよ)
Encoding UTF-8
Event compression type よく分からんので初期値(None)

sa-05.png

終わったら、下の[Save]で保存完了です。

4. データ出力先を作成する

[Outputs]から[Add]内の[Blob storage]を選択します。
sa-06.png

出力先設定を行います。

入力項目 内容
Output alias リソース内で被らなければOK
Provide Blob storage settings manually チェック外す
Select Blob storage from your subscriptions チェック入れる
サブスクリプション 現在のサブスクリプション名
Storage account 出力先のStorage名
Storage account key (自動入力)
Container BlobStorage内フォルダの事, 既存or新規作成どちらでも
Path pattern {Date}(日付毎にフォルダが自動作成される)
Date format YYYY/MM/DD
Time format よく分からんので初期値(自動入力)
Event serialization format 皆大好きJSON(CSVもあるよ)
Encoding UTF-8
Format よく分からんので初期値(Line separated)

sa-07.png

終わったら、下の[Save]で保存完了です。

5. 処理内容を記述する

[Query]を選択し、エディタ内にSQL文を記述します。

-- 入力データを出力に丸投げする
select * into [output_alias] from [input_alias]

sa-08.png

終わったら、上の[Save]で保存完了です。

これで、StreamAnalyticsの準備は完了です。

Arduino側の構築

ハードウェアの実装

至って単純です。
SPIバスと電源をそれぞれ接続するだけです。

SPI信号ピン{MISO, MOSI, SCK}は、両側とも指定のピンに接続します。
SPI制御ピン{CS, IRQ, RST, EN}は、Arduino側は何処のピンに接続しても大丈夫です。

今回はそれぞれ{9, 10, 11, 12}番ピンとしました。

Arduino側ピン WINC1500側ピン
MISO MISO
MOSI MOSI
SCK SCK
任意(Pin9) CS
任意(Pin10) IRQ
任意(Pin11) RST
任意(Pin12) EN

hard-wire.png

ブレッドボードに組んだ状態ですが、至ってシンプルです。
(右下のディスプレイはデバッグ用なので関係無いです)
hard.jpg

ソフトウェアの実装

ESP8266向けのIoTHubクライアントライブラリを、Arduino/WINC1500でも使用出来るように移植しました。
なお、このライブラリは、Arduino公式WiFiライブラリを内部参照しているので、そちらも併せてインストールします。

基本はサンプルスケッチの通りで大丈夫です。
{SSID}など固有の部分を追加入力したら、コンパイルと書き込みを行います。

基本的な使用方法は readme.md にざっくり書いてあるので、掻い摘んで解説します。

1. WiFi.setPins(cs, irq, rst, en);

先ほど ハードウェアの実装 で接続した、SPI制御ピンの番号をそれぞれ指定します。
今回の例では以下となります。

WiFi.setPins(9, 10, 11, 12);

2. String azurekey = "";

先ほど 接続キーを確認する で確認した[Connection string (primary key)]を貼り付けます。
イメージとしてはこんな感じです。

String azurekey = "HostName=<HostName>;DeviceId=<DeviceName>;SharedAccessKey=<DeviceKey>";

なお、サンプルスケッチでは、{A0}ピンのアナログ値を送信するようになっています。
通常はここにセンサー等を接続して、読み取った値を送信するような感じになります。

が、今回の趣旨はデバイスとクラウドの連携なので、センサーは接続しなくても問題無いです。
センサーを接続しなかった場合は、空文字列が送信されます。

動作テスト

全ての準備は整いました。

1. StreamAnalyticsを起動する

[Start]を選択し、起動タイミングを指定します。

入力項目 内容
Job output start time Now

try-01.png

終わったら、[Start]を押した後、数十秒で起動が完了します。
起動後は、[Stopped]の部分が[Running]に変わります。

2. Arduinoを起動する

PCとArduinoを接続し、COMポートを開きます。
[Attempting MQTT connection... connected]と表示されたら、IoTHubとの接続は成功です。
その後は無限ループで、データが送信される度に[pushed]と表示されます。
try-10.jpg

3. 蓄積されたデータを確認する

Storageリソースを開き、[Blob]からコンテナ名を選択します。
try-02.jpg

コンテナを辿って行くとJSONファイルがあるので、開いてから[BLOBの編集]を選択します。
エディタに、Arduinoから送信されたJSONデータが蓄積されていれば、無事に動作している証です。
try-03.jpg

4. デバイスにデータを送信する

そしてIoTHub最大の魅力、デバイスへのデータ送信を行います。
IoTHubリソースを開き、[IoT devices]からデバイス名を選択します。
iothub-06.png

上の[Message to device]を選択します。
try-04.jpg

[Device Id]を確認後、送信したいメッセージを入力します。
今回は試してませんが、[Properties]よりJSON文字列も送信可能です。

入力項目 内容
Message Body (お好みで)

try-05.jpg

終わったら、上の[Send Message]を押すと、数秒後に送信完了します。

そして、COMポートに[Azure Message arrived [(your message)]]と表示されれば無事成功です。
try-06.jpg

5. StreamAnalyticsを停止する

StreamAnalyticsリソースを開き、[Stop]から[はい]を選択します。
try-07.jpg

クラウドサービスは、使った分だけ課金されます。
万が一ではありますが、サービスを起動したまま接続キーが漏れてしまい、悪用されてしまったら、それはもう顔面蒼白な請求書が届く事は間違い無しです。

悪用が証明出来れば、救済措置はあるそうですが、そんな寿命の縮むような思いをしない為にも、使わないサービスはこまめに停止しましょう。

6. メトリクス(ログ)を確認する

Azureサービスは、誰が何をいつどれだけ使ったか、一目瞭然で表示されます。

StreamAnalyticsは、このグラフから{21:50から22:00にかけて計40回の入力と出力があった}と言う事がパッと見で分かります。
try-08aa.jpg

IoTHubは、このグラフから{21:50から22:00にかけて94回の受信と1回の送信があった}と言う事が分かります。
try-09aa.jpg

勿論、各リソースの[メトリック]欄から、もっと詳細なログを条件指定で確認出来ます。

まとめ

かなり長くなってしまいましたが、逆を言えば、たったこれだけでIoTデバイスとクラウドサービスを連携可能、とも言えるでしょう。

そもそもクラウドサービスの利用自体が初めてだったので、最初はかなり敷居高そうなイメージでした。
しかし、実際使ってみたら思ったより簡単で、イメージが大きく変わりました。

環境は整ったので、後は足回りを肉付けするだけです。
色々と想像が膨らみますが、また次回としましょう。

それではまた。

12
10
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
10