LoRaWAN をつかってみよう!? (2021.1 版)

会社に LoRaWAN の Getaway(GW) をおいて基地局にしてみました。TTN(the things network) につないでいるので誰でも自由に使うことが可能（原理的には）です。試行錯誤した結果、まぁ使えるよねというところまで来たのでちょっとした記事を書いておきます。

# LoRaWAN(TTN) は誰でも自由に使えるよ
もし、運よくTTNに参加しているGW(基地局)が近くにあれば、LoRaWAN のデバイスさえあれば自分で GW もってなくても使えるでしょう。なんとなく、いろんな人のレポートを見ていると簡易 GW をたてて実験している人が多いので GW が必要かという気になりますが、実は必要ありません。

GW が充実していれば、例えばその市内では LoRa のデバイスは使い放題(語弊があるけど)ということになります。LoRa の性質上それほど多くの情報をやりとりできませんが、オープンな草の根ネットワーク・インフラとして他の通信インフラとは一線を画します。地域コミュニティと相性がよさそうです。

#TL;DR
ちかくに TTN に参加している GW があれば気軽に LoRaWAN に対応できます。心ある人は安くて技適と LBT に対応した GW を買って地域に貢献しましょう。

ということをいか延々と書いてます。

## ゲートウェイ普及がカギ
GW が増えればご利益が増えそうです。現在使っているものは、秋月で KiWi Technology の 8ch サーバ(TLG2901B-J01S) なるものを購入しました。これは高価なのでお勧めしません。日本で GW を購入し使うとなればポイントは技適を通っているという事と LBT に対応していることですね。

技適に通っているという意味は製造元がちゃんとシールをはってないといけないみたいです。技適の検索で OK しているだけだったり、自分でシール貼ってもダメ。中間的な輸入業者がシール貼るのもダメ見たい。
参考：twitter
https://twitter.com/SgkSsci/status/1178875342380908544

## LBT(Listen Before Talk) にも注意
日本の法律的には送信前にはキャリアセンスをして送信されていないこと（いまから送るチャネルが使われていないこと）を確認しないと送れないみたいです。Listen Before Talk (LBT) と略されたりします。（しらないで使ってたのは、、、やばいです）

LBT については情報を展開してくれている人がいます。ありがとう。
https://qiita.com/tanupoo/items/18803245cb6130095729

個人的には法律的に解除されても LBT 入れた方がいい気がするよ。だれかの送信処理を邪魔するという事だからね。

最新の LMIC では対応しているので Arduino で送信する分には大丈夫。（LMIC を最新にしましょう。というか mcci という会社が提供している LMIC  https://github.com/mcci-catena/arduino-lorawan/ を使いましょう)。興味のある人はソースを読んでください。結構面白いと思います。

RadioHead で直接送信しちゃうと LBT 入ってません(たぶん)。あと、GW も LBT 入りとそうでないのがあります。購入の時は注意しましょう。

## TTN の GW
The Things Indoor Gateway が 70€ 程度の値段でよさげです。技適も通って LBT にも対応しているみたいです(確証があるわけではない。あくまでカタログを見て)。海外の RS で買えるみたいなのですが、技適マークがちゃんとつい来るか？ほんとに LBT 対応しているのかは?マーク。だれか人柱で購入してください。実験的に技適を通すということが可能になったので、１年間は試験的に運用できるはず（総務省？に拒否されなければ）。

追補：技適のデータベースにはなかったので、現時点(2021.1)で技適なさそうです。CPU はESP8266。GW 買う側からすると SX1302 対応で $100 切るAS923JP(LBT 対応) の GW がどっかから出てくるの待ちかな、、、

