2020/08/24

[第4回]LoRa ClientとServerでLoRaの通信を試してみよう

rolaiotarduino

概要

前回ではLG01のLEDを点灯させて、Arduino IDEからのプログラムが正常にアップロードできることを確認しました。

今回は、LoRa ClientであるLoRa Mini DevとLora ServerであるLG01間のLoRa通信の検証を行います。

Client側の設定

PCとLoRa Mini Devの接続

まずは、LoRa Clientである、LoRa Mini DevをUSBを使って、PCと接続します。

LoRa Mini DevはUSB経由で給電されるので、USBを繋げば勝手で電源がつきます。

PCと繋いでいる様子(机汚くてすいません)
usb-connet-client-min.png

Arduino IDEの設定

プログラムを書くまえに、必要なライブラリをインストールしておく必要があります。
Arduino IDEを立ち上げて、以下をインストールしましょう。

ライブラリ名 用途 インストール方法
RadioHead LoRa通信用のライブラリ https://github.com/dragino/RadioHead/archive/master.zipをダウンロード&解凍して、Arduino IDEのlibrariesフォルダに格納

Client側のプログラムとアップロード

Dragino Yun + UNO or LG01/OLG01 のボードを選択しておきます。

ファイル > スケッチ例 > Dragino > LoRa > LoRa_Simple_Client_Arduino からプログラムの例を開くことができます。

arduino-ide-simple-client-min.png

/*
  LoRa Simple Client for Arduino :
  Support Devices: LoRa Shield + Arduino 
  
  Example sketch showing how to create a simple messageing client, 
  with the RH_RF95 class. RH_RF95 class does not provide for addressing or
  reliability, so you should only use RH_RF95 if you do not need the higher
  level messaging abilities.

  It is designed to work with the other example LoRa Simple Server
  User need to use the modified RadioHead library from:
  https://github.com/dragino/RadioHead

  modified 16 11 2016
  by Edwin Chen <[email protected]>
  Dragino Technology Co., Limited
*/

#include <SPI.h>
#include <RH_RF95.h>

// Singleton instance of the radio driver
RH_RF95 rf95;
float frequency = 868.0;

void setup() 
{
  Serial.begin(9600);
  //while (!Serial) ; // Wait for serial port to be available
  Serial.println("Start LoRa Client");
  if (!rf95.init())
    Serial.println("init failed");
  // Setup ISM frequency
  rf95.setFrequency(frequency);
  // Setup Power,dBm
  rf95.setTxPower(13);

  // Setup Spreading Factor (6 ~ 12)
  rf95.setSpreadingFactor(7);
  
  // Setup BandWidth, option: 7800,10400,15600,20800,31200,41700,62500,125000,250000,500000
  //Lower BandWidth for longer distance.
  rf95.setSignalBandwidth(125000);
  
  // Setup Coding Rate:5(4/5),6(4/6),7(4/7),8(4/8) 
  rf95.setCodingRate4(5);
}

void loop()
{
  Serial.println("Sending to LoRa Server");
  // Send a message to LoRa Server
  uint8_t data[] = "Hello, this is device 1";
  rf95.send(data, sizeof(data));
  
  rf95.waitPacketSent();
  // Now wait for a reply
  uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
  uint8_t len = sizeof(buf);

  if (rf95.waitAvailableTimeout(3000))
  { 
    // Should be a reply message for us now   
    if (rf95.recv(buf, &len))
   {
      Serial.print("got reply: ");
      Serial.println((char*)buf);
      Serial.print("RSSI: ");
      Serial.println(rf95.lastRssi(), DEC);    
    }
    else
    {
      Serial.println("recv failed");
    }
  }
  else
  {
    Serial.println("No reply, is LoRa server running?");
  }
  delay(5000);
}

プログラムの中身

  • 868.0 の周波数でLoRa通信を行い、 5秒間隔で、“Hello, this is device 1” という文字列を送信します。
  • 通信が上手くいき、serverからのレスポンスがあれば、それをConsoleに表示します。

次に、このプログラムをアップロードするため、以下を選択します。

  • ボードを Arduino Uno を選択します
  • ポートを LoRa Mini Devが繋がれた、USBのポート (画像では、 /dev/cu.usbserial-14430 )を選択します

arduino-ide-simple-client-port-min.png

選択できたら、

スケッチ > マイコンボードに書き込む で先ほどのプログラムをアップロードします。

アップロードができたら、 ツール > シリアルモニタ をクリックして、シリアルモニタを表示します。

arduino-ide-simple-client-monitor-min.png

今は、Server側のプログラムが動いていない状態なので、Serverに送信するも、通信エラーで失敗するようなログが表示されます。

Sending to LoRa Server
No reply, is LoRa server running?
Sending to LoRa Server
No reply, is LoRa server running?
...(以下同様)

Server側の設定

