Deep Insider の Tutor コーナー
>>  Deep Insider は本サイトからスピンオフした姉妹サイトです。よろしく! 
.NET対応組み込みデバイス「Netduino」入門(8)

.NET対応組み込みデバイス「Netduino」入門(8)

GR-PEACHボードとAzure Event Hubでクラウド集計

2015年8月3日 (2015/08/08 更新)

ついに発売開始されたGR-PEACHを利用。Microsoft Azure Event Hubを使って室温データをクラウドに送信してWebから見えるようにしてみよう。

Microsoft MVP for Windows Platform Development 初音 玲
  • このエントリーをはてなブックマークに追加

 前回は、Microsoft Azure Mobile Servicesを使ってNetduinoからHTTP-POSTでREST/JSON形式で室温データを送信した。Microsoft AzureでIoTといえばAMQPSを使うMicrosoft Azure Event Hubsなのだが、残念なことにNetduinoの現在のファームウェアはSSLによる暗号化に対応していないため、HTTPで済むMobile Serviceを選択した。

 今回は前回の最後に予告したように、Arduinoピン互換+.NET Micro Framework+AMQPS対応を満たすボードとして、若松通商から新発売のルネサスGR-PEACHを使って、室温データのクラウド送信を試し見てみる。

GR-PEACHについて

 GR-PEACHは、ルネサスが後押しする『がじぇっとるねさすプロジェクト』が企画し、製造・総販売元の株式会社若松通商が(8月1日のMaker Faire Tokyo 2015で発売開始され)本日から通販サイト上でも購入できるようになっているボードだ。

図1 GR-PEACH

GR-PEACHの特徴

 GR-PEACHは、2つのUSBソケット(=図1の左側)と複数列のピン(=図1の上と下)が存在する。USBソケットは、ArduinoやNetduinoにもあるPC接続IFとGR-PEACHの特徴であるmbed-IFがある(IF=インターフェース)。

 mbed(エンベッド)とは、オンライン開発環境でC++を使ってアプリが作れるプロトタイピング用ワンボードマイコンだ。GR-PEACHも、オンライン開発環境を使ってプログラムコードを作成・コンパイルし、出来上がったバイナリファイルをmbed-IFを通してGR-PEACH で実行できる。

 入出力ピンもArduino互換、つまりNetduino互換が一番外側にある。この位置は物理的にも互換性があるのでArduinoのシールドなどもそのまま使える。

GR-PEACHのハードウェアスペック

 Netduino Plus 2と比較すると、次のようなハードウェアスペックの相違がある。

