GPSデータロガー構築と Azure IoT Hub での空間分析
部品と材料
| 部品名 | 数量 | 備考 |
|---|---|---|
| Arduino UNO | 1 | GPSデータロガー制御用 |
| Raspberry Pi 2 Model B | 1 | Windows 10 IoT Core 実行用 |
| Adafruit Ultimate GPS Breakout | 1 | 高精度 GPS モジュール |
| 9V バレルジャックコネクター | 1 | 電源接続用 |
| 9V 電池 | 1 | Arduino 用電源 |
| フォトレジスタ (CdS セル) | 1 | 照度測定用 |
| LED (汎用) | 6 | クリア 3個、赤 1個、黄 1個、緑 1個 (衛星測位状態表示用) |
| SparkFun プッシュボタンスイッチ 12mm | 2 | 記録トリガー、モード切替等 |
| スライドスイッチ | 3 | 地物タイプ選択用 (3ビット = 0〜7) |
| 抵抗 10kΩ | 4 | プルアップ/プルダウン用 |
| 抵抗 221Ω | 3 | LED 電流制限用 |
| ハーフサイズ ブレッドボード | 1 | |
| フルサイズ ブレッドボード | 1 | |
| ジャンパーワイヤー | 1式 | |
| SanDisk 16GB microSD カード (アダプター付き) | 2 | データ記録用 |
使用アプリとオンラインサービス
- Microsoft Windows 10 IoT Core
- Microsoft Azure (IoT Hub 等)
- Arduino IDE
- Microsoft Visual Studio 2015
- Google Earth Professional
- Quantum GIS (QGIS)
- Microsoft Windows 10 Enterprise
プロジェクト概要
はじめに
現在のモバイル技術は非常に高度化し、GIS 情報マップはほぼあらゆるデバイスで利用可能になりました。このプロジェクトは、オープンソースハードウェア、モバイルコンピューティング、地理空間技術、クラウドコンピューティングの基礎を子供たちに教える授業教材としても活用できます。
本プロジェクトは以下の 3 パートで構成されます:
- Arduino GPS データロガー
子供たちでも支援があれば、GPS 位置情報、照度、対象物タイプを記録するデバイスを製作できます。屋外に出て、標識、木、公園のベンチなど、決められた物の位置を記録させます。これにより、身の回りの世界への理解と、GIS マップに表示されるデータへの理解が深まります。夜間の公共エリアの照度不足は安全上の懸念事項です。大人の同伴のもと、夜間に照度測定を行い、後で分析できます。 - GIS 可視化と分析
現地で収集した位置情報を地図上に可視化します。空間点補間分析を行い、エリアの照度レベルを推定してマップ上に表示します。 - Windows 10 IoT Core と Azure IoT Hub の活用
GIS 可視化と分析の後、Windows 10 IoT Core と Azure IoT Hub を使ってデータをアップロード・配信します。これにより、現場の数千台のデータコレクター/デバイスからのデータ管理に容易にスケールアップできます。
Arduino GPS データロガー
以下のビデオで Arduino Uno GPS データロガーの概要とデモをご覧いただけます。ソースコードとブレッドボード図は後述します。
主要コンポーネントの詳細
フォトレジスタ
光の明るさを測定するアナログセンサーで、扱いが非常に簡単です。アナログ読み取り値は 0〜1023 ですが、非常に明るい光でない限り 200 以下になることが多いです。デバイス製作時にいくつか測定して期待値を把握しておくとよいでしょう。
- 晴天の直射日光: 約 1000
- 日中の屋外日陰: 約 900
- 夜間の街灯直下: 約 170
microSD スロット
Arduino IDE の ファイル > スケッチ例 > SD > Datalogger に良い例があります。
Adafruit Ultimate GPS
扱いやすい GPS モジュールです。こちらの例に従って Arduino IDE にライブラリをインストールしてください。
衛星測位ステータス LED
水平精度低下率 (HDOP) は GPS から得られる X,Y 位置精度の指標です。HDOP 値が低いほど精度が高いです。GPS が測位できていれば、緯度経度とともに HDOP 値が返されます。詳細は GPS Dilution of Precision を参照してください。
- 赤: 衛星測位なし
- 黄: 測位あり、HDOP > 1.5
- 緑: 測位あり、HDOP ≤ 1.5
バイナリ地物タイプ スライドスイッチ
3つのスライドスイッチで 2進数表現 (基数10で 0〜7) を作ります。左が 2² (4)、中央が 2¹ (2)、右が 2⁰ (1) です。ON/OFF 状態に基づき値を足し合わせ、0〜7 の数値で収集対象の地物タイプを表します。ユーザーがコードの意味を理解していることが理想的です。
例:
OFF OFF OFF = 0 0 0 = 0 = 照度センサー読み取り
OFF OFF ON = 0 0 1 = 1 = 公園のベンチ
OFF ON OFF = 0 1 0 = 2 = 岩
OFF ON ON = 0 1 1 = 3 = ゴミ箱
ON OFF OFF = 1 0 0 = 4 = 木
ON OFF ON = 1 0 1 = 5 = 公衆電話
ON ON OFF = 1 1 0 = 6 = 街灯
ON ON ON = 1 1 1 = 7 = 飲み水栓
ボタン
ボタンを押すたびに、カンマ区切り (CSV) の 1 行が microSD カードの datalog.csv に追記されます。
データ形式:
LATITUDE,LONGITUDE,LIGHT_VALUE,FEATURE_TYPE
- LATITUDE, LONGITUDE: GPS から取得
- LIGHT_VALUE: フォトレジスタのアナログ読み取り値
- FEATURE_TYPE: 3つのスライドスイッチ設定による 0〜7 の値
CSV データ例:
40.77221,-73.97392,105,5
40.77139,-73.97394,60,1
40.77051,-73.97460,150,6
40.77225,-73.97650,25,3
40.77171,-73.97462,43,2
40.77283,-73.975033,54,1
LCD ディスプレイを使わない理由
複数の LED は 1602 LCD と追加ボタンで代替可能でしたが、問題がありました。
- GPS、microSD、1602 LCD のコードを Arduino Uno にコンパイル・書き込み可能でしたが、microSD スロットが不安定になりました。LCD を外すと安定したため、ユーザー通知用に LED を採用しました。Arduino MEGA 等、リソースの多いボードなら GPS + microSD + LCD の共存も可能でしょう。
- 9V 電池は Arduino GPS データロガーには便利ですが、1602 LCD を点灯させると電池寿命が極端に短くなります。必須コンポーネントではないため、LCD は見送りました。
GIS 可視化と分析
GPS ポイントの可視化
CSV 形式の GIS データは地図上で見られなければあまり役立ちません。Arduino GPS データロガーから microSD カードを取り出し、Google Earth Professional がインストールされた Windows 10 PC に挿入します。インストールとライセンスについては こちらを参照してください。テキストファイルを PC にコピーし、テキストエディタで開き、先頭に以下の列見出し行を追加して .CSV として保存します。
LATITUDE,LONGITUDE,LIGHT_VALUE,FEATURE_TYPE
Google Earth Professional の [ファイル] メニューから [インポート...] を選び、CSV ファイルを指定します。オプションを設定して、地物タイプごとに異なるアイコンスタイルを作成し、ポイント位置を表示します。Google Earth Professional 版が必須です。通常版には CSV インポート機能がありません。

