イントロダクション
前回の投稿で、LoRaでのIoT(「モノ」と「インターネット」をどう繋ぐのか?)について紹介しました。
今回の記事では一歩進んで、LoRaWANでのIoTについてまとめたいと思います。
使用する機器は前回同様、弊社(株式会社オープンウェーブ)のLoRa IoT スターターキットですが、接続するIoTプラットフォームにはThe Things Network(以降TTN)を使用します。
LoRaとLoRaWAN
この二つは、似て非なるものです。
LoRa
無線の通信規格(物理層の規格)。
LoRaWAN
ノードからIoTプラットフォームまでのプロトコル。
2019/2/1
TTNから画像が削除され、他で分かりやすく説明されている画像と差し替えました。 作者:https://www.researchgate.net/profile/Jonathan_De_Carvalho_Silva上図は、LoRaWANのプロトコルを説明する図です。
LoRaWANの場合、3つの登場人物がいます。
- センサー:センサーを設置する機器(ノード、エンドデバイスと表現したりもする。)
- ゲートウェイ:デバイスから受け取ったパケットを、ネットワークサーバに上げる機器
- ネットワークサーバ:IoTプラットフォーム(ここにデータが集まる。)
LoRaが利用されている部分は、センサーとゲートウェイの間です。(PHY Layer→物理レイヤのLoRa)
LoRaWANは、センサー、ゲートウェイ、ネットワークサーバの一連のプロトコル全体です。
ゲートウェイはカプセル化して転送(Packet Forward)するだけです。
ネットワークサーバがTTNです。
私はセンサーとネットワークサーバを直接結ぶ赤い矢印この層をLoRaWANだととらえています。
アプリケーションから見れば、センサーとネットワークサーバが繋がっているように見えるという状態です。(ゲートウェイは単なる中継者)
LoRaWANの良いところ
LoRaを使ってIoTをするときと比べると、登場人物は同じで、役割も変わりません。
ではLoRaWANのメリットは、何でしょうか?次の二つが大きいと思います。
通信の暗号化
LoRaWANでは、デバイスとバックエンドの通信が暗号化されています。デバイスからの電波が傍受されても、傍受者はデータは読み取れません。
デバイス(ノード)毎にデータを管理
Thing Speakではチャネル毎にデータを管理していました。(複数のデバイスから一つのチャネル宛にデータを投げると、見分けがつきません)
LoRaWANでは、デバイスごとにEUIと呼ばれるIDを管理し、デバイス単位のより細かいデータの管理が可能です。
The Things Network(TTN)とは
EUでLoRaWANの草分け的存在で、LoRaWANのことを調べるとだいたいここにたどり着きます。
TTNではバックエンドを誰でも使えるように公開しています。
世界初のクラウドソーシング型IoTネットワーク
オランダの首都アムステルダムでは、2015年8月、世界で初めて、クラウドソーシングによるIoT向けネットワークの構築に取り組む『The Things Network』を創設。有志の市民や地元企業らが、IoT向け無線通信規格LoRaWANに準拠するゲートウェイを合わせて10台購入し、それぞれの住宅やオフィスに設置。
わずか6週間で、アムステルダム市内にIoTネットワークを張り巡らせることに成功した。
引用:http://news.mynavi.jp/news/2015/11/14/244/
全体像
デバイス:LoRa Mini
ゲートウェイ:LG01-JP
デバイスの固定文字列「Hello, world!」を、LoRaWANプロトコルでTTNへ送信します。
使用ハードウェア
- Dragino社のLoRa IoT スターターキット
- Dragino LG01-JP:LoRaゲートウェイ
- Dragino LoRa mini:LoRaノード
使用ソフト
- Arduino IDE(1.6.13)
- Python 2.7(LG01-JPにインストールされている)
- TeraTerm等ターミナルのソフト
- WinSCP等SCPの使えるソフト
- Arduino用LMiCのライブラリ(下記をダウンロードして、Arduino IDEのライブラリにインクルードしておく)
https://github.com/matthijskooijman/arduino-lmic
使用プログラム
- LoRaWANExample/lora-arduino/lora-arduino.ino →デバイス(LoRa mini)
- LoRaWANExample/liteLoraGW/liteLoraGW.ino →ゲートウェイLoRa受信(LG01-JP)
- LoRaWANExample/pythonScript →ゲートウェイTTN送信(LG01-JP)
手順
TTNの設定
アプリケーションとデバイスの登録
TTNにアカウントを作成し、アプリケーションの登録と、そのアプリケーションにデバイスを登録します。
アプリケーションは作成後、ABPに変更します。(デフォルトはOTAA)
デバイスを作成した時に得られた、Network Session Key、App Session Key、Device Addressを控えます。
)
ゲートウェイの登録
次の点に注意し、TTNでゲートウェイを作成します。
- 予めLG01-JPにTeraTerm等でログインし、MACアドレス※1を控えておきます
- TTNでゲートウェイの登録を行います
- 「I'm using the legacy packet forwarder」を選択した上で作成します
- Gateway IDはLG01-JPのMACアドレスを上3桁、FF、FF、下三桁で登録します
- 例:MACアドレス「AA BB CC 11 22 33」の場合「AA BB CC FF FF 11 22 33」となる
- 他は適宜設定します※2
※1:MACアドレスについて、LG01-JPには複数あります。(WiFiと有線の口ですね)
WiFiと有線のどちらのMACアドレスを使うのか?という疑問が出てくるかと思いますが、実はどちらでも構いません。
Pythonのプログラムの項でもGateway IDを使うのですが、ハードから直接MACアドレスを取得したりはしません。
多数のゲートウェイを設置する場合には、この辺を自動で設定する必要があります。
※2:ゲートウェイの接続先ルータの設定について。
ゲートウェイのプログラミングでは、現在router.au.thethings.network(オーストラリア)のサーバへ接続しています。
そのため、下記の設定では、アジアのルータを設定してください。
ゲートウェイのプログラミング
ゲートウェイでは、LoRaでデバイスからデータを受信するArduinoのプログラムと、TTNにデータを転送するPythonのプログラムがあります。
Pythonのプログラム
「使用プログラム」のpythonScript内のgwstat.pyを開き、Gateway IDの個所を、TTNに登録したGateway IDで書き換えます。
# change your gateway ID(from 0xA8 to 0xD4)
head = chr(1) \
+ chr(random.randint(0,255)) \
+ chr(random.randint(0,255)) \
+ chr(0) \
+ chr(0xA8) \
+ chr(0xAA) \
+ chr(0xAA) \
+ chr(0xFF) \
+ chr(0xFF) \
+ chr(0xAA) \
+ chr(0xAA) \
+ chr(0xD4)
書き換えたgwstat.py含み、pythonScript内のファイルとフォルダを、LG01-JPの下記のディレクトリに配置します。(WinSCP等で可能です。dataディレクトリは作成してください。)
/mnt/mtdblock3
├─data
├─base64.py
└─gwstat.py
Arduinoのプログラム
「使用プログラム」のliteLoraGW.inoを、Arduino IDEで開きます。
→LG01-JPに書き込み
デバイスのプログラミング
デバイス側では、LMiCライブラリの修正とデバイス情報の設定が必要になります。
LMiCライブラリの修正
LMiCとは、IBMが作成した暗号化を含めたLoRaのMACプロトコル→LoRaMACのライブラリです。(LoraMac in Cの略)
LoRaWANではLoRaMACを使用しているため、デバイスはLoRaMACに準拠してコーディングする必要があります。下記サイトがLMiCのサイトですが、LoRa WAN in Cとなっています。LoRaMAC=LoRaWANのような流れがあるように思われますね。ファイル名は今のところlmicのままです。
https://www.research.ibm.com/labs/zurich/ics/lrsc/lmic.html
これをArduinoで使えるようにしたものが「使用ソフト」に挙げたArduino用LMiCのライブラリです。
2017/3現在のLMiCライブラリ(v1.5ベース)は、EUとUS基準の無線周波数の設定が用意されています。そのまま日本では使えないので、とりあえず簡単に日本で使っても良い設定に変更します。
Arduino IDEを通常通りインストールすると、インクルードしたライブラリは\Documents\Arduino\librariesに配置されます。
\Documents\Arduino\libraries\arduino-lmic-master\src\lmic\lorabase.hを開き、EUの設定を書き換えます。
// Default frequency plan for EU 868MHz ISM band
// Bands:
// g1 : 1% 14dBm
// g2 : 0.1% 14dBm
// g3 : 10% 27dBm
// freq band datarates
enum { EU868_F1 = 868100000, // g1 SF7-12
EU868_F2 = 868300000, // g1 SF7-12 FSK SF7/250
EU868_F3 = 868500000, // g1 SF7-12
EU868_F4 = 868850000, // g2 SF7-12
EU868_F5 = 869050000, // g2 SF7-12
EU868_F6 = 869525000, // g3 SF7-12
EU868_J4 = 864100000, // g2 SF7-12 used during join
EU868_J5 = 864300000, // g2 SF7-12 ditto
EU868_J6 = 864500000, // g2 SF7-12 ditto
};
enum { EU868_FREQ_MIN = 863000000,
EU868_FREQ_MAX = 870000000 };
// Default frequency plan for EU 868MHz ISM band
// Bands:
// g1 : 1% 14dBm
// g2 : 0.1% 14dBm
// g3 : 10% 27dBm
// freq band datarates
enum { EU868_F1 = 923200000, // g1 SF7-12
EU868_F2 = 923400000, // g1 SF7-12 FSK SF7/250
EU868_F3 = 923600000, // g1 SF7-12
EU868_F4 = 923800000, // g2 SF7-12
EU868_F5 = 924000000, // g2 SF7-12
EU868_F6 = 924200000, // g3 SF7-12
EU868_J4 = 924600000, // g2 SF7-12 used during join
EU868_J5 = 924800000, // g2 SF7-12 ditto
EU868_J6 = 925000000, // g2 SF7-12 ditto
};
enum { EU868_FREQ_MIN = 920600000,
EU868_FREQ_MAX = 928000000 };
※上記は、複数チャンネルのある環境(923.2MHz~925MHzの9チャネル)を想定した設定です。送信する際、チャネルを切り替えながら送信します。LG01-P-JPのプログラムは923.2MHzの1チャネルのみでコーディングしています。(F2~J6のチャネルで送信しているデータは受信できません)
デバイスのプログラミング
「使用プログラム」のlora-arduino.inoを、Arduino IDEで開きます。
「アプリケーションとデバイスの登録」で控えたNetwork Session Key、App Session Key、Device Addressで下記を書き換えます。
//ttn
static const PROGMEM u1_t NWKSKEY[16] = { 0x19, 0x7C, 0x79, 0x8E, 0x6D, 0xDE, 0xEB, 0xA6, 0x92, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0FF, 0xFF };
// LoRaWAN AppSKey, application session key
// This is the default Semtech key, which is used by the prototype TTN
// network initially.
//ttn
static const u1_t PROGMEM APPSKEY[16] = { 0x07, 0x8C, 0xB1, 0x4F, 0x1E, 0xAD, 0x39, 0x4A, 0x99, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0FF, 0xFF };
// LoRaWAN end-device address (DevAddr)
// See http://thethingsnetwork.org/wiki/AddressSpace
//ttn
static const u4_t DEVADDR = 0x2600FFFF;
このソース内でmydataという変数が、送信するデータです。
→LoRa miniに書き込み
接続確認
Payloadの「48656C6C6F2C20776F726C6421」が、デバイスのmydataになります。
この数字をASCII文字で表現すると、「Hello, world!」になります。
最後に
今回使用したLMiCにはまだ日本のLoRaWANの基準が実装されていないこともあり、「とりあえず日本で飛ばしてよい周波数」で動かしました。
本来であれば、どのチャンネルをどう使うかなどLoRa AllianceのLoRaWANの仕様とARIBのSTD-T108が定める仕様に則って実装する必要があると思います。
注意
プログラミングにはArduino IDEを使用しますが、事前にArduino IDEに次の設定が必要です。
- Dragino向けの設定をしておく必要があります。
http://www.ibeacondo.com/download/LG01_LoRa_Gateway_Manual_JP.pdf - 次のライブラリを検索してインクルードしておく必要があります。
- 「LoRa」(LoRaライブラリ)
この記事で使用するソースは、使用するハードに依存している部分が大きいため、他のハードとの組み合わせでどうなるかは分かりません。
また、今回使用したプログラムは、LoRaWANの仕様を完全に満たしているわけではありません。(最も簡単なLoRaWANによるデータのアップロードをしているだけです。パケットのカウントや、SN比の算出など、ゲートウェイやデバイスの状態を表す値の取得の実装もダミーで実装しています。)