Edited at

LoRaWANでIoTプラットフォーム(The Things Network)にデータを上げる方法


イントロダクション

前回の投稿で、LoRaでのIoT(「モノ」と「インターネット」をどう繋ぐのか?)について紹介しました。

今回の記事では一歩進んで、LoRaWANでのIoTについてまとめたいと思います。

使用する機器は前回同様、弊社(株式会社オープンウェーブ)のLoRa IoT スターターキットですが、接続するIoTプラットフォームにはThe Things Network(以降TTN)を使用します。


LoRaとLoRaWAN

この二つは、似て非なるものです。


LoRa

無線の通信規格(物理層の規格)。


LoRaWAN

ノードからIoTプラットフォームまでのプロトコル。

全体像.PNG

2019/2/1

TTNから画像が削除され、他で分かりやすく説明されている画像と差し替えました。

作者:https://www.researchgate.net/profile/Jonathan_De_Carvalho_Silva

上図は、LoRaWANのプロトコルを説明する図です。

LoRaWANの場合、3つの登場人物がいます。


  1. センサー:センサーを設置する機器(ノード、エンドデバイスと表現したりもする。)

  2. ゲートウェイ:デバイスから受け取ったパケットを、ネットワークサーバに上げる機器

  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/


全体像

全体像lorawan.PNG

デバイス: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


使用プログラム

https://github.com/openwave-co-jp/LoRaWANExample


  • LoRaWANExample/lora-arduino/lora-arduino.ino  →デバイス(LoRa mini)

  • LoRaWANExample/liteLoraGW/liteLoraGW.ino   →ゲートウェイLoRa受信(LG01-JP)

  • LoRaWANExample/pythonScript         →ゲートウェイTTN送信(LG01-JP)


手順


TTNの設定

https://www.thethingsnetwork.org/


アプリケーションとデバイスの登録

TTNにアカウントを作成し、アプリケーションの登録と、そのアプリケーションにデバイスを登録します。

アプリケーションは作成後、ABPに変更します。(デフォルトはOTAA)

デバイスを作成した時に得られた、Network Session Key、App Session Key、Device Addressを控えます。

TTN.PNG

)


ゲートウェイの登録

次の点に注意し、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(オーストラリア)のサーバへ接続しています。

そのため、下記の設定では、アジアのルータを設定してください。

TTN_GW設定.PNG


ゲートウェイのプログラミング

ゲートウェイでは、LoRaでデバイスからデータを受信するArduinoのプログラムと、TTNにデータを転送するPythonのプログラムがあります。


Pythonのプログラム

「使用プログラム」のpythonScript内のgwstat.pyを開き、Gateway IDの個所を、TTNに登録したGateway IDで書き換えます。


gwstat.py

# 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に書き込み

LG01-JP.PNG


デバイスのプログラミング

デバイス側では、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の設定を書き換えます。


lorabase.h修正前

// 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 };


lorabase.h修正後

// 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で下記を書き換えます。


lora-arduino.ino

//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に書き込み

LoRamini.PNG


接続確認

TTNにログインし、コンソールでデバイスの画面を開きます。

wan01.PNG

データを受信すると、リストに表示されます。

wan02.PNG

行を展開すると、受信したデータの詳細を見ることができます。

wan03.PNG

Payloadの「48656C6C6F2C20776F726C6421」が、デバイスのmydataになります。

この数字をASCII文字で表現すると、「Hello, world!」になります。


最後に

今回使用したLMiCにはまだ日本のLoRaWANの基準が実装されていないこともあり、「とりあえず日本で飛ばしてよい周波数」で動かしました。

本来であれば、どのチャンネルをどう使うかなどLoRa AllianceのLoRaWANの仕様とARIBのSTD-T108が定める仕様に則って実装する必要があると思います。


注意

プログラミングにはArduino IDEを使用しますが、事前にArduino IDEに次の設定が必要です。

この記事で使用するソースは、使用するハードに依存している部分が大きいため、他のハードとの組み合わせでどうなるかは分かりません。

また、今回使用したプログラムは、LoRaWANの仕様を完全に満たしているわけではありません。(最も簡単なLoRaWANによるデータのアップロードをしているだけです。パケットのカウントや、SN比の算出など、ゲートウェイやデバイスの状態を表す値の取得の実装もダミーで実装しています。)

株式会社オープンウェーブ