Quantum GIS (QGIS) での空間分析
QGIS は人気の無料オープンソース GIS で、インストーラーとチュートリアルは こちら から入手できます。QGIS を使って、GPS 位置の照度センサー属性に対して空間分析を行い、公園などの公共エリアにおける夜間の十分/不十分な照明エリアを特定できます。
- ステップ 1: 評価対象エリアの境界線、遊歩道、その他関連情報を読み込みます。

- ステップ 2: GPS データロガーからの CSV ポイントを QGIS マップに読み込みます。ポイントシンボロジーとラベルを適用して、照度値を視覚的に確認します。

ポイントデータだけを見ても、広いエリアを分析するには不十分です。
- ステップ 3: ポイントデータに対して補間を実行し、既知地点間の値を推定します。補間は、特定地点のデータから未知地点の値を推定する手法です。詳細は こちら を参照してください。

補間により、公園内の照度分布がより明確になります。既知地点での照度測定を増やせば分析精度は向上します。
- ステップ 4: さらに照度測定を行い、QGIS に読み込みます。

- ステップ 5: 拡大データセットで補間を再実行します。

2回目の補間は最初と似たパターンですが、追加ポイントにより詳細が増しています。
Windows 10 IoT Core と Azure IoT Hub の活用
スケールアップ
Arduino GPS データロガーは安価・シンプルで、センサー情報を microSD カードに記録できます。これらを地理的に広く配置して情報収集できますが、それらからの情報管理システムを自前で設計するのは困難です。
Windows 10 IoT Core と Azure IoT Hub をメッセージングシステムの基盤として使えば、デバイス数を数千台規模に容易にスケールアップできます。
まずはこれらの例を試してください
本格的に進める前に、Azure IoT Hub 入門チュートリアル (.NET) を完了することを強くお勧めします。Azure 試用アカウント作成、IoT Hub セットアップ、メッセージ送受信のコアサンプル開発までをステップバイステップで学べます。
また、Azure IoT Hub Device Explorer をダウンロードして、Windows 10 IoT Core デバイスの管理を容易にしてください。
Raspberry Pi 2 で Windows 10 IoT Core
Windows 10 開発機で、Raspberry Pi 2 向け Windows 10 IoT Core をダウンロードし、Windows IoT Image Helper で microSD カードに書き込みます。
microSD を Pi 2 に挿入し、イーサネット接続して起動。開発機の Windows IoT Core Watcher にデバイスが表示されることを確認します。
下図のようにブレッドボードにボタンを接続します (回路図はページ下部参照)。ソースコードへのリンクもページ下部にあります。

