DRAGINO LoRa GPS HATとLoRa Mini を使って 温度、湿度データをTTN-Cayenneで表示してみた

RSコンポーネンツさんのオンラインショップrs-online.comでDRAGINO社のLoRa GPS HATを購入して手元に届いたので設定して使ってみました。

https://jp.rs-online.com/web/

以前よりLoRa IoT スターターキットを使っていましたので、その応用となります。

センサーデバイスから取得したデータの可視化にはクラウドサービスである「Cayenne」を使います。

https://mydevices.com/

LoRa IoTスターターキットとCayenneの使い方については、以下の書籍で詳しく紹介されていますので

そちらをご覧ください。
長距離まで届く無料のIoTネットワークサービス The Things Network

「LoRaWAN」をみんなでシェアして使う (工学社 吉田 秀利、尾鷲 彰一)

https://www.kohgakusha.co.jp/books/detail/978-4-7775-2043-5

ttn_raspberry
使用する機器

1)Raspberry Pi 3 B+

2)ゲートウェイ DORAGINO LoRa GPS HAT-JP


【写真1】

【写真2】

写真1の左がRaspberry Pi 3 B+、右がLoRa GPS HATです。

写真2はRaspberry PiにLoRa GPS HATを載せた状態です。

3)センサーデバイス DORAGINO LoRa Mini Wireless Module、DHT-11(温湿度センサー)


LoRa MiniとDHT-11を接続します。

LoRa Miniの3V3ポートにDHT-11のVCC、GNDポートにGND、A0ポートにDATAをそれぞれ接続します。

こちらのWirelress ModuleとセンサーはLoRa IoTスターターキットに含まれています。

詳しくは以下のページをご覧ください。

https://www.rs-online.com/designspark/getting-start-the-lora-iot-starter-kit-with-the-things-network-part1-jp?fbclid=IwAR3cZtoOSJhzuf3nZFfn30L5Zc7y0IErt-mROhr4uIKb5r0tAPYLAKJCLt4

Raspberry Piの起動用SDカードの用意

今回は手元にあった2018-11-13-raspbian-stretch-fullを使いました。

適宜、公式サイトからダウンロードしてインストールしてください。

ゲートウェイ側ソースコードの取得

Raspberry Piで動作させるLoRa GPS HAT用のプログラムをgithubからダウンロードしてきます。https://github.com/bokse001/dual_chan_pkt_fwd.git

設定ファイルの編集

その中にある設定ファイルglobal_config.jsonを以下のように変更します。

