前回 ARDUINO MKR WAN 1300 をArduino IDE で使えるように環境構築しましたので
今回は実際にLoRaWANゲートウェイに接続してみます。
先ずは自分が良く使っている福岡市LoRaWAN実証実験に接続します。
(福岡市に在住の皆様限定になってしまいますが、他の接続先でも基本は変わらないと思います。)
Arduino公式ページでLoRaWAN接続用のサンプルプログラムが公開されています。
なお、このサンプルプログラムはOTAAモードでの接続となります。
OTAAとABPの違いはこちらの記事を参考にしてください。
公開されているサンプルプログラム
/* Lora Send And Receive This sketch demonstrates how to send and receive data with the MKR WAN 1300 LoRa module. This example code is in the public domain. */ #include <MKRWAN.h> LoRaModem modem; // Uncomment if using the Murata chip as a module // LoRaModem modem(Serial1); #include "arduino_secrets.h" // Please enter your sensitive data in the Secret tab or arduino_secrets.h String appEui = SECRET_APP_EUI; String appKey = SECRET_APP_KEY; void setup() { // put your setup code here, to run once: Serial.begin(115200); while (!Serial); // change this to your regional band (eg. US915, AS923, ...) if (!modem.begin(EU868)) { Serial.println("Failed to start module"); while (1) {} }; Serial.print("Your module version is: "); Serial.println(modem.version()); Serial.print("Your device EUI is: "); Serial.println(modem.deviceEUI()); int connected = modem.joinOTAA(appEui, appKey); if (!connected) { Serial.println("Something went wrong; are you indoor? Move near a window and retry"); while (1) {} } // Set poll interval to 60 secs. modem.minPollInterval(60); // NOTE: independently by this setting the modem will // not allow to send more than one message every 2 minutes, // this is enforced by firmware and can not be changed. } void loop() { Serial.println(); Serial.println("Enter a message to send to network"); Serial.println("(make sure that end-of-line 'NL' is enabled)"); while (!Serial.available()); String msg = Serial.readStringUntil('\n'); Serial.println(); Serial.print("Sending: " + msg + " - "); for (unsigned int i = 0; i < msg.length(); i++) { Serial.print(msg[i] >> 4, HEX); Serial.print(msg[i] & 0xF, HEX); Serial.print(" "); } Serial.println(); int err; modem.beginPacket(); modem.print(msg); err = modem.endPacket(true); if (err > 0) { Serial.println("Message sent correctly!"); } else { Serial.println("Error sending message :("); Serial.println("(you may send a limited amount of messages per minute, depending on the signal strength"); Serial.println("it may vary from 1 message every couple of seconds to 1 message every minute)"); } delay(1000); if (!modem.available()) { Serial.println("No downlink message received at this time."); return; } char rcv[64]; int i = 0; while (modem.available()) { rcv[i++] = (char)modem.read(); } Serial.print("Received: "); for (unsigned int j = 0; j < i; j++) { Serial.print(rcv[j] >> 4, HEX); Serial.print(rcv[j] & 0xF, HEX); Serial.print(" "); } Serial.println(); }
このプログラムを Arduino IDE の新しいプログラムとしてコピペしてください。
とりあえずこのままコンパイルしてみると当然ながら エラー となります。
(コンパイルは ✔ ボタンをクリックします)
エラーの内容としては
1. MKRWAN.h が無い
2. arduino_secrets.h が無い
3. SECRET_APP_EUI と SECRET_APP_KEY が定義されていない
となります。
1つずつ潰していきます。
1.の MKRWAN.h に関しては MKRWAN library のインストールが必要となります。
MKRWAN library のインストール
スケッチ ⇒ ライブラリをインクルード ⇒ ライブラリを管理 の順にクリックして
とクリックして ライブラリマネージャー を起動します。
ライブラリマネージャーが表示されたら 検索入力欄に [MKRWAN] と入力してください。
以下のように表示が変わりますので
Support library for MKR WAN 1300 をインストールしてください。
2.の arduino_secrets.h に関しては arduino_secrets.h を調べたら
SECRET_APP_EUI と SECRET_APP_KEY を定義しているだけでした。
よって、 #include "arduino_secrets.h" の一行を削除(コメントアウト)して
String appEui = "";
String appKey = "";
のようにappEuiとappKey直接設定するようにしました。
これで 3. のエラーも無くなります。
修正したソースコードは次のようになります。
/* Lora Send And Receive This sketch demonstrates how to send and receive data with the MKR WAN 1300 LoRa module. This example code is in the public domain. */ #include <MKRWAN.h> LoRaModem modem; // Uncomment if using the Murata chip as a module // LoRaModem modem(Serial1); // #include "arduino_secrets.h" // Please enter your sensitive data in the Secret tab or arduino_secrets.h String appEui = "77xxxxxxxxxxxx48"; String appKey = "FFxxxxxxxxxxxxxxxxxxxxxxxxxxxxBB"; void setup() { // put your setup code here, to run once: Serial.begin(115200); while (!Serial); // change this to your regional band (eg. US915, AS923, ...) if (!modem.begin(EU868)) { Serial.println("Failed to start module"); while (1) {} }; Serial.print("Your module version is: "); Serial.println(modem.version()); Serial.print("Your device EUI is: "); Serial.println(modem.deviceEUI()); int connected = modem.joinOTAA(appEui, appKey); if (!connected) { Serial.println("Something went wrong; are you indoor? Move near a window and retry"); while (1) {} } // Set poll interval to 60 secs. modem.minPollInterval(60); // NOTE: independently by this setting the modem will // not allow to send more than one message every 2 minutes, // this is enforced by firmware and can not be changed. } void loop() { Serial.println(); Serial.println("Enter a message to send to network"); Serial.println("(make sure that end-of-line 'NL' is enabled)"); while (!Serial.available()); String msg = Serial.readStringUntil('\n'); Serial.println(); Serial.print("Sending: " + msg + " - "); for (unsigned int i = 0; i < msg.length(); i++) { Serial.print(msg[i] >> 4, HEX); Serial.print(msg[i] & 0xF, HEX); Serial.print(" "); } Serial.println(); int err; modem.beginPacket(); modem.print(msg); err = modem.endPacket(true); if (err > 0) { Serial.println("Message sent correctly!"); } else { Serial.println("Error sending message :("); Serial.println("(you may send a limited amount of messages per minute, depending on the signal strength"); Serial.println("it may vary from 1 message every couple of seconds to 1 message every minute)"); } delay(1000); if (!modem.available()) { Serial.println("No downlink message received at this time."); return; } char rcv[64]; int i = 0; while (modem.available()) { rcv[i++] = (char)modem.read(); } Serial.print("Received: "); for (unsigned int j = 0; j < i; j++) { Serial.print(rcv[j] >> 4, HEX); Serial.print(rcv[j] & 0xF, HEX); Serial.print(" "); } Serial.println(); }
※ appEui と appKey は伏字にしています。
このプログラムをボードに書き込んでシリアルモニターを起動すると
シリアルモニタ
のように表示されます。(一部伏せています)
ここに表示されている
Your device EUI is: a8xxxxxxxxxxxx0b がゲートウェイにデバイスを登録する時に必要になります。
次にLoRaWANゲートウェイにディバイスの登録を行います。
この部分は利用するゲートウェイによって異なります、今回は福岡市LoRaWAN実証実験のゲートウェイを例とします。
Device activation は OTAA モードになります。
DevEUI: はシリアルモニターに表示されたデータを入力します。
AppEUI: 任意の16進数8桁のデータ
Appkey: 任意の16進数16桁のデータ
ここで設定した AppEUI と Appkey をプログラムの
appEui と appKey に設定します。
最後にプログラムをもう一ヶ所変更します。
それはLoRaの周波数の設定です。
LoRaの周波数はヨーロッパ、アメリカ、アジアで異なっているので、日本の周波数に合わせる必要があります。
ソースコードの setup関数内の
if (!modem.begin(EU868)) {
の部分を
if (!modem.begin(AS923)) {
に変更します。
この修正したプログラムを ARDUINO MKR WAN 1300 に書き込んで起動すると、問題が無ければゲートウェイとの通信が始まります。
ARDUINO MKR WAN 1300 の シリアルモニタ
ARDUINO MKR WAN 1300 から送った "abcd" が ゲートウェイに届いているのが確認出来ました。
なお、このサンプルプログラムではシリアルモニタから送ったデータがゲートウェイに送られます。
これで、ARDUINO MKR WAN 1300 で正常に LoRaWANゲートウェイ と通信出来ることが確認出来ました。
実際にはもっと作り込む必要がありますが ARDUINO MKR WAN 1300 が使えるという検証が目的でしたので、その目的は達成できたと思っています。
以下のプログラムが今回の最終形です。
/* Lora Send And Receive This sketch demonstrates how to send and receive data with the MKR WAN 1300 LoRa module. This example code is in the public domain. */ #include <MKRWAN.h> LoRaModem modem; // Uncomment if using the Murata chip as a module // LoRaModem modem(Serial1); // #include "arduino_secrets.h" // Please enter your sensitive data in the Secret tab or arduino_secrets.h String appEui = "77xxxxxxxxxxxx48"; String appKey = "FFxxxxxxxxxxxxxxxxxxxxxxxxxxxxBB"; void setup() { // put your setup code here, to run once: Serial.begin(115200); while (!Serial); // change this to your regional band (eg. US915, AS923, ...) if (!modem.begin(AS923)) { Serial.println("Failed to start module"); while (1) {} }; Serial.print("Your module version is: "); Serial.println(modem.version()); Serial.print("Your device EUI is: "); Serial.println(modem.deviceEUI()); int connected = modem.joinOTAA(appEui, appKey); if (!connected) { Serial.println("Something went wrong; are you indoor? Move near a window and retry"); while (1) {} } // Set poll interval to 60 secs. modem.minPollInterval(60); // NOTE: independently by this setting the modem will // not allow to send more than one message every 2 minutes, // this is enforced by firmware and can not be changed. } void loop() { Serial.println(); Serial.println("Enter a message to send to network"); Serial.println("(make sure that end-of-line 'NL' is enabled)"); while (!Serial.available()); String msg = Serial.readStringUntil('\n'); Serial.println(); Serial.print("Sending: " + msg + " - "); for (unsigned int i = 0; i < msg.length(); i++) { Serial.print(msg[i] >> 4, HEX); Serial.print(msg[i] & 0xF, HEX); Serial.print(" "); } Serial.println(); int err; modem.beginPacket(); modem.print(msg); err = modem.endPacket(true); if (err > 0) { Serial.println("Message sent correctly!"); } else { Serial.println("Error sending message :("); Serial.println("(you may send a limited amount of messages per minute, depending on the signal strength"); Serial.println("it may vary from 1 message every couple of seconds to 1 message every minute)"); } delay(1000); if (!modem.available()) { Serial.println("No downlink message received at this time."); return; } char rcv[64]; int i = 0; while (modem.available()) { rcv[i++] = (char)modem.read(); } Serial.print("Received: "); for (unsigned int j = 0; j < i; j++) { Serial.print(rcv[j] >> 4, HEX); Serial.print(rcv[j] & 0xF, HEX); Serial.print(" "); } Serial.println(); }
今後実際にセンサーからのデータを送信したり、LoRaWANゲートウェイとして TTN に接続する検証を行いたいと思っています。
1件のコメント