データアップロード用ユニバーサル Windows アプリケーション
Visual Studio 2015 で ファイル > 新規作成 > プロジェクト、[空白のアプリ (ユニバーサル Windows)] テンプレートを選択。プロジェクト名を IoTHubClientSendEvent とします。NuGet で Microsoft.Azure.Devices.Client と Newtonsoft.Json を追加。また、[参照の追加] から [Windows IoT Extensions for the UWP] を参照し、Raspberry Pi 2 の GPIO アクセスを可能にします。
MainPage.xaml.cs の冒頭に以下の using 文を追加:
using Windows.Devices.Gpio;
using Newtonsoft.Json;
using Microsoft.Azure.Devices.Client;
using System.Text;
MainPage クラスに以下の変数と定数を追加。deviceId は Azure IoT Hub Device Explorer で設定したデバイス名に合わせてください。
private const int buttonPin = 6;
private GpioPin buttonGPIO;
static DeviceClient deviceClient;
static string deviceId = "MakerChallengeDevice2";
static string uploadFile = "data.csv";
JSON シリアライズ用の evData クラスを MainPage クラス内に追加:
class evData {
public string id { get; set; }
public string data { get; set; }
}
MainPage コンストラクターに以下 2 行を追加。DEVICE_CONNECTION_STRING は Azure IoT Hub Device Explorer で取得した値を設定:
deviceClient = DeviceClient.CreateFromConnectionString("DEVICE_CONNECTION_STRING", TransportType.Http1);
initGPIO();
GPIO 初期化関数を追加:
private void initGPIO() {
var gpio = GpioController.GetDefault();
buttonGPIO = gpio.OpenPin(buttonPin);
if (buttonGPIO.IsDriveModeSupported(GpioPinDriveMode.InputPullUp))
buttonGPIO.SetDriveMode(GpioPinDriveMode.InputPullUp);
else
buttonGPIO.SetDriveMode(GpioPinDriveMode.Input);
buttonGPIO.DebounceTimeout = TimeSpan.FromMilliseconds(50);
buttonGPIO.ValueChanged += buttonPin_ValueChanged;
}
ボタンクリックハンドラーを追加:
private void buttonPin_ValueChanged(GpioPin sender, GpioPinValueChangedEventArgs e) {
if (e.Edge == GpioPinEdge.FallingEdge) {
sendMessageToIOTHub();
}
}
Azure IoT Hub へメッセージ送信する関数を追加:
private static async void sendMessageToIOTHub() {
string myString;
var msg = new evData();
if (File.Exists(uploadFile)) {
myString = System.IO.File.ReadAllText(uploadFile);
} else {
myString = "Just checking in!!";
}
msg.id = deviceId;
msg.data = myString;
var messageString = JsonConvert.SerializeObject(msg);
var message = new Message(Encoding.ASCII.GetBytes(messageString));
await deviceClient.SendEventAsync(message);
}
デフォルトの Debug x86 でコンパイルして動作確認後、ターゲットを Release ARM、配置先を リモート マシン に変更します。

