こんにちわ。
昨今のIoTシーンにおいて、猫も杓子もEspressifありきなのが納得行かない捻くれ者です。
概要
Microsoft Azure と Arduino を連携させて、IoT環境構築にチャレンジしてみました。
今回は、AzureとArduinoの双方向メッセージングまでを試したいと思います。
使用するAzureサービス
IoTHub
IoTデバイスを纏めて管理出来るサービスです。
主な内容は以下となります。
- デバイスの登録/削除
- 通信する際の認証
- データの送信/受信
- 状態監視
StreamAnalytics
データストリームをリアルタイム処理してくれるサービスです。
今回は、IoTHubが受信したデータを受け取り、後述のBlobStorageへ書き込む、仲介役的な動作をしています。
なお、StreamAnalyticsの代わりに Azure EventHubs や Azure Function を使う方法もあるそうです。
が、使ってみたら結構難しかったので、今回は一番簡単だったStreamAnalyticsを使う事にしました。
BlobStorage
ストレージサービスです。
BlobStorageは、リアルタイム性の高いストリームデータを保存するのに向いてるそうです。
Azureのストレージサービスは他にも何種類か存在し、OneDriveのようにファイル単位の操作を得意とする FileStorage や、SQL的なテーブルデータを扱える TableStorage などがあります。
Azureはホントに沢山のサービスが存在して、違うサービスでも実装によっては同じような事が出来たりします。
なので、やりたい事に対してどのサービスを使うのがベストか、と言うのは悩み所だと感じました。
使用するデバイス
Arduino
互換ボードでも問題ありません。
ただ、Mega328P や Mega32u4 搭載ボードは、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など) |
言葉で説明するとややこしくなるので、スクリーンショットを交えて解説して行きます。
IoTHubの作成
1. リソースを作成する
**[リソースの作成]から[IoT Hub]**を選択します。
初期設定画面が表示されるので埋めて行きます。
まずは**[Basics]**タブ。
入力項目 | 内容 |
---|---|
Subscription | 現在のサブスクリプション名 |
Resource Group | 既存or新規作成どちらでも |
Region | 東日本or西日本の近い方 |
IoT Hub Name | 外部公開されるので機密情報や被りはNG |
次は**[Size and scale]**タブ。
入力項目 | 内容 |
---|---|
Pricing and scale tier | F1: FreeTier |
終わったら、下の**[Review + create]**を押すと、数分間デプロイ処理の後、リソースが作成されます。
2. デバイスを登録する
作成したIoTHubリソースへ移動し、**[IoT devices]から[Add]**を選択します。
デバイス名などの設定をしていきます。
終わったら、下の**[Save]**を押すと、登録完了です。
3. 接続キーを確認する
キーが沢山並んでますが、デバイスとの通信に必要なのは1個だけです。
確認項目 | 内容 |
---|---|
Connection string (primary key) | 後述のArduinoスケッチ内String azurekey に貼り付ける |
これでIoTHubの準備は完了です。
BlobStorageの作成
1. リソースを作成する
**[リソースの作成]から[ストレージアカウント]**を選択します。
初期設定を埋めて行きます。
まずは**[基本]**タブ。
入力項目 | 内容 |
---|---|
サブスクリプション | 現在のサブスクリプション名 |
リソースグループ | 既存or新規作成どちらでも |
ストレージアカウント名 | 外部公開されるので機密情報や被りはNG |
場所 | 東日本or西日本の近い方 |
パフォーマンス | Standard |
アカウントの種類 | Storage(汎用v1) |
レプリケーション | ローカル冗長ストレージ(LRS) |
次は**[詳細]**タブ。
入力項目 | 内容 |
---|---|
安全な転送が必須 | 有効 |
仮想ネットワーク | すべてのネットワーク |
DATA LAKE STORAGE GEN2 | よく分からんので初期値(無効) |
終わったら、下の**[確認および作成]**を押すと、数分間デプロイ処理の後、リソースが作成されます。
これでBlobStorageの準備は完了です。
StreamAnalyticsの作成
1. リソースを作成する
**[リソースの作成]から[Stream Analytics job]**を選択します。
初期設定を埋めて行きます。
入力項目 | 内容 |
---|---|
job name | 外部公開されるので機密情報や被りはNG |
Subscription | 現在のサブスクリプション名 |
Resource Group | 既存or新規作成どちらでも |
Region | 東日本or西日本の近い方 |
Hosting environment | Cloud |
Streaming units (1 to 120) | 1 |
終わったら、下の**[作成]**を押すと、数分間デプロイ処理の後、リソースが作成されます。
2. 言語設定
作成したStreamAnalyticsリソースに移動し、**[Locale]**を選択します。
入力項目 | 内容 |
---|---|
Data locale | 日本語(日本) |
終わったら、上の**[Save]**で保存完了です。
3. データ入力先を作成する
**[Inputs]から[Add stream input]内の[IoT Hub]**を選択します。
入力先設定を行います。
終わったら、下の**[Save]**で保存完了です。
4. データ出力先を作成する
**[Outputs]から[Add]内の[Blob storage]**を選択します。
出力先設定を行います。
終わったら、下の**[Save]**で保存完了です。
5. 処理内容を記述する
**[Query]**を選択し、エディタ内にSQL文を記述します。
-- 入力データを出力に丸投げする
select * into [output_alias] from [input_alias]
終わったら、上の**[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 |
ブレッドボードに組んだ状態ですが、至ってシンプルです。
(右下のディスプレイはデバッグ用なので関係無いです)
ソフトウェアの実装
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 = "";
先ほど [接続キーを確認する](#3. 接続キーを確認する) で確認した**[Connection string (primary key)]**を貼り付けます。
イメージとしてはこんな感じです。
String azurekey = "HostName=<HostName>;DeviceId=<DeviceName>;SharedAccessKey=<DeviceKey>";
なお、サンプルスケッチでは、**{A0}**ピンのアナログ値を送信するようになっています。
通常はここにセンサー等を接続して、読み取った値を送信するような感じになります。
が、今回の趣旨はデバイスとクラウドの連携なので、センサーは接続しなくても問題無いです。
センサーを接続しなかった場合は、空文字列が送信されます。
動作テスト
全ての準備は整いました。
1. StreamAnalyticsを起動する
**[Start]**を選択し、起動タイミングを指定します。
入力項目 | 内容 |
---|---|
Job output start time | Now |
終わったら、**[Start]を押した後、数十秒で起動が完了します。
起動後は、[Stopped]の部分が[Running]**に変わります。
2. Arduinoを起動する
PCとArduinoを接続し、COMポートを開きます。
**[Attempting MQTT connection... connected]と表示されたら、IoTHubとの接続は成功です。
その後は無限ループで、データが送信される度に[pushed]**と表示されます。
3. 蓄積されたデータを確認する
Storageリソースを開き、**[Blob]**からコンテナ名を選択します。
コンテナを辿って行くとJSONファイルがあるので、開いてから**[BLOBの編集]**を選択します。
エディタに、Arduinoから送信されたJSONデータが蓄積されていれば、無事に動作している証です。
4. デバイスにデータを送信する
そしてIoTHub最大の魅力、デバイスへのデータ送信を行います。
IoTHubリソースを開き、**[IoT devices]**からデバイス名を選択します。
上の**[Message to device]**を選択します。
**[Device Id]を確認後、送信したいメッセージを入力します。
今回は試してませんが、[Properties]**よりJSON文字列も送信可能です。
入力項目 | 内容 |
---|---|
Message Body | (お好みで) |
終わったら、上の**[Send Message]**を押すと、数秒後に送信完了します。
そして、COMポートに**[Azure Message arrived [(your message)]]**と表示されれば無事成功です。
5. StreamAnalyticsを停止する
StreamAnalyticsリソースを開き、**[Stop]から[はい]**を選択します。
クラウドサービスは、使った分だけ課金されます。
万が一ではありますが、サービスを起動したまま接続キーが漏れてしまい、悪用されてしまったら、それはもう顔面蒼白な請求書が届く事は間違い無しです。
悪用が証明出来れば、救済措置はあるそうですが、そんな寿命の縮むような思いをしない為にも、使わないサービスはこまめに停止しましょう。
6. メトリクス(ログ)を確認する
Azureサービスは、誰が何をいつどれだけ使ったか、一目瞭然で表示されます。
StreamAnalyticsは、このグラフから**{21:50から22:00にかけて計40回の入力と出力があった}**と言う事がパッと見で分かります。
IoTHubは、このグラフから**{21:50から22:00にかけて94回の受信と1回の送信があった}**と言う事が分かります。
勿論、各リソースの**[メトリック]**欄から、もっと詳細なログを条件指定で確認出来ます。
まとめ
かなり長くなってしまいましたが、逆を言えば、たったこれだけでIoTデバイスとクラウドサービスを連携可能、とも言えるでしょう。
そもそもクラウドサービスの利用自体が初めてだったので、最初はかなり敷居高そうなイメージでした。
しかし、実際使ってみたら思ったより簡単で、イメージが大きく変わりました。
環境は整ったので、後は足回りを肉付けするだけです。
色々と想像が膨らみますが、また次回としましょう。
それではまた。