Qiita

はじめに

世界最大の無料LoRaWANネットワーク「The Things Network」については、ネット上で多く語られていますので、ここでは具体的に、ゲートウェイLG01-Pでの「The Things Network」日本国内接続設定作業を掲載いたします。

内容

まず、設定パソコン ⇒ LG01-P ⇒ 既設ルーターと接続し、LG01-Pが通常のルーターとしてDHCP機能で設定パソコンにIPアドレスを割り付け、インターネット接続するところから、ゲートウェイとしての基本設定をするところまで行います。
LG01-Pは、無線WiFiポートが1つあり、LAN側またはWAN側どちらかを無線接続することができます。
そして、「The Things Network(TTN)」のアカウントを作成し、LG01-PでTTNに接続させます。

設定作業

1. マニュアルLG01_LoRa_Gateway_Manual_JP.pdfの15頁「2.1.2 LoRa サーバスケッチをアプロード」までを設定

設定-1.jpg
8頁、このページが表示されましたら正常に「設定パソコン ⇒ LG01-P」ができていますので、Aurduino IDEでの設定に移れます。
設定-2.jpg
最後15頁、Aurduino IDEの右上のボタンシリアルモニターでこの画面を確認できましたら、LG01-Pの基礎設定は完了です。

2. Dragino wiki「Connect to TTN」でTTNとLG01-Pの接続設定

設定-4.jpg
と、その前に、フリーソフトのTeratrmで、10.130.1.1(LG01-P)に接続し、
設定-3.jpg
ifconfigとタイプ、実行してください。
39行目 Version: Dragino-v2 IoT-4.2.2
40行目 Build Web Jul 19 15:06:00 CST 2017
46行目 br-lan Link encap:Ethernet HWaddr A8:40:41:17:C5:19
に注目です。
39,40行目2017年7月19日(水)の4.2.2では、TTNに接続できませんでした!
Version: Dragino-v2 IoT-4.2.3
Build Sat Aug 19 15:41:30 CST 2017
wikiにも掲載されましたが、2017年8月19日(水)のファームウェア4.2.3にする必要があります。
そして46行目、LG01-Pの裏に貼ってあるシールと番号が少々違いましたが使えました。

wikiの設定を開始します。
TTNのコンソールとLG01-Pのファーム設定画面を行き来し、
設定-5.jpg
設定-6.jpg

LoRaWANサーバーを構成する

ところで、TTN Server Addressを「router.as.thethings.network」にするなどTTNの設定を書き写し、TXとRX周波数を「923200000」(その下そのまま)にしwikiを離れます。

3. 最後にLG01-Pを輸入しているオープンウェーブが提供しているGitHubのページをClone or download、編集してLG01-Pに書き込みます。

まずは、TTNへの送信側gwstat.pyファイルの編集

gwstat.py
import sys
import socket
import subprocess
import struct
import random
import base64

from struct import *

argvs = sys.argv
argc = len(argvs)
print argvs
if (argc < 3):
    print 'Usage: # python %s filename' % argvs[0]
    quit()

print 'ip    : %s ' % argvs[1]
print 'port  : %s ' % argvs[2]
print 'argvs1: %s ' % argvs[3]

# change your gateway ID(from 0xA8 to 0x19)
head = chr(1) \
+ chr(random.randint(0,255)) \
+ chr(random.randint(0,255)) \
+ chr(0) \
+ chr(0xA8) \
+ chr(0x40) \
+ chr(0x41) \
+ chr(0xFF) \
+ chr(0xFF) \
+ chr(0x17) \
+ chr(0xC5) \
+ chr(0x19)


if (argvs[3] == "stat"):
    stat = "{\"stat\":{" \
      + "\"time\":" + subprocess.check_output(["date", "+\"%Y-%m-%d %H:%M:%S GMT"])[0:24] + "\"," \
      + "\"lati\":34.82965074," \
      + "\"long\":138.12424447," \
      + "\"alti\":0," \
      + "\"rxnb\":0," \
      + "\"rxok\":0," \
      + "\"rxfw\":0," \
      + "\"ackr\":0," \
      + "\"dwnb\":0," \
      + "\"txnb\":0," \
      + "\"pfrm\":\"Dragino LG01-P\"," \
      + "\"mail\":\"rfid@nervio.jp\"," \
      + "\"desc\":\"\"" \
      + "}}"
    head+=stat
else:
    rxpk = "{\"rxpk\":[{" \
      + "\"tmst\":" + subprocess.check_output(["date", "+%s"])[0:10] + ",".replace('\n','') \
      + "\"chan\":0," \
      + "\"rfch\":0," \
      + "\"freq\":" + argvs[5] + "," \
      + "\"stat\":1," \
      + "\"modu\":\"LORA\"" + "," \
      + "\"datr\":\"SF7" \
      + "BW125\""  + ","\
      + "\"codr\":\"4/5\"," \
      + "\"lsnr\":9," \
      + "\"rssi\":" + argvs[3] + "," \
      + "\"size\":" + argvs[4] + "," \
      + "\"data\":\""

    f = open('/mnt/mtdblock3/data/bin','rb')
    data1 = f.read()
    f.close()
    rxpk+=base64.b64encode(data1)

    rxpk+="\"}]}"
    head+=rxpk