## GW の2freq (923.2MHz と 923.4MHz)
日本で使う分には GW の最低限のラインは決められた、923.2MHz と 923.4MHz に対応している必要があります。LoRaWAN™ 1.1 Regional Parameters を読むと詳細がわかります。じゃ、LoRa Arudino の類が２つあれば GW が形成できるのかというとさにあらず。DR0 から DR5 まで受けることができる必要があります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99921/125e0d86-efbc-1a2c-f012-563d992c51e2.png)
(LoRaWAN™ 1.1 Regional Parameters から引用。赤線は私が追加）

そのため、SX1301 とか SX1308 とかちゃんとマルチチャネル？で受信することができるチップを搭載した GW が必要になります。LoRaWAN に参加するには OTAA で JoinRequest を送出するのが望ましい（と私は考えています）のですが、GW 側でそれをちゃんと受けて、返答してくれる必要があるわけです。返答は GW じゃなくてそのネットワーク(例えば TTN)が答えてくれます。

## SX1301 と LBT 
どうも SX1301 はマルチチャネルで受信は出来ても LBT は出来ないようなのです。送信するときにキャリアセンスをすればよさそうなものですが、それが出来ないみたいです。世の中には LBT できる GW とできない GW があるので注意が必要です。LBT ができる GW で詳しい資料があるのを見つけました。 embit s.r.l. 社の EMB-LR1301-mPCIe で（技適は通ってない）ブロックダイアグラムはこんな感じ(製品 pdf から引用)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99921/5d8cc818-2684-fa93-e9fa-3b6598c1af01.png)

SX1301 を使っているのですが、LBT のチェックには SX1272 を使ってます。ここで LBT に対応するみたいです。SX1272 の前段（ホスト側）にFPGA が入ってます。これは　Lattice のチップでこのチップがキャリアセンスをしてくれるようです。実際に Semtech 社の lora_getway のソース(github にある)をみると FPGA 用の hex ファイルが置いてあります(HDL のソースはない)。

これって、SPI インタフェースだから、FPGA でなくてもよさそうです。参考までに書くと私が購入した kiwi の装置は TLM922S-P01A というモジュールが入っていて、Cypress S6E1C32 が SX1272 をコントロールしていて LBT にも対応しているみたいです。

逆に LBT できないのは SX130x + SX1257 x2 みたいな構成のもの（う～んできそうだけど出来ないと言っている。真偽はいずれ調べる）で本家 Semtech の PicoCell Gateway などは明確に LBT できないといってます。あと will127534 さんが詳しくコメントしています。

https://github.com/will127534/LoRa-concentrator/issues/16