項目Arduino Uno R3Netduino Plus 2GR-PEACH
CPU ATmega328P
(20MHz 8-bit AVR)
STMicro STM32F4 32bit
(168MHz Cortex-M4)
RZ/A1H
(Coretex-A9 400MHz)
メモリ 32Kbytes 384Kbytes 10Mbytes
デジタル入出力ピン 14本(5V) 14本(出力3.3V、入力5V) Arduino互換ピン部分
14本(出力3.3V、入力3.3V5V
※2015/08/08修正
アナログ入力ピン 6本 6本 Arduino互換ピン部分
6本
アナログ出力ピン 6本 6本 Arduino互換ピン部分
6本
開発環境 Arduino IDE Visual Studio 2013 Community Visual Studio 2013 Community
開発言語 Arduino言語 C# C#
表1 Arduino/Netduino/GR-PEACHの相違点

Visual Studio Communityの最新版は2015になっているが、執筆時点ではVisual Studio 2013のCommunityエディション以上を使う必要がある。

 GR-PEACHにはPinKitと呼ばれる温度センサーが乗ったドーターボード付きのものがある。今回はこのPinKitの評価ボードをお借りすることができたので、製品発売前に執筆できた。貸与していただいた関係者の皆さんに感謝したい。

 なお温度測定には、ドーターボードのセンサーではなく、前回と同じようにブレッドボードに液晶と温度センサーを配置したものを使って測定する。

.NET Micro Frameworkのインストール

 GR-PEACHには出荷状態で.NET Micro Frameworkはインストールされていない。mbed用.NET Micro FrameworkがCodePlexにあるのでダウンロードし(図2)、mbed-IF経由で転送してインストールする。

図2 GR-PEACH用.NET Micro Frameworkのダウンロード

 ダウンロードした.zipファイルから「Tinyclrmbl.bin」ファイルを解凍して取り出す。GR-PEACHをmbed-IFでPCにUSB接続すると、ファイルエクスプローラーにインストール先がドライブ表示される(図3)。

図3 .NET Micro Frameworkインストール

 このドライブ直下に.binファイルをコピーする。コピー時にタイムアウトした場合は、USBを抜き差しした後に、再度根気よくコピーしてみてほしい。なお、.zipファイルの中から直接コピーすると、転送タイムアウトになる確率が高くなるので、事前に解凍して.binファイルを取り出しておくとよい。

インストール状態の確認

 インストールが成功したかどうかは、ファイルコピーが成功した後に、.NET Micro Framework Deployment Tool(MFDeply)で確認ができる。

 まずは、PC側からUSBを取り外して、GR-PEACH側の接続をmbed-IFからPC接続IFにつなぎ替える。その後にPC側でUSBを接続する。

 MFDeplyを起動したら、[Device]接続で「USB」を選択すれば「GR_PEACH_GR_PEACH」が選択できるようになる(図4)。

図4 インストール状態の確認

 メニューバーから[Plug-In]-[Debug]-[Show Device Info]をクリックすれば、DeviceInfo(デバイス情報)が表示される。図4はその表示例で、執筆時点では最新版の4.3.1.0が表示されている。

ネットワーク設定

 今回はEvent Hubsへのデータ送信するので、MFDeplyでネットワーク設定が必要だ。

 ネットワーク設定は、(メニューバーの)[Target]-[Configuration]-[Network]メニューでダイアログを表示して行う。

図5 ネットワーク設定

 [MAC Address]欄に設定する値は、Netduino Plus 2のように裏面にシールで貼られているわけではないので、何か適当な値を指定しなければならない。Netduino Plus 2と同時利用するのでなければ、Netduino Plus 2のシールの値でもよいだろう。

 あとは接続するネットワーク環境に合わせて[DNS Primary Address](プライマリDNSアドレス)を指定して[Update]ボタンをクリックする。設定したMAC Addressは後でデバイスIDとして使用する。

使用部品について

 前回のおさらいになるが使用部品とブレッドボード上の実装を再度紹介する。Netduinoと異なり、5Vトレラントではなく3.3V入力なので、ブレッドボードへの電力供給は3.3Vで行う(※2015/08/08追記)。

図6 ブレッドボード上に配置

FritzingにGR-PEACHが登録されていないので同じピン配置のNetduino Plus 2画像で代用

 GR-PEACHからの3.3V5Vラインは、赤いラインを通ってブレッドボードの一番下のプラス電源ラインを経由し、LCDのVDDRESETそして温度センサーのVDD、1組のプルアップ抵抗へと3.3V5Vを供給する。GR-PEACHのGNDからの線も同様に青いラインを通って下から2番目のGNDラインに接続し、LCDと温度センサーのGNDに接続する。

 SCLSDAの2つの信号線は、SCLがA23、SDAがA22でGR-PEACHに接続し、ここからB13C14に分岐してLCD側に接続する。また、プルアップ用の10KΩ抵抗でA13A14からプラス電源ラインの間を接続する。

 実際に接続すると次の図のようになる。

図7 実装写真

 最後にGR-PEACHにLANケーブルを挿しておこう。

Microsoft Azure Event Hubs

 Event Hubsは、多数のデバイスからのデータ受信、多数のデバイス向けデータ送信に最適なMicrosoft Azureのサービスだ。

 Event Hubで受信したデータはWeb JobsやStream Analyticsを使ってSQL Databaseに格納し、Machine LearningやPower BIなどで分析を行う(図8)。このIoTの一連の流れのうち、Event Hubでの受信までを紹介する。

図8 IoTの流れ

 Azure新ポータルでは、まだEvent Hubの作成ができないので、旧ポータル(manage.windowsazure.com)から行う。

イベントハブの作成

 ポータルトップで左下にある[新規]リンクをクリックして[APP SERVICES]-[サービス バス]-[イベント ハブ]-[カスタム作成]を選択する。

図9 イベントハブの作成

イベントハブ名の指定

図10 イベントハブ名の指定

 今回のサンプルでは、イベントハブ名として「device」、名前空間名として「netduino-ns」を採用した。イベントハブ名は名前空間ごとに設定できるが、名前空間名はAzure全体としてユニークである必要があるので「netduino-ns」以外でおのおの好きな名前を付けてほしい。

 右下の[→]ボタンをクリックして次のページに進むと、パーティション数やデータ保管期間の設定もできるが、パーティション数は最小値の「8」、データ保存期間も最小の「1日」でよいだろう。

イベントハブの構成

 Event Hubにアクセスするためには、ポリシー名とプライマリキーを指定する。初期状態では管理権限付きのポリシーしか存在しないので、デバイスからデータを受信するために権限を限定したアクセスポリシーを作成する。

図11 データ送受信用ポリシーの作成

 図11のように、先ほど作成したEvent Hubの[構成]タブを開き、[共有アクセス ポリシー]欄の新しいポリシー名に「DeviceAccessKey」を指定し、[アクセス許可](=権限)として「リッスン」などを指定する。今回はデバイス側への送信も想定して「送信、リッスン」権限とする。ここで、下部に表示される[保存]ボタンを押しておこう。

 ポリシーを作成すると、[プライマリ キー]が自動生成されるのでメモしておく([共有アクセス キー生成コンポーネント]の[ポリシー名]を「DeviceAccessKey」にする必要があるので注意してほしい)。

NetduinoでのAMQPプログラミング

 それではアプリのプログラミングを始めよう。

新規プロジェクト作成

 Visual Studioで「Console Application」テンプレートを選択して(図12)、新規にプロジェクトを作成する(本稿の例では、プロジェクト名はVisual Basic用は「IoTAmqpVB」、C#用は「IoTAmqpCS」とした)

図12 新規プロジェクトの作成

クラス構成

 前回のクラス構成を基にして、REDTLibクラスの代わりにEventHubLibクラスを作成する(図13)。

図13 クラス構成

 I2C用クラスであるI2CLibクラスを基本クラスとして、LCD用AQM0802Libクラス、温度センサー用ADT7410Libクラスに派生させてから呼び出している。

 データ送信用のEventHubLibクラスも新規クラスファイルとして追加しておこう。

AMQPクラスライブラリの追加

 AMQP用のクラスライブラリは、NuGetパッケージとして配布されている。NuGetから必要なクラスライブラリを取得するには次の手順で行う。

 ソリューションエクスプローラーでプロジェクト名を右クリックして表示されるメニューから[NuGetパッケージの管理]を選択する。その後は図14の内容で実行すればよい。

図14 AMQPクラスライブラリの追加
  • 1[オンライン]を選択。
  • 2検索欄に「AMQP」と入力して検索。
  • 3検索結果の一覧から「AMQP.Net Lite」を選択して[インストール]ボタンをクリック。

 NuGetパッケージとしてインストールすれば、自動的に参照設定なども行われるし、更新がかかればNuGetパッケージの管理で「更新プログラム」に表示されるので、クラスライブラリが管理しやすくなる。

データ送信クラスの作成

 AMQPクラスライブラリの追加が完了したら、室温を送信するためのEventHubLibクラスにコードを記述する。

Visual Basic
Imports System
Imports Microsoft.SPOT
 
Friend Class EventHubLib
  Implements IDisposable
 
  Private Const DeviceId As String = "[MacAddress]"
  Private Const PolicyName As String = "[PolicyName]"
  Private Const AccessKey As String = "[AccessKey]"
  Private Const EventhubNS As String = "[EventHubNamespace]"
  Private Const EventhubName As String = "device"
  Private AmqpSender As Amqp.SenderLink
 
  Public Sub Setup()
    Dim amqpAddress = "amqps://" &
      PolicyName & ":" & AccessKey &
      "@" & EventhubNS & ".servicebus.windows.net"
    Dim addr = New Amqp.Address(amqpAddress)
    Dim connection = New Amqp.Connection(addr)
    Dim session = New Amqp.Session(connection)
 
    Me.AmqpSender = New Amqp.SenderLink(session,
                      "send-link:" & EventhubName,
                      EventhubName & "/Partitions/1")  '1
  End Sub
 
  Public Sub Upload(temperature As Single)
    Try
      Dim message = New Amqp.Message(System.Text.UTF8Encoding.UTF8.GetBytes("Sending Sensor"))
      message.ApplicationProperties = New Amqp.Framing.ApplicationProperties()
      message.ApplicationProperties("DeviceId") = DeviceId.ToString()
      SyncLock (Me)
        message.ApplicationProperties("Temperature") = temperature  '2
      End SyncLock
      Me.AmqpSender.Send(message)                      '3
    Catch ex As Exception
      Debug.Print(ex.Message)
    End Try
  End Sub
 
#Region "IDisposable Support"
    ' ……省略…… 
#End Region
 
End Class
C#
using System;
using Microsoft.SPOT;
 
namespace IoTAmqpCS
{
  public class EventHubLib : IDisposable
  {
    private const string DeviceId = "[MacAddress]";
    private const string PolicyName = "[PolicyName]";
    private const string AccessKey = "[AccessKey]";
    private const string EventhubNS = "[EventHubNamespace]";
    private const string EventhubName = "device";
    private Amqp.SenderLink AmqpSender;
 
    public void Setup()
    {
      var amqpAddress = "amqps://" +
        PolicyName + ":" + AccessKey +
        "@" + EventhubNS + ".servicebus.windows.net";
      var addr = new Amqp.Address(amqpAddress);
      var connection = new Amqp.Connection(addr);
      var session = new Amqp.Session(connection);
 
      this.AmqpSender = new Amqp.SenderLink(session,
        "send-link:" + EventhubName,
        EventhubName + "/Partitions/1");  //1
    }
 
    public void Upload(float temperature)
    {
      try
      {
        var message = new Amqp.Message(System.Text.UTF8Encoding.UTF8.GetBytes("Sending Sensor"));
        message.ApplicationProperties = new Amqp.Framing.ApplicationProperties();
        message.ApplicationProperties["DeviceId"] = DeviceId.ToString();
        lock (this)
        {
          message.ApplicationProperties["Temperature"] = temperature;  //2
        }
        this.AmqpSender.Send(message);    //3
      }
      catch (Exception ex)
      {
        Debug.Print(ex.Message);
      }
    }
 
    #region "IDisposable Support"
      // ……省略…… 
    #endregion
  }
}
リスト1 通信部分(上:EventHubLib.vb、下:EventHubLib.cs)より抜粋

[MacAddress]にはデバイスIDを指定する。また、[PolicyName][AccessKey][EventHubNamespace]を先ほど取得した値に書き換える。なお設定値はURLエンコードされていないといけないので、設定前にURLエンコードサイトなどを使ってエンコードしてから設定してほしい。

  • 1送信先のEventHubパーティションを指定。
  • 2室温を設定。
  • 3AMQPSデータ送信。

メインプログラムの作成

 クラスの用意ができたらMainメソッドを作成する。

Visual Basic
Module Module1
  Sub Main()
  Using amqp As New EventHubLib
      amqp.Setup()
      Using lcd As New AQM0802Lib
        lcd.Init()                            ' ……1
      End Using
      While (True)
        Dim value As Single
 
        Using adt7410 As New ADT7410Lib
          value = adt7410.ReadTemperatre      ' ……2
        End Using
        Using lcd As New AQM0802Lib
          lcd.Locate(0, 0)
          lcd.WriteMessage(value.ToString())  ' ……3
          amqp.Upload(value)                  ' ……4
        End Using
        Thread.Sleep(1000)
      End While
    End Using
  End Sub
End Module
C#
……省略……
public class Program
{
  public static void Main()
  {
    using (var amqp = new EventHubLib())
    {
      amqp.Setup();
      using (AQM0802Lib lcd = new AQM0802Lib())
      {
        lcd.Init();                            // ……1
      }
      while (true)
      {
        Single value;

        using (ADT7410Lib adt7410 = new ADT7410Lib())
        {
          value = adt7410.ReadTemperature();   // ……2
        }
        using (AQM0802Lib lcd = new AQM0802Lib())
        {
          lcd.Locate(0, 0);
          lcd.WriteMessage(value.ToString());  // ……3
          amqp.Upload(value);                  // ……4
        }
        Thread.Sleep(1000);
      }
    }
  }
}
リスト2 メインルーチン(上:Module.vb、下:Program.cs)
  • 1LCD初期化(usingブロックの間だけ接続)。
  • 2温度センサーからの値取得(usingブロックの間だけ接続)。
  • 3LCDに温度表示(usingブロックの間だけ接続)。
  • 4温度データ送信。

アプリ実行

 アプリを実行すると1秒ごとに気温を更新表示する。

【動画】GR-PEACHでIoT

まとめ

 Mobile ServiceにREST/JSONでデータ送信したときと、Event HubにAMQPSで送信したときを比べると、送信するためのメソッド実行は明らかにEvent Hubの方が短時間であった。通信時間が短くて済めば通信モジュールへの通電時間を短くできるので、組み込み機器全体の省電力に寄与する。このようにEvent Hubはデバイスとのデータ送受信に最適化された方法といえるだろう。

 プログラムからアナログやデジタルのピン指定時の方法に多少差異はあるが、今回のようにI2Cとネットワークであれば、Netduino Plus 2と同一コードが使えるなどの特徴があるGR-PEACHはCPU性能やメモリ容量の良さも相まって複雑な処理もパワフルに処理できる。ケースバイケースでNetduino Plus 2とGR-PEACHを使い分けていくのも面白いだろう。

 次回はNetduino Plus 2を使ってマイクロサーボSG90を使ってサーボ制御にチャレンジする。PWMを使ったサーボ制御を紹介予定だ。

【コラム】GR-PEACHのピン定義

 Netduinoで使用するピン指定は、SecretLabs.NETMF.Hardware.Netduino名前空間のPins.GPIO_PIN_D9のように指定する。GR-PEACHのプログラムで使うピン指定もPins.GPIO_PIN_D9と指定できるようにしておくと、Netduino Plus 2のソースコードもPinsの名前空間を切り替えるだけで動作可能になるので便利だ。

 GR-PEACHのArduino互換ピンに対する内部コードは次の表の通りだ。

pin nameCpu.Pin
GPIO_PIN_D0 P2_15
GPIO_PIN_D1 P2_14
GPIO_PIN_D2 P4_7
GPIO_PIN_D3 P4_6
GPIO_PIN_D4 P4_5
GPIO_PIN_D5 P4_4
GPIO_PIN_D6 P8_13
GPIO_PIN_D7 P8_11
GPIO_PIN_D8 P8_15
GPIO_PIN_D9 P8_14
GPIO_PIN_D10 P10_13
GPIO_PIN_D11 P10_14
GPIO_PIN_D12 P10_15
GPIO_PIN_D13 P10_12
SDA P1_3
SCL P1_2
GPIO_PIN_AD0 P1_8
GPIO_PIN_AD1 P1_9
GPIO_PIN_AD2 P1_10
GPIO_PIN_AD3 P1_11
GPIO_PIN_AD4 P1_13
GPIO_PIN_AD5 P1_15
表2 ピンアサイン表(ピンアサイン図より抜粋

 表を参考にしながらGr.NETMF.Hardware.Peach名前空間でPins定義を作っておくとよいだろう。例えば、表中でGPIO_PIN_D0にはP2_15が相当するので、GPIO_PIN_D0には「0x02」+「0x0f」=0x2fを割り当てる。

 なお、今回のサンプルではI2Cのみを使用しているので、GR-PEACH用のピンアサイン定義は不要だ。GR-PEACHを使ってアナログ入力やデジタル入出力を行う場合に、この表を活用してほしい。

【更新履歴】2015/08/08

 GR-PEACHのデジタル入力ピンを、当初、「5V」としていましたが、「3.3V」の誤りでした。お詫びして訂正させていただきます。

※以下では、本稿の前後を合わせて5回分(第6回~第10回)のみ表示しています。
 連載の全タイトルを参照するには、[この記事の連載 INDEX]を参照してください。

.NET対応組み込みデバイス「Netduino」入門(8)
6. Netduinoシリアル通信(I2C)で複数機器接続

シリアル通信(I2C)で2つ以上の機器を同時に使用するサンプルを作成する。温度センサーから室温を取得して液晶ディスプレイ(LCD)にリアルタイム表示してみよう。

.NET対応組み込みデバイス「Netduino」入門(8)
7. Netduinoの計測結果をクラウド集計

Netduinoで計測した室温データをクラウドに送信してWebから見えるようにしてみよう。

.NET対応組み込みデバイス「Netduino」入門(8)
8. 【現在、表示中】≫ GR-PEACHボードとAzure Event Hubでクラウド集計

ついに発売開始されたGR-PEACHを利用。Microsoft Azure Event Hubを使って室温データをクラウドに送信してWebから見えるようにしてみよう。

.NET対応組み込みデバイス「Netduino」入門(8)
9. サーボモーターをコントロールしよう

Netduinoはセンサー入力系だけでなく豊富な出力系も活用できる。今回は、ラジコン経験者にはなじみがあるサーボモーターをNetduinoから制御してみよう。

.NET対応組み込みデバイス「Netduino」入門(8)
10. Windows 10+Visual Studio 2015でNetduinoアプリを動かすには?

本シリーズのNetduinoサンプルをWindows 10+Visual Studio 2015で動かす方法と注意点を番外編のコラムとしてまとめた。

サイトからのお知らせ

Twitterでつぶやこう!