※ LG01とは、同じネットワーク上に存在していることに注意してください。(ネットワークなどの設定は、第2回および第3回の記事を参考にしてください。)

  • ボードを Dragino Yun + UNO or LG01/OLG01 に戻します
  • ポートは LG01 のローカルIPアドレスであるネットワークポートを選択します

arduino-led-port-min.png

この状態で、ファイル > スケッチ例 > Dragino > LoRa > LoRa_Simple_Server_Yun からプログラムの例を開くことができます。

arduino-ide-simple-server-min.png

/*
  LoRa Simple Yun Server :
  Support Devices: LG01. 
  
  Example sketch showing how to create a simple messageing server, 
  with the RH_RF95 class. RH_RF95 class does not provide for addressing or
  reliability, so you should only use RH_RF95 if you do not need the higher
  level messaging abilities.

  It is designed to work with the other example LoRa Simple Client

  User need to use the modified RadioHead library from:
  https://github.com/dragino/RadioHead

  modified 16 11 2016
  by Edwin Chen <[email protected]>
  Dragino Technology Co., Limited
*/
//If you use Dragino IoT Mesh Firmware, uncomment below lines.
//For product: LG01. 
#define BAUDRATE 115200

//If you use Dragino Yun Mesh Firmware , uncomment below lines. 
//#define BAUDRATE 250000

#include <Console.h>
#include <SPI.h>
#include <RH_RF95.h>

// Singleton instance of the radio driver
RH_RF95 rf95;

int led = A2;
float frequency = 868.0;

void setup() 
{
  pinMode(led, OUTPUT);     
  Bridge.begin(BAUDRATE);
  Console.begin();
  while (!Console) ; // Wait for console port to be available
  Console.println("Start Sketch");
  if (!rf95.init())
    Console.println("init failed");
  // Setup ISM frequency
  rf95.setFrequency(frequency);
  // Setup Power,dBm
  rf95.setTxPower(13);
  
  // Setup Spreading Factor (6 ~ 12)
  rf95.setSpreadingFactor(7);
  
  // Setup BandWidth, option: 7800,10400,15600,20800,31200,41700,62500,125000,250000,500000
  rf95.setSignalBandwidth(125000);
  
  // Setup Coding Rate:5(4/5),6(4/6),7(4/7),8(4/8) 
  rf95.setCodingRate4(5);
  
  Console.print("Listening on frequency: ");
  Console.println(frequency);
}

void loop()
{
  if (rf95.available())
  {
    // Should be a message for us now   
    uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
    uint8_t len = sizeof(buf);
    if (rf95.recv(buf, &len))
    {
      digitalWrite(led, HIGH);
      RH_RF95::printBuffer("request: ", buf, len);
      Console.print("got request: ");
      Console.println((char*)buf);
      Console.print("RSSI: ");
      Console.println(rf95.lastRssi(), DEC);
      
      // Send a reply
      uint8_t data[] = "And hello back to you";
      rf95.send(data, sizeof(data));
      rf95.waitPacketSent();
      Console.println("Sent a reply");
      digitalWrite(led, LOW);
    }
    else
    {
      Console.println("recv failed");
    }
  }
}

プログラムの中身

  • 868.0 の周波数でLoRa通信を行い、データの入力を待ちます。
  • while (!Console) ; // Wait for console port to be available の部分で、シリアルコンソールを立ち上げないとプログラムの動作を待機することに注意。
  • 通信が上手くいき、clientから送信された文字列をコンソールに表示し、 “And hello back to you” を返信します。

スケッチ > マイコンボードに書き込む で先ほどのプログラムをアップロードします。

アップロードができたら、 ツール > シリアルモニタ をクリックして、シリアルモニタを表示します。

got request: Hello, this is device 1
RSSI: XXXXXXXX
Sent a reply
got request: Hello, this is device 1
RSSI: XXXXXXXX
Sent a reply
...(以下同様)

(先ほどはエラーになっていましたが、Serverが動いたことにより)このような感じで、Clientから5秒毎にメッセージを受信して、返信をするような動作が確認できます。

以上で、LoRa ClientとServer間の疎通確認ができました。

これと同じような要領で、LoRa Clientから湿度・温度を送信し、Serverで受信したタイミングで、クラウドサービスにアップする部分に挑戦していきます。

開発手順のおさらい

以下のような手順で実施します。

  1. LG01(Gateway)のwifiの設定 <= 第2回の記事で紹介
  2. Arduino IDEを使って、LG01の動作確認 <= 第3回の記事で紹介
  3. Arduino IDEを使って、LoRa Mini DevとLG01の通信を検証 <= 今回の記事のスコープ
  4. ThingSpeakのアカウントの作成
  5. DHT11(湿度・温度センサー)とLoRa Mini Devをつなぎ、LG01を経由してThingSpeakにデータをアップロードする

第4回は以上になります。
第5回では、No.4のStepを説明していこうと思います。