ついでにかくと SX1308 もだめっぽそう。(DM_Indoor Pico Gateway_0627という製品が SX1308 をつかっているが、additional SX1276 for LBT and background scan と書かれているのが根拠。

### SX1302 と SX1262 と LBT 
どうやら SX1262 になると LBT をサポートしているみたいです。であらためて、semtech の lora_gateway のソースを読むと、どうやら FPGA + SX1272 は送信用ではなく単純に受信用です。LBT のチェック対象の周波数を複数（たとえば 8chとか）書き込むとその周波数に対して、常時監視して最後に空きだった時間を記録するみたいです。その情報を見てソフトは送信すべきかどうかを決定します。実際の送信は SX1301 経由で行っているみたいでした。常時監視のために FPGA が必要であるみたいです。まぁソフトでもできそうですが、常にやってないといけないのでたいへんということみたいですね。

あと、SX1302 が対応しているようです。

https://www.mouser.jp/new/semtech/semtech-sx1302-gateways/

GW なら SX1302 なので今後発売される SX1302 のチップが入ったGWは LBT 対応になりそうです。

ソースも詳しくは見てないけど LBT という記述があり、以前あった FPGA の hex はなくなっています。
https://github.com/Lora-net/sx1302_hal

# The Things Network
The Things Network 略してTTN。https://www.thingsnetwork.org というコミュニティをつくって LoRaWAN の普及を目指しているようです。おそらく、同じ人たちが運営している https://thethingsindustries.com/ ってのもあって、こちらは .com が示す通り企業。明確に非営利・営利をわけてます。えらい。

この前者の TTN に参加すれば、オープンなネットワークに気軽に参加できるわけです。通信料を気にしなくていいのが魅力ですね。その分、草の根ネットワークに支えられているわけですが。

## なんちゃって GW を立ててみた
最初、Dragino の LG01 で、次にラズベリパイ用の HAT でなんちゃって GW をたてて遊んでいました。前述のように GW は2つの周波数と複数の DR に対応しなければならないので厳密な意味での GW ではありません。まぁ普及の過渡期にはそういう GW もあってもいいのかなとも思っています。

で、当然 OTAA できないので　ABP でテストをしていました。

## TTN の理念？
このネットワークの理念を私が解釈するところではオープンな草の根ネットワークです。それを考えると OTAA に対応した GW を設置しないとで十分にその特性を生かし切れていないということにふと気が付きました。なんちゃってGWの構成だと、 Device が GW が何で待ち受けているかを明確に知らないといけません。つまり GW 運営者となかよくないとデバイスを参加させられません。誰でも気軽に、、、とはいかなくなります。

その上、特定の周波数と特定のデータレート(LoRa DR) を Device 側が念頭に入れなくちゃならなくて、そのチャネルにアクセスが集中してしまうでしょう。

といういことで急遽 8ch の GW 衝動買い。これで近所の人はだれでも気軽に、そして、セキュアに草の根ネットワークを楽しめます。

正直、この記事みても意味は分かりませんでした。
https://www.rs-online.com/designspark/what-is-the-activation-method-on-lorawan-abp-and-otaa-jp
ABP の P が Personalization ということにきがつけばよかったのかも。「そのため、全てのデバイスを手動でプログラミングする必要がある」とあるけど、OTAA でも各デバイスとそのサービスはプログラミングなどをする必要あるしね。そこがポイントじゃありませんでした。

## TTN は世界的な草の根ネットワークなので
TTN を使うとちょっとうれしいことは、世界的なネットワークという事でしょう。例えば、私がデバイスをもってアムステルダムへ、あるいはアジアのどっかの国へ行ったとします。設定さえしていればそのデバイスは機能してインタネット経由でその情報得ることができるという事を意味します。

世界まで広げなくてもいろいろできそうです。

地域コミュニティと相性がいいのは確かですが、地理的な距離を超えた仮想的なコミュニティ(たとえば、北海道と沖縄と千葉をつなぐとか）上のサービスを展開するということが可能になるわけです。

## TTN の恩恵
GW が 8ch あるのに AS923(日本での仕様) では 2つの freq しか Listen しないという規格です。もったいないですよね。おそらくですが、、、(未確認です)、LoRaWAN にはネゴシエーションとしてどのチャネルを使っていいかリストの交換があるはずなので（仕様書を見返しても見つからず。見失ってしまった、、、）、Join 後は周波数やDRを変えることが可能なはずです。通常は GW からの指示あるいはリスト提示になるはずで(device 側が変えても、GW は追従するかもしれないけど device 側は GW が何対応しているのか知る必要があるでしょう)その範囲で device は分散していくはずです。（後でログ見たらちゃんと 2ch より多くのチャネルをつかっていました。Join 時に CFList を与えるのでしょう）

TTN は ADR(Adaptive Data Rate) という仕組みを用意しているようなので、これも頼もしいですね。
https://www.thethingsnetwork.org/docs/lorawan/adaptive-data-rate.html

いずれにせよ TTN がいろいろサービスをして負荷分散なりなんなりをしてくれるようなので、自分でネットワークを組むよりその方が楽そうです(github に ttn のソースがあるのでそこから build して自分のネットワークを構築することも可能。でもあまり意味ないかな)。そのためには GW は TTN に対しいろいろ情報を教えないといけないはずですね。これらは今後調べていきたいと思います。

プロトコルには CFList(Channel Frequency List) というのがあるみたいですね。

## それでも ABP
まぁABPだから TTN の恩恵が受けられないというわけではなさそうなので、ABP 簡単だからいいかな。でも GW が OTAA に対応しているなら(というか対応しているのが GW だから)、GW が普及していけば ABP にわざわざする必要もない気がします。

# GW 設定
ここからはざっくりと実践編です。そろそろ長くなって書いている側も力尽き始めたのでほんとざっくりと行きます。

kiwi tech の資料を見てもどう設定したらいいかわかりません。github を探すと、、、ありました(https://github.com/TheThingsNetwork/gateway-conf/blob/master/AS1-global_conf.json) はい！うまく設定できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99921/1ed40de5-ce11-e949-20ce-8d912fa3d394.png)

## パケットフォワーダー
なぜか、asia-se.thethings.network はだめでした。router.jp.thethings.network です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99921/75212995-f339-c8b0-cd59-2b4924c3a028.png)

TTN は looking forward の API を用意しているようなので、本当はそこから探さないといけないようです。TTN 用の cli もあるみたいですし。

# TTN 側の設定
省略
gateway の設定して、アプリ追加して、デバイスを追加します。gateway は場所を公開しないという設定にもできます（デフォルトは公開）

# ライブラリの設定
私は Arduino (正確には Dragino の LoRa Mini）を使いました。ライブラリとしては micc の LMIC を使います。オリジナルの LMIC はコンパイル時に引数で諸設定をするようですが、Arduino ではそれがむずかしいので、ライブラリ内の project_config の lmic_project_config.h を修正します。ライブラリ側を修正するのは管理上心苦しいですが、そういうものなので、仕方なく修正します。

```
// project-specific definitions
//#define CFG_eu868 1
// #define CFG_us915 1
//#define CFG_au915 1
#define CFG_as923jp 1
//#define CFG_kr920 1
//#define CFG_in866 1
#define CFG_sx1276_radio 1
//#define LMIC_USE_INTERRUPTS
```

# デバイス側のプログラミング (まずは ABP で)
TTN のデバイス設定で払い出された device EUI を使います。GW が 8ch 対応なので、LMIC にパッチを当てる必要はありません。

NWKSKEY、APPSKEYの設定、DEVADDRの設定、lmic_pins の変更、修正点はそれくらいかな？LMIC_setSession の第一引数は 0x13 そのままです。0x13 は TTN の netid なので、TTN に参加するので敬意を表してそのままにします。private でサーバを立てているなら 0 とか 1 にすればいいでしょう。出力のパワー？は日本向けに LMIC_setDrTxpow の第２引数が 13 になっていることを確認します。

NetID の一覧はこちら。デバイスもアサインされているんですね。
https://www.thethingsnetwork.org/docs/lorawan/prefix-assignments.html

```
// Pin mapping
// Adapted for Feather M0 per p.10 of [feather]
const lmic_pinmap lmic_pins = {
    .nss = 10,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 9,
    .dio = {2, 6, 7},
};
中略
    LMIC_setSession (0x13, DEVADDR, nwkskey, appskey);
中略
    LMIC_setDrTxpow(DR_SF7, 13);
```

## なんちゃって GW 対応
前の設定だと標準的な GW 対応になっているので、 923.4MHz(１個目) と 923.2MHz(２個目） を送信時に交互に使います。そこで、もし、実験的にポートフォワーダを LG01 みたいな１つしか受けがないハードを使う場合は2つめのチャネル(テーブルの番号は1)を Disable すると 924.4MHz のみを使うようになります。LMIC のソースを読むと規約通り、beacon に使う周波数とかが定義されていたりします。class B は今回使わないので、この対応で通信が可能です。ライブラリの方に手を入れるという手もありますが、後で混乱しそうなのでしませんでした。もちろん、標準的な GWをつかい２つの周波数の受信を常に可能であるならそもそも Diable する必要はありません。

```
    LMIC_disableChannel(1);
```

## TTN でパケット確認
TTN でパケットを確認することが出来ます。Device のデータというところです。なお、この表示はパケットに刻まれた積算カウンタと TTN サーバ側で管理している受信カウンタを比較していて、TTN サーバ側のカウンタよりパケットのそれが小さいと表示してくれません！

デバイスはリセットしたりして立ち上げなおすとカウンタがゼロになるのでデバッグ時には不便です。

その場合は TTN の設定でカウンタをクリアするか、デバイスの Setting で Frame Counter Check のチェックを外すとデバッグに便利です。なお「フレームカウンターチェックを無効にすると、セキュリティが大幅に低下するため、開発目的でのみ使用してください。」ということなので、デバッグ以外の時はチェックを入れたままにしましょう。

## Payload Formats
Application の設定で Payload フォーマットというのがあります。Javascript で書く Payload をデコードする簡易機能です。本当は自前の MQTT とつなげたいのですがそれはまだできていません。他のサービスとつなぐということも簡単にできるみたいですね。

```
function Decoder(bytes, post) {
   var decoded = {};
   decoded.message = String.fromCharCode.apply(null, bytes);
   return decoded;
}
```

テスト的にストリングを流しているので上のデコーダーで解析します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99921/9c36b6d3-a6a2-e3f7-b891-1b0f5d9848e0.png)

メッセージが OTTA になっているのはご愛嬌ということで。

## OTAA 対応
micc 提供の  https://github.com/mcci-catena/arduino-lmic から examples の ttn-otaa/ttn-otaa.ino をコピペして使います。

APPEUI, DEVEUI, APPKEY の修正、lmic_pinmap の追加、くらいでしょうか？APPEUI と DEVEUI はなぜか little endian だそうです。ここで最初失敗しました。APPKEY は big endian 。なんでよ。あとシリアルのボーレート。115200 に変更したかな。RX2 のウィンドウ等はネゴシエーションの結果、自動で設定されるので付け加える必要がありません。

コンパイルするとメモリが足りなさそうというワーニングが出ます。
「動作が不安定になる可能性があります。」と言われますが、今のところ何か重大な事は起こっていません。LMIC を使うんだと、もうすこし ROM/RAM がリッチなデバイスを使う必要がありそうです。現在は 32K/2K かな？

全部自動なのでらくちんです。よりらくちんな arduino-lorawan というライブラリも micc が提供しています。ただメモリが足りるかどうか、、、まだ試してません。

## GW 側設定とTNNでのパケットの確認
GW のフォワード先を間違えて eu にすると GW へ EU の周波数が伝えられるみたいでうまく JOIN できませんでした。あと、最初 APPEUI と DEVEUI が little endian と気が付かなった、、、。まぁうまくいくと TNN の画面にデータが出るのでちょっとうれしくなります。あとは TNN の API をつかって MQTT とか展開するとよいのでしょう。
 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99921/1ae1ceee-769a-2410-2fd1-c43a4c2bc5a7.png)

GATEWAY の TRAFFIC でも確認できます。こちらでは Join の Request と Accept のパケットを見ることが出来ます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/99921/9fda4f1a-eba4-60f8-7d61-a761c7e557f6.png)

いまみると、Join には 923.2MHz つかってますが、その後 922.2 MHz などを使いまわしてますね。ちゃんと 8ch になっている。（一つは特別だから　7ch を使いまわしているのかな？）

# 今後
LoRaWAN を使おうと思うと、32K/2K だとちょっとメモリが足りない感じです（とほほ）。ROM はともかく RAM がね。ビーコンとかつかってない(GW が class B 対応してないし)ので、設定で off にすればもうちょい使うメモリ少なくて済むかも。

今後、確かめたいのはしないでどの辺まで飛ぶのか？5Km ということはないでしょうが、ポートタワーの上からぐらいは飛ばしてみたい。2km はないけど、1km 以上。あと、いまメッセージになっているけど、ちゃんと GPS で場所情報を飛ばしたい。そして、それを MQTT で拾って、じぶんのスマホで見てみたいな。 

もちろん、周辺の人は勝手に使ってください。

最後になるにつれ雑になったけど、ここまで読んでくれてありがとうございました。