ネットワーク上に Windows 10 IoT Core デバイスがあれば、Visual Studio が検出して配置ターゲットに設定できます。
ヒント: 配置前にプロジェクトを右クリック → [プロパティ] → [アプリケーション] パネルの [パッケージ マニフェスト] ボタン → [パッケージング] タブで [パッケージ名] をわかりやすい名前に (例: IoTHubClientSendEvent) 変更しておくと、Windows 10 IoT Core Web インターフェースでアプリを特定しやすくなります。
[ビルド] メニューから [ソリューションの配置] を実行。配置完了後、Windows IoT Core Watcher でデバイスを右クリック → [Web ブラウザーで開く]。ローカル Administrator でログインし、左メニュー [Apps] → [インストール済みアプリ] ドロップダウンから配置したアプリを選び [Start] をクリック。

Azure IoT Hub からメッセージ受信するユニバーサル Windows アプリケーション
Visual Studio 2015 で新規 C# コンソールアプリケーションプロジェクトを作成。名前を IoTEventHubReceiver とする。NuGet で WindowsAzure.ServiceBus と Newtonsoft.Json を追加。
Program.cs の冒頭に using 文を追加:
using System.IO;
using System.Threading;
using Newtonsoft.Json;
using Microsoft.ServiceBus.Messaging;
IoTEventHubReceiver クラス内に JSON デシリアライズ用クラスを追加:
class evData {
public string id { get; set; }
public string data { get; set; }
}
Azure IoT Hub からメッセージ受信用の変数を追加。IOT_HUB_CONNECTION_STRING は Azure IoT Hub Device Manager で取得:
static string connectionString = "IOT_HUB_CONNECTION_STRING";
static string iotHubD2cEndpoint = "messages/events";
static EventHubClient eventHubClient;
Main() 関数に以下 2 行を追加:
eventHubClient = EventHubClient.CreateFromConnectionString(connectionString, iotHubD2cEndpoint);
SynchMessages();
最後に SynchMessages() と ReceiveMessagesFromDeviceAsync() を追加:
private static async void SynchMessages() {
while (true) {
var d2cPartitions = eventHubClient.GetRuntimeInformation().PartitionIds;
foreach (string partition in d2cPartitions) {
ReceiveMessagesFromDeviceAsync(partition);
}
}
}
private async static Task ReceiveMessagesFromDeviceAsync(string partition) {
var eventHubReceiver = eventHubClient.GetDefaultConsumerGroup().CreateReceiver(partition, DateTime.UtcNow);
while (true) {
EventData eventData = await eventHubReceiver.ReceiveAsync();
if (eventData == null) continue;
string data = Encoding.UTF8.GetString(eventData.GetBytes());
evData d = JsonConvert.DeserializeObject<evData>(data);
StreamWriter writer = new StreamWriter(@"c:\gps\download\" + d.id + "." + DateTime.Now.Year + "." + DateTime.Now.Month + "." + DateTime.Now.Day + "." + DateTime.Now.Hour + "." + DateTime.Now.Minute + "." + DateTime.Now.Second + ".csv");
writer.Write(d.data);
writer.Close();
Console.WriteLine(string.Format("Message received from {0}.\n{1}", d.id, d.data));
}
}
開発ワークステーションに c:\gps\download フォルダを作成し、受信メッセージの保存先とします。
送受信アプリケーションの実行
開発ワークステーションで IoTEventHubReceiver を起動し、コンソール画面が表示されるのを待ちます。次に、Windows 10 IoT Core が動く Raspberry Pi 2 の GPIO に接続したボタンを押し、IoTHubClientSendEvent プログラムを動作させます。ボタンを押すと "Just checking in!" というテキストを含むメッセージが Azure IoT Event Hub に送信されます。開発機のコンソールには以下のように表示されます:
Message received from MakerChallengeDevice2.
Just checking in!
テキストファイルの内容をメッセージとして送信することも可能です (最大 256 KB、Azure IoT Hub の現在の最大メッセージサイズ)。sendMessageToIOTHub() でファイル読み込み・シリアライズ、ReceiveMessagesFromDeviceAsync() でデシリアライズ・ファイル書き込みを行っています。
現在、Windows 10 IoT Core ではコードから絶対パスのファイルアクセスはできませんが、実行ファイルと同じディレクトリのファイルなら参照可能です。ベストプラクティスではありませんが動作します。アプリフォルダにファイルを配置するには、Windows 10 IoT Core Watcher でデバイスを右クリック → [ネットワーク共有を開く] → ローカル Administrator で認証 → 以下のパスを参照:
c$\Data\Users\DefaultAccount\AppxLayouts
配置したアプリ名のフォルダを探し、そこに data.csv という名前で 256 KB 未満のテキストファイルを置きます。サンプルとして緯度、経度、照度、地物タイプを列挙した CSV ファイルが適しています。Raspberry Pi 2 の GPIO ボタンを押すと、コンソールに以下のように表示されます:
Message received from MakerChallengeDevice2.
LAT,LNG,LT,TYP
45.45926,-110.57361,45,6
45.78546,-110.02487,156,3
ファイルアップロードの拡張については、Azure IoT Hub 入門チュートリアル の「次のステップ」セクションに Azure Blob Storage へのファイルアップロード例があります。
まとめ
このプロジェクトでは、シンプルな Arduino GPS データロガーで情報を記録し、収集データを分析し、クラウドで情報管理する一連の流れを実演しました。以下のような拡張が可能です:
- Arduino GPS データロガーでさまざまなセンサータイプの情報を記録
- Arduino デバイスから Wi-Fi、Bluetooth、セルラー経由で直接 Azure にアップロード
- 環境への意思決定に役立つさまざまなタイプの空間分析を実行
- 生データや分析結果を表示するマッピング Web アプリケーションを開発
- Azure Stream Analytics の EventProcessor を使って、IoT Hub 受信データにリアルタイムで対応
ソースコード
- Arduino GPS データロガー: スケッチと配線図 - GitHub
- Azure IoT Hub 例: Windows 10 IoT Core に配置して Azure IoT Hub にメッセージ送信する UWP アプリ - GitHub
- Azure SDK: Azure IoT Device Explorer - GitHub
- Windows 10 IoT Core サンプル: IoT Core 配置用サンプル - GitHub
回路図

GPSDataLogger.fzz

RPi2%20IOT%20Core.fzz
製造プロセス
- Windows 10 IoT CoreとSHT15センサーで高精度な温湿度モニタリング
- Arduinoで温湿度ロガーを作る – DHT11とEthernetシールドでSDカード記録
- ESP8266・Arduino・超音波センサーで作るスマートIoTジャー:リアルタイム中身監視
- 光と音で祝おう:Arduinoで作るDIYバースデープロジェクト
- u-blox LEA-6H 02 GPSモジュール: Arduino & Python 統合ガイド
- Arduino IoT CloudとAlexaでテレビを音声操作:ステップバイステップガイド
- DIYギター高速ピック&ストンプペダル - 3Dプリントモーター駆動ピックの自作
- ESP8266とDHT22で作るWi-Fi気象観測ステーション – ThingSpeak連携
- Azure IoT対応スマートプール制御システム:水温・気温監視と遠隔ポンプ制御
- IoT向けPCB設計の完全ガイド:フレックス基板とHDI基板の活用
- Avnet Silica、Embedded World 2019で最先端AI、IoT、接続ソリューションを展示