print(head)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
sock.sendto(bytes(head), (argvs[1], int(argvs[2])))
sock.close()
  • chr(0xA8)  からMACアドレスを1行ずつ入力
  • “\”lati\”:34.82965074,” \  緯度をTTNのコンソール地図からコピペ
  • “\”long\”:138.12424447,” \  経度もTTNコピペ
  • “\”mail\”:\”rfid@nervio.jp\”,” \  メールアドレスを自分のものへ編集

フリーソフトのWinSCPにて、ダウンロードしたpythonScript内のファイルをLG01-P内のmntフォルダにmtdblock3フォルダを作成しコピーします。

Winscpにて
/mnt/mtdblock3
        ├─data(dataフォルダも作ります)
        ├─base64.py
        └─gwstat.py

つぎに、ノードからの受信側liteLoraGW.inoファイルの編集

liteLoraGW.ino
#include <SPI.h>
#include <LoRa.h>
#include <Console.h>
#include <time.h>
#include <Process.h>
#include <lmic.h> //時間の取得に利用
#include <FileIO.h>

#define PROTOCOL_VERSION 1
#define PKT_PUSH_DATA 0
#define PKT_PUSH_ACK  1
#define PKT_PULL_DATA 2
#define PKT_PULL_RESP 3
#define PKT_PULL_ACK  4

#define TX_BUFF_SIZE  2048
#define STATUS_SIZE  1024

#define LORAMAC_PHY_MAXPAYLOAD 255
#define UPLINK 0
#define DOWNLINK 1
static uint16_t datasize = 10;

// MACアドレス等は、python側で管理

// define servers
// TODO: use host names and dns
char SERVER1[] = "router.as.thethings.network"; // The Things Network Southeast Asia 923-925 MHz
unsigned int ttnPort = 1700;//ttn
// Set center frequency
uint32_t freq = 923200000;

// 位置情報
float lat=34.82965074;
float lon=138.12424447;
int alt=0; //高さ

void sendudp(char *rssi, char *packetSize, char *freq) {
  Process p;
  String strRssi = rssi;
  String strPacketSize = packetSize;
  String strFreq = freq;

  delay(3000);
  p.begin("python");
  p.addParameter("/mnt/mtdblock3/gwstat.py");
  p.addParameter(String(SERVER1));
  p.addParameter(String(ttnPort));
  p.addParameter(strRssi);
  p.addParameter(strPacketSize);
  p.addParameter(strFreq);
  p.run();
  while(p.running());
  while (p.available()) {
    char c = p.read();
    Console.print(c);
  }
  Console.flush();
}


void sendstat() {
  // ゲートウェイステータスの送信はpythonソース側で行う
  sendudp("stat","",String((double)freq/1000000).c_str());
}


void receivepacket() {
  // try to parse packet
  int packetSize = LoRa.parsePacket();

  if (packetSize) {
    // received a packet
    Console.print("packetSize : ");
    Console.println(packetSize);
    int rssicorr = 157;

    // read packet
    int i = 0;
    char message[256];

    while (LoRa.available() && i < 256) {
      message[i]=LoRa.read();
      i++;
    }
    FileSystem.begin();
    File dataFile = FileSystem.open("/mnt/mtdblock3/data/bin", FILE_WRITE);
    for(int j=0;j<i;j++)
        dataFile.print(message[j]);
    dataFile.close();
    delay(1000);
    //send the messages
    sendudp(String(LoRa.packetRssi()).c_str(), String(packetSize).c_str(),String((double)freq/1000000).c_str());
  }
}

void setup() {
  Bridge.begin(115200);
  Console.begin();
  while(!Console);
  // put your setup code here, to run once:
  Console.println("LoRa Receiver");

  if (!LoRa.begin(freq)) {
    Console.println("Starting LoRa failed!");
    while (1);
  }
  LoRa.setSyncWord(0x34); //同期するための値
  LoRa.receive(0);        //受信状態にする
}

long lasttime;
void loop() {
  receivepacket();
  //60秒インターバル
  long nowseconds = os_getTime();

  if(nowseconds-lasttime > 6000000){
      Console.println("send stat\n");
      lasttime = nowseconds;
      sendstat();
  }
}
  • char SERVER1[] = “router.as.thethings.network”;  TTNのコンソールとの一致を確認
  • uint32_t freq = 923200000; LG01-Pは1チャンネルのゲートウェイなので1ヶ周波数を書き込み
  • // 位置情報
  • float lat=34.82965074;  またTTN緯度をコピペ
  • float lon=138.12424447;  またTTN経度をコピペ

Arduino IDEにて書き込み作業終了です。

確認

設定-10.jpg
Statusがnot connectedから
設定-20.jpg
connectedになれば接続できています。
DSC_0082-(2017-08-19T14_41_22.000).jpg
TTN_SHIZUOKAへのご参加お待ちしております。

参考