{

"SX127x_conf":

{

"freq": 923400000,

"freq_2": 923200000,

"spread_factor": 10,

"pin_nss": 6,

"pin_dio0": 7,

"pin_nss_2": 6,

"pin_dio0_2": 7,

"pin_rst": 3,

"pin_led1":4,

"pin_NetworkLED": 22,

"pin_InternetLED": 23,

"pin_ActivityLED_0": 21,

"pin_ActivityLED_1": 29

},

プログラムの修正

以下 の内容をdual_chan_pkt_fwd.cppに追加します。

// Tx Power Register
#define REG_PA_CFG 0x09
// Power Setting for Japan ARIB STD-T108
// 20mW=13dBm
// SX1276 RegPaConfig(0x09), Val=0x3f
// bit 7 PaSelect = 0 select RFO
// bit 6-4 MaxPower = 3 Pmax=10.8+0.6*3=12.6 < 13
// bit 3-0 OutputPower = 0x0f Pout=Pmax-(15-0x0f)=12.6
// SX1272 RegPaConfig(0x09), Val=0x0e
// bit 7 PaSelect = 0 select RFO
// bit 6-4 unused = 0
// bit 3-0 OutputPower = 0xe Pout=-1 + OutputPower = -1 + 0x0e = 13dBm
int PWR_JPN_1276 = 0x3f;
int PWR_JPN_1272 = 0xe;

周波数設定の後に追加します.
// Set Tx Power for Japan
if (sx1272) {
writeRegister(REG_PA_CFG, PWR_JPN_1272);
} else {
// sx1276
writeRegister(REG_PA_CFG, PWR_JPN_1276);
}


2019年4月25日訂正:
writeRegister(REG_PA_CFG,PWR_JPN_1272);
writeRegister(REG_PA_CFG,PWR_JPN_1276);
となっているところは関数の仕様が変わっていますので
WriteRegister(REG_PA_CFG,PWR_JPN_1272, CE);
WriteRegister(REG_PA_CFG,PWR_JPN_1276, CE);
に変更してください。(先頭のwがW(大文字)になる、引数にCEを追加)


こちらの内容は@Densyoさんのqiitaを参考にしています。

プログラムのコンパイル

ここまでの修正が終わったらプログラムをコンパイルします。

この手順は以下のページを参照してください。

プログラムの実行

プログラムを実行すると以下のように表示されてゲートウェイが動作していることがわかります。

pi@raspberrypi : ~/dual_chan_pkt_fwd $ sudo ./dual_chan_pkt_fwd

server: .address = router.eu.staging.thethings.network; .port = 1700; .enable = 1

server: .address = router.eu.thethings.network; .port = 1700; .enable = 0

Gateway Configuration

Takenori Tanaka (takenori_tanaka@niigata-sl.com)

Dual channel pkt forwarder

Latitude=37.83515930

Longitude=139.11381531

Altitude=3

Interface: eth0

Trying to detect module CE0 with NSS=6 DIO0=7 Reset=3 Led1=unused

SX1276 detected on CE0, starting.

Trying to detect module CE1 with NSS=6 DIO0=7 Reset=3 Led1=unused

SX1276 detected on CE1, starting.

Gateway ID: b8:27:eb:ff:ff:01:4a:6b

Listening at SF10 on 923.400000 Mhz.

Listening at SF10 on 923.200000 Mhz.


stat update: 2019-04-05 05:40:07 GMT no packet received yet

センサーデバイス側プログラムの準備

センサーデバイス側のサンプルコードが株式会社オープンウェーブのgithubで公開されています。

以下のコードはサンプルコードを参考に作成したものです。

このプログラムではLoRaWANからクラウドサービスCayenneにデータを渡すようになっています。

また、LoRaWANでは,デバイスとセキュアに通信するため暗号化して通信する仕組みが導入されています。通信開始時には「アクティベーション」により暗号鍵を交換します。この方式にはABPとOTAAの2種類があり、今回はABPを使用しています。

LoRaWANの暗号化システムについては以下のページに詳しく解説されています。

https://www.rs-online.com/designspark/what-is-the-activation-method-on-lorawan-abp-and-otaa-jp?fbclid=IwAR2kv5ck3o1ZJAn1IG48tQws1avPadfzW2CzDhK98ETAoFnpf4pNsHRM9Dk

/*******************************************************************************

  • Copyright © 2015 Thomas Telkamp and Matthijs Kooijman

  • Changed 2017.11.01 OpenWave inc,

  • Permission is hereby granted, free of charge, to anyone

  • obtaining a copy of this document and accompanying files,

  • to do whatever they want with them without any restriction,

  • including, but not limited to, copying, modification and redistribution.

  • NO WARRANTY OF ANY KIND IS PROVIDED.

  • Change DEVADDR to a unique address!

  • See http://thethingsnetwork.org/wiki/AddressSpace

  • Do not forget to define the radio type correctly in config.h.

  • Required Library:

  • Require Hardware:

    • LoRa Shield + Arduino
    • LoRa GPS Shield + Arduino
    • LoRa Mini etc.
  • このサンプルは、The Things NetworkにABPで、DHT11の

  • 温度、湿度のデータをCayenneLPPのペイロードで送信します。

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

*******************************************************************************/

#include <lmic.h>

#include <hal/hal.h>

#include <SPI.h>

#include "DHT.h"

#include "CayenneLPP.h"

#define dht_dpin A0 // Use A0 pin as Data pin for DHT11.

#define DHTTYPE DHT11 // DHT 11

/*

  • 以下の、デバイスアドレス、ネットワークセッションキー、アプリケーションセッションキー

  • を、The Things Networkで取得した値に変更してください。

*/

// デバイスアドレス

static const u4_t DEVADDR = ここにデバイスアドレスを設定します;

// ネットワークセッションキー

static const PROGMEM u1_t NWKSKEY[16] = { ここにネットワークセッションキーを設定します };

// アプリケーションセッションキー

static const u1_t PROGMEM APPSKEY[16] = { ここにアプリケーションセッションキーを設定します };

// 以下の変数はOTAAでアクティベーションする際に、TTNから割り当てられる値となります。

void os_getArtEui (u1_t* buf) { }

void os_getDevEui (u1_t* buf) { }

void os_getDevKey (u1_t* buf) { }

static uint8_t mydata[4];

static osjob_t initjob,sendjob,blinkjob;

// Schedule TX every this many seconds (might become longer due to duty

// cycle limitations).

const unsigned TX_INTERVAL = 20;

DHT dht(dht_dpin, DHTTYPE);

// Pin mapping

const lmic_pinmap lmic_pins = {

.nss = 10,

.rxtx = LMIC_UNUSED_PIN,

.rst = 9,

.dio = {2, 6, 7},

};

void do_send(osjob_t* j){

float h = dht.readHumidity();

float t = dht.readTemperature();

CayenneLPP lpp(51); // create a buffer of 51 bytes to store the payload

lpp.reset(); // clear the buffer

lpp.addTemperature(1, t); // on channel 1, add temperature, value 22.5°C

lpp.addRelativeHumidity(2, h); // channel 2, pressure

// Check if there is not a current TX/RX job running

if (LMIC.opmode & OP_TXRXPEND) {

Serial.println("OP_TXRXPEND, not sending");

} else {

// Prepare upstream data transmission at the next possible time.

LMIC_setTxData2(1, lpp.getBuffer(), lpp.getSize(), 0);

Serial.println("Packet queued");

Serial.println(LMIC.freq);

}

// Next TX is scheduled after TX_COMPLETE event.

}

void onEvent (ev_t ev) {

Serial.print(os_getTime());

Serial.print(": ");

Serial.println(ev);

switch(ev) {

case EV_TXCOMPLETE:

Serial.println("EV_TXCOMPLETE (includes waiting for RX windows)");

if(LMIC.dataLen) {

// data received in rx slot after tx

Serial.print("Data Received: ");

Serial.write(LMIC.frame+LMIC.dataBeg, LMIC.dataLen);

Serial.println();

}

// Schedule next transmission

os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);

break;

default:

Serial.println("Other Event");

break;

}

}

