クラウドエンジニアブログ

風速計の IoT Edge デバイス化 ②

human01

今泉 正

Windows 10 IoT Core と Raspberry Pi 3 で Azure に接続できる風速計を IoT Edge デバイス化してみよう!

こんにちは! 今泉 正です。
今回は、風速計から GPIO (General Purpose Input/Output) でパルスを取り込んでパルス数を計算し、IoT Hub へ風速を送信するためのソースコードを書きます。

ソースコード書いてみよう!

ソースコードを書く準備

Windows 10 IoT Core Dashboard のインストール

https://docs.microsoft.com/ja-jp/windows/iot-core/downloads
Raspberry Pi 3 起動用の Windows 10 IoT Core の OS イメージを microSD カードへ書き込むために、上記ページより、ダウンロードしてください。また、Windows 10 IoT Core Dashboard を使用すれば、OS イメージの書き込みデバイスの管理、Azure との連携も行えます。また、ボードに合った IoT Core ISO のイメージのみをダウンロードすることも可能です。

Windows 10 SDK のインストール

https://developer.microsoft.com/ja-jp/windows/downloads/windows-10-sdk
Windows 10 (Windows 10 IoT Core 含む) アプリを開発するために、上記ページより、インストールしてください。

Visual Studio 2017 の設定

・ファイル>新規プログラムの作成>新しいプロジェクト>Visual C#>Windows ユニバーサル>空白のアプリ(ユニバーサル Windows)

ユニバーサル Windows

・ソリューションエクスプローラー>参照>参照の追加>参照マネージャー

参照マネージャー

・参照マネージャー>Universal Windows>拡張>Windows Desktop Extensions for the UWP (最新版を推奨)

Windows Desktop Extensions for the UWP


NuGet の取得

・ソリューションエクスプローラー>NuGet パッケージの管理

NuGet パッケージの管理

・Microsoft.Azure.Device.Client を選択

Microsoft.Azure.Device.Client

・Microsoft.NetCore.UniversalWindows.Platform を選択

Microsoft.NetCore.UniversalWindows.Platform

・Newtonsoft.Json を選択

Newtonsoft.Json

・以下のように3種類がインストールできていれば NuGet の取得完了です。

NuGet の取得完了

Azure Portal から Raspberry Pi を接続する IoT Hub を作成

Microsoft IoT Hub は以下を参照ください。
https://docs.microsoft.com/ja-jp/azure/iot-hub/iot-hub-csharp-csharp-getstarted
「IoT Hub の作成」を参照して、IoT Hub を作成し、Connection string Primary Key をコピーして、作成したソースコードへ貼り付けます。


ソースコード

using System;
using Windows.Devices.Gpio;
using Microsoft.Azure.Devices.Client;
using Newtonsoft.Json;
using System.Text;

namespace Anemometer
{
    public sealed partial class MainPage : Page
    {
        // Azure IoT HubのIDレジストリで作成したもの入力
        static DeviceClient deviceClient;
        static string iotHubUri = "{iot hub hostname}";
        static string deviceKey = "{device key}";

        static DeviceClient deviceClient = DeviceClient.Create(iotHubUri,new DeviceAuthenticationWithRegistrySymmetricKey("myFirstDevice",deviceKey), Microsoft.Azure.Devices.Client.TransportType.Http1);

        private const int PULSEIN_PIN = 13; // 33pin GPIO13
        private GpioPin pin;
        public MainPage()
        {
            this.InitializeComponent();

            PulseCount();    // パルス数のカウント
        }

        // パルス数のカウント
        private void PulseCount()
        {
            int PulseCnt = 0;
            float Velocity;
            long Now, StartTime, DiffTime;
            var gpio = GpioController.GetDefault();
            if (gpio == null)
            {
                pin = null;
                return;
            }

            pin = gpio.OpenPin(PULSEIN_PIN);                     // 入力ピンへセット
            pin.SetDriveMode(GpioPinDriveMode.Input);             // inputにする。
            var sw = new System.Diagnostics.Stopwatch();             // ストップウォッチ
            do
            {
                sw.Start();                                         // タイマースタート
                StartTime = sw.ElapsedMilliseconds;
                do
                {
                    Now = sw.ElapsedMilliseconds;
                    DiffTime = Now - StartTime;
                    if (DiffTime >= 1000)                           // 1sec周期
                    {
                        sw.Reset();                                 // ストップウォッチリセット
                        break;                                     // 測定終了
                    }
                    if (pin.Read() == GpioPinValue.High) {       // パルスhigh検出
                        for (; ; )
                        {
                            if (pin.Read() == GpioPinValue.Low)     // パルスlow検出
                            {
                                PulseCnt++;                       // パルス数カウントアップ
                                break;                             // 1pulse検出済みとして終了
                            }
                        }
                    }
                } while (true);
                if (PulseCnt != 0) {
                    Velocity = PulseCnt*0.064f*10f;                  // 0.064は定数、Azure側の処理の入力に合わせて10倍
                }
                else {
                    Velocity = 0;                                   // 風速0m/s
                }
                SendDeviceToCloudMessagesAsync((int)Velocity);     // データの送信()
                PulseCnt = 0;                                      // パルス数のクリア
            } while (true);
        }

        private async void SendDeviceToCloudMessagesAsync(int iVelocity)
        {
            var SendData = new
            {
                DataTimeStamp = DateTime.Now,
                Velocity = iVelocity,                                // 風速データ
	    };
            var messageString = JsonConvert.SerializeObject(SendData);
            var message = new Message(Encoding.UTF8.GetBytes(messageString));
            await deviceClient.SendEventAsync(message);
        }
    }
}


ソースコード解説 

Nos-OS や RTOS では割り込みイベントハンドラを作り、立ち上がりエッジをイベントとして検出し、時間当たりのパルスの入力回数をカウントアップします。
今回は Windows 10 IoT Core で、API が用意されていますので GpioPin Class を使用します。
GPIO の High/Low を Gpio.Read() で連続的に読み出して時間当たりの入力回数をカウントアップします。
High が来たらスタート、Low が来たら1カウントアップして、1秒間カウントしたら1サンプリング終了です。
GPIO を使用する時の API は以下を参照してください。
Windows Dev Center:https://docs.microsoft.com/en-us/uwp/api/windows.devices.gpio

※ C/C++ でマイコンのプログラミングをするときはデータシートを見て使い方を覚えてから、ソースコードを書かなければなりませんが、C# では簡単にコーディングできます。
イベントハンドラや Task ベースの非同期処理を使って書くと良いですが、今回はできる限り簡単に書きました。
ソースコードに出てくる式 Velocity = PulseCnt*0.064f*10f; の0.064は BOX ファンを風速計にあてた時の風速から算出した定数になります。

デバッグの設定

Raspberry Pi 3 の IP を固定し、LAN ケーブルで接続しデバックします。
Visual Studio で以下画面を開き、リモートデバッグする Raspberry Pi 3 の IP アドレスを入力します。

デバッグの設定

※ リモートコンピュータにデバイス名が出てくる場合もあります。

これからの記載内容

Azure IoT Hub で受信してみよう! IoT Hub のメトリックで確認するところまで(※ 7月中に公開予定)

では、乞うご期待。



次回予告
  • Azure Custom Vision Service の紹介



【総合】お問い合わせ

ソリューションに関する全般的なお問い合わせはお気軽にご相談ください。

ピックアップ

セミナー情報
クラウドエンジニアブログ
clouXion
メールマガジン登録