Arduino MKR WANで雨量計をLoRaWAN化!自宅の降雨データをTTNで観測してみた話
はじめに
どうも、皆さん!
最近、家の周りでいきなり土砂降りになることが増えて、「うちの庭、今どれくらい雨降ってんだろ?」って気になること、ありませんか?
そこで思いついたのが、「自宅の降水量をリアルタイムで計測して、長距離無線でデータを飛ばせたら面白そう!」ということ。
せっかくなら、今話題の省電力長距離無線LoRaWANを使ってみたい!
というわけで今回は、Arduino公式のLoRaWANボード**「MKR WAN 1310」と、そこらで手に入る「雨量計」**を組み合わせて、降水量データをThe Things Network (TTN) に送信するまでの奮闘記をまとめてみました。
この記事が、これからLoRaWANで何か作ってみたいと思っているあなたの、最初の一歩を後押しできれば嬉しいです! 🚀
今回作るシステムの全体像
こんな感じのシステムを目指します。
- ☔ 雨が降ると、転倒ます型の雨量計が「カタンッ」と倒れて信号を出す。
- 📟 我らがMKR WAN 1310が、その「カタンッ」を健気にカウント。
- 📡 数分おきに、カウントした数値をLoRaWANの電波に乗せて送信!
- 🌐 The Things Network (TTN) のゲートウェイがデータを受信し、クラウドへ送る。
- 💻 TTNの管理画面で、受信したデータを「降水量(mm)」に変換してニヤニヤ眺める。
冒険のパーティ(用意するもの) 🛠️
ハードウェア
-
Arduino MKR WAN 1310 (または1300)
- 安心と信頼のArduino公式ボード。LoRaWANの心臓部です。
- 付属のアンテナを絶対に接続するのを忘れないで! これ、本当に大事。
-
転倒ます型雨量計
- よくあるウェザーステーションの部品です。仕組みは超シンプルで、「カタン」と倒れると一瞬だけ電気が流れるただのスイッチ。
-
Micro USBケーブル
- プログラムを書き込んだり、電源供給に使います。
-
ジャンパーワイヤー
- 雨量計とボードを繋ぐ命綱。
ソフトウェア & サービス
-
Arduino IDE
- 我らが城、開発の拠点です。ボードとライブラリの準備が必要(後で解説!)。
-
The Things Network (TTN) のアカウント
- 無料で使えるLoRaWANネットワークサーバー。これがないと始まりません。アカウントを作っておきましょう!
- The Things Network
さっそく作ってみよう!
Step 1: ハードウェアの接続(驚くほど簡単)
まずは、雨量計をMKR WANに接続します。
配線はめちゃくちゃシンプル! 雨量計から出てる2本の線を、ボードにプスッと挿すだけ。
- 雨量計の片方の線 → MKR WAN の
D1ピン - 雨量計のもう片方の線 → MKR WAN の
GNDピン
たったこれだけ! 電子工作が苦手な人でも安心ですね👍
Step 2: The Things Network (TTN) の設定(データの受け皿作り)
次に、データの受け皿となるTTNの設定をします。ここがLoRaWANプロジェクトの最初の山場かもしれません。でも大丈夫、一つずついきましょう。
- TTNのコンソールにログインし、自分の住んでいる地域に近いリージョン(例:
Europe 1など)を選びます。 - "Go to applications" をクリックして、"+ Create application" で新しいアプリを作ります。名前は好きなものでOK。
- 作ったアプリの中で、"+ Register end device" をクリックして、今回の主役であるMKR WANを登録します。
-
"Enter registration data manually" を選び、以下の項目を入力します。
-
Frequency plan:
AS923-1を選びましょう。(日本で使う周波数帯です) -
LoRaWAN version:
MAC V1.0.2を選択。 -
Activation mode:
Over-the-air activation (OTAA)を選択。
-
Frequency plan:
- デバイスを登録すると、
AppEUIとAppKeyが自動で生成されます。この2つの呪文は後でArduinoのコードに書き込むので、どこかにメモしておきましょう📝
DevEUI は後でボード自身から取得するので、今は空っぽのままで大丈夫です。
Step 3: Arduino IDEの準備とプログラミング
いよいよコーディングの時間です!
準備
まずはArduino IDEに、MKR WANと会話するための準備をさせます。
-
ボード情報のインストール:
- IDEのメニューから「ツール」 > 「ボード」 > 「ボードマネージャ」を開きます。
- 検索窓に
Arduino SAMD Boardsと入力してインストール。
-
専用ライブラリのインストール:
- 「ツール」 > 「ライブラリを管理」を開きます。
-
MKRWANを検索してインストール。
コード
さあ、以下のコードをArduino IDEに貼り付けてください。MKRWANライブラリのおかげで、思ったよりスッキリ書けます。
#include <MKRWAN.h>
// --- センサー設定 ---
const int RAIN_PIN = 1; // 雨量計はD1ピンに接続
volatile unsigned long tipCount = 0; // 雨の「カタン」を数えるカウンター
// ★★★ここが超重要!★★★
// あなたの雨量計が1回倒れると何mmの降雨量になるか、調べて書き換えてください。
// 製品の仕様書(データシート)に書いてあるはずです。
const float MM_PER_TIP = 0.2794;
LoRaModem modem;
// --- TTNの呪文 ---
// Step2でTTNからコピーした値をここに貼り付け!
String appEui = "YOUR_APP_EUI";
String appKey = "YOUR_APP_KEY";
// 「カタン」を検知した瞬間に呼ばれる関数(割り込み処理)
void countPulse() {
// チャタリング(物理的な振動による誤作動)防止のためのおまじない。
// 短い間隔(200ミリ秒以内)での連続パルスは無視します。
static unsigned long last_interrupt_time = 0;
unsigned long interrupt_time = millis();
if (interrupt_time - last_interrupt_time > 200) {
tipCount++;
}
last_interrupt_time = interrupt_time;
}
void setup() {
Serial.begin(115200);
// シリアルモニタが開くまで待機
while (!Serial);
// 雨量計を接続したピンを、内部プルアップ付きの入力モードに設定
pinMode(RAIN_PIN, INPUT_PULLUP);
// D1ピンの電圧が下がった瞬間(FALLING)にcountPulse関数を呼び出す、という割り込みを設定
attachInterrupt(digitalPinToInterrupt(RAIN_PIN), countPulse, FALLING);
// LoRaモデムを初期化
if (!modem.begin(AS923)) {
Serial.println("Failed to start module");
while (1);
};
Serial.print("Your module version is: ");
Serial.println(modem.version());
// ★重要★ ここで表示されるDevEUIを、後でTTNにコピペします!
Serial.print("Your device EUI is: ");
Serial.println(modem.deviceEUI());
// TTNへJoinリクエスト(「仲間に入れて!」とお願いする感じ)
int connected = modem.joinOTAA(appEui, appKey);
if (!connected) {
Serial.println("Something went wrong; are you indoor? Move near a window and retry");
while (1);
}
// 送信間隔を設定 (TTNのルールを守るため、ちょっと長めに)
// 300000ミリ秒 = 5分
modem.minPollInterval(300000);
}
void loop() {
Serial.println("よし、データを送る準備だ...");
// 他の処理と衝突しないように、一瞬だけ割り込みを止めて安全に値を読み取る
noInterrupts();
unsigned long currentCount = tipCount;
tipCount = 0; // 送信したらカウンターはゼロに戻す
interrupts();
// 送信するデータ(ペイロード)を作成
byte payload[2];
// カウント数を2バイトのデータに変換(最大65535カウントまでOK)
payload[0] = (currentCount >> 8) & 0xFF; // 上位バイト
payload[1] = currentCount & 0xFF; // 下位バイト
// データ送信!
int err = modem.beginPacket();
if (err > 0) {
modem.write(payload, sizeof(payload));
err = modem.endPacket(false); // falseは「返事はいらないよ(Unconfirmed)」という意味
if (err > 0) {
Serial.println("データ送信成功!");
} else {
Serial.println("あれ?データの送信に失敗したみたい...");
}
} else {
Serial.println("パケットの準備に失敗しました。");
}
// 5分待機。この間に雨が降れば、tipCountはどんどん増えていきます。
delay(300000);
}
コードを貼り付けたら、appEui と appKey、そして一番大事な MM_PER_TIP の値を自分のものに書き換えるのを忘れずに!
Step 4: 動作確認と最後の仕上げ
- MKR WANにアンテナを繋いで、PCにUSBで接続します。
- Arduino IDEでコードを書き込みます。ドキドキ…。
-
シリアルモニタを開きましょう(通信速度は
115200に設定)。 -
Your device EUI is: XXXXXXXXXXXXXXXXと表示されますね?このEUIをTTNのデバイス設定画面にコピペします。これがMKR WANの固有IDです。 - すべてがうまくいけば、シリアルモニタに
データ送信成功!と表示されるはず。やった!🎉
Payload Formatterでデータを「翻訳」してもらおう
このままだと、TTNには 00 01 みたいな謎の16進数データが届くだけ。これじゃ人間には何のことかサッパリわかりません。
そこで、TTNのPayload Formatterという超便利な機能を使って、このデータを意味のある数値(降水量)に「翻訳」してもらいましょう。
- TTNのアプリケーション画面で "Payload formatters" > "Uplink" を選択します。
-
Formatter type で
Javascriptを選び、以下のコードを貼り付けます。
function decodeUplink(input) {
// ArduinoコードのMM_PER_TIPと同じ値にすること!
var MM_PER_TIP = 0.2794;
// 2バイトのデータを1つの数値に戻す魔法
var count = (input.bytes[0] << 8) | input.bytes[1];
// 降水量を計算
var rainfall = count * MM_PER_TIP;
// 整形して返す
return {
data: {
count: count,
rainfall_mm: rainfall
},
warnings: [],
errors: []
};
}
これを設定しておくと、TTNの "Live data" 画面で rainfall_mm: 0.28 のように、計算済みの降水量が表示されるようになります。これが動いた瞬間は、ちょっと感動しますよ!
ハマりどころと先輩からのアドバイス
-
アンテナは絶対につなぐこと!
- これ、基本ですが意外と忘れがち。アンテナなしで送信すると、最悪モジュールが壊れることもあるのでマジで注意です。
-
MM_PER_TIPの値は命!- この値が間違っていると、全くデタラメな降水量になってしまいます。お使いの雨量計の仕様書を穴が開くほど確認しましょう。
-
TTNのフェアユースポリシーを忘れずに
- TTNは無料で使える神サービスですが、「データを送りすぎないでね」というルールがあります。1日の送信時間やデータサイズに制限があるので、送信間隔は数分おきにするのがマナーです。
おわりに
無事に、自宅の雨量データをLoRaWANで飛ばすことができました!
これで、いつどれくらい雨が降ったのかが手軽に記録できます。このデータをグラフ化したり、一定量を超えたらLINEに通知したり…なんて夢も広がりますね。
今回は雨量計だけでしたが、これに風速計や温湿度センサーも追加して、自分だけの本格的なIoT気象台を作るのも面白そう。
皆さんもぜひ、LoRaWANを使ったIoT工作に挑戦してみてください!
最後まで読んでいただき、ありがとうございました!