void setup() {

memset(mydata, 0x00, 4);

Serial.begin(9600);

while(!Serial);

Serial.println("Starting");

delay(1000);

// LMIC init

os_init();

// Reset the MAC state. Session and pending data transfers will be discarded.

LMIC_reset();

//LMIC_setClockError(MAX_CLOCK_ERROR * 1/100);

// Set static session parameters. Instead of dynamically establishing a session

// by joining the network, precomputed session parameters are be provided.

#ifdef PROGMEM

// On AVR, these values are stored in flash and only copied to RAM

// once. Copy them to a temporary buffer here, LMIC_setSession will

// copy them into a buffer of its own again.

uint8_t appskey[sizeof(APPSKEY)];

uint8_t nwkskey[sizeof(NWKSKEY)];

memcpy_P(appskey, APPSKEY, sizeof(APPSKEY));

memcpy_P(nwkskey, NWKSKEY, sizeof(NWKSKEY));

LMIC_setSession (0x1, DEVADDR, nwkskey, appskey);

#else

// If not running an AVR with PROGMEM, just use the arrays directly

LMIC_setSession (0x1, DEVADDR, NWKSKEY, APPSKEY);

#endif

// Disable link check validation

LMIC_setLinkCheckMode(0);

// TTN uses SF9 for its RX2 window.

LMIC.dn2Dr = DR_SF9;

// Set data rate and transmit power (note: txpow seems to be ignored by the library)

LMIC_setDrTxpow(DR_SF10,13);

dht.begin();

// Start job

do_send(&sendjob);

}

void loop() {

os_runloop_once();

}

センサーデバイスの起動

ArduinoIDEを使用してプログラムを書き込み、実行します。

デバイスでは温度と湿度を計測してデータ送信を開始します。

センサーデバイスからデータを受信するとゲートウェイ側のコンソールにその様子が表示されます。

pi@raspberrypi : ~/dual_chan_pkt_fwd $ sudo ./dual_chan_pkt_fwd

server: .address = router.eu.staging.thethings.network; .port = 1700; .enable = 1

server: .address = router.eu.thethings.network; .port = 1700; .enable = 0

Gateway Configuration

Takenori Tanaka (takenori_tanaka@niigata-sl.com)

Dual channel pkt forwarder

Latitude=37.83515930

Longitude=139.11381531

Altitude=3

Interface: eth0

Trying to detect module CE0 with NSS=6 DIO0=7 Reset=3 Led1=unused

SX1276 detected on CE0, starting.

Trying to detect module CE1 with NSS=6 DIO0=7 Reset=3 Led1=unused

SX1276 detected on CE1, starting.

Gateway ID: b8:27:eb:ff:ff:01:4a:6b

Listening at SF10 on 923.400000 Mhz.

Listening at SF10 on 923.200000 Mhz.


stat update: 2019-04-06 00:57:48 GMT no packet received yet

CE0 Packet RSSI: -43, RSSI: -96, SNR: 14, Length: 20 Message:’@…&.T…‘e…B#…’

rxpk update: {"rxpk":[{"tmst":416552586,"freq":923.4,"chan":0,"rfch":0,"stat":1,"modu":"LORA","datr":"SF10BW125","codr":"4/5","rssi":-43,"lsnr":14.0,"size":20,"data":"QIYbBCaAVAUBJ2UatrShjUIj0dI="}]}

stat update: 2019-04-06 00:58:18 GMT 1 packet received

CE0 Packet RSSI: -44, RSSI: -95, SNR: 14, Length: 20 Message:’@…&.U…x…8(…$’

rxpk update: {"rxpk":[{"tmst":453612330,"freq":923.4,"chan":0,"rfch":0,"stat":1,"modu":"LORA","datr":"SF10BW125","codr":"4/5","rssi":-44,"lsnr":14.0,"size":20,"data":"QIYbBCaAVQUBiXjB2DgopBgO8yQ="}]}

stat update: 2019-04-06 00:58:48 GMT 2 packets received

stat update: 2019-04-06 00:59:18 GMT 2 packets received

CE0 Packet RSSI: -45, RSSI: -96, SNR: 12, Length: 20 Message:’@…&.V…(…l…’

アプリケーションデータの確認


TTNのコンソールでアップロードされるデータを確認しました。

Cayenneでの表示

LoRaWANからCayenneにデータが上がってきますとコンソール画面でグラフ表示などで確認できます。

最後に

今回は簡単にできる範囲でゲートウェイ機能を使ってみただけですが、今後はGPS機能やフィールドに持ち出しての利用についても試していきたいと思っています。

「いいね!」 2