Windows 10 IoT Core と Raspberry Pi 3 で Azure に接続できる風速計を IoT Edge デバイス化してみよう!
こんにちは! 今泉 正です。
今回は、風速計から GPIO (General Purpose Input/Output) でパルスを取り込んでパルス数を計算し、IoT Hub へ風速を送信するためのソースコードを書きます。
ソースコード書いてみよう!
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 のイメージのみをダウンロードすることも可能です。
https://developer.microsoft.com/ja-jp/windows/downloads/windows-10-sdk
Windows 10 (Windows 10 IoT Core 含む) アプリを開発するために、上記ページより、インストールしてください。
・ファイル>新規プログラムの作成>新しいプロジェクト>Visual C#>Windows ユニバーサル>空白のアプリ(ユニバーサル Windows)
・ソリューションエクスプローラー>参照>参照の追加>参照マネージャー
・参照マネージャー>Universal Windows>拡張>Windows Desktop Extensions for the UWP (最新版を推奨)
・ソリューションエクスプローラー>NuGet パッケージの管理
・Microsoft.Azure.Device.Client を選択
・Microsoft.NetCore.UniversalWindows.Platform を選択
・Newtonsoft.Json を選択
・以下のように3種類がインストールできていれば NuGet の取得完了です。
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月中に公開予定)
では、乞うご期待。