12-14-2021 05:08 AM - 編集済み 12-14-2021 05:58 AM
屋外でデータを集めたり制御したりするときの通信モジュールとして一つの候補になると思いますので「920MHz LoRa/FSK無線ブレークアウト基板(ES920LR3)」を紹介します。
このモジュールは低消費電力で通信距離がかせげるというのがうたい文句で、見通せる場所では10km、市街地では2kmの実績があるそうです。プライベートLoRaという独自のプロトコルで通信できるためLoRaWANの事業者に支払う通信コストをセーブすることができます。
子機はESP32をコントローラ(Arduinoプログラム)にしてGPSモジュールからのデータを通信モジュールに渡します。親機で受けたデータはUSB-シリアル変換でLabVIEWでファイルに記録します。
手始めに、屋内に親機を置いて、バッテリーで給電した子機を車に乗せて近所を一周したデータから距離と信号強度のデータをグラフ化しましたので紹介します。
親機です。
子機です。
左側のグラフが自宅を中心にした子機の位置です。右側のグラフは信号強度と距離のグラフです。200mぐらいが最遠で、100mぐらい離れると通信が途絶える場合が多くなりそうです。市街地で2kmの実績といっても、見通せる位置関係とか、いろいろ条件があるでしょうから、数年前に試した通信モジュールよりかなり良い印象です。
使用した機材
920MHz LoRa/FSK無線ブレークアウト基板(EASEL社製ES920LR3を使用)2個
スイッチサイエンス(7920円/個)
子機コントローラはMH ET LIVE ESP32MiniKit
MH ET LIVE ESP32MiniKitについての情報
GPS受信機キット 1PPS出力付き「みちびき」3機受信対応
秋月電子通商(2100円)
USB-シリアル変換モジュール(FT231X USBシリアル変換モジュール)
秋月電子通商(750円)
親機の配線
USB-シリアル変換モジュール -> 920MHz LoRa/FSK無線ブレークアウト基板のCN2
5V (14ピン) -> 5V (3ピン)
GND (11ピン) -> GND (1ピン)
TXD (2ピン) -> TXD (4ピン:ES920LR3のUSART2_RX)
RXD (3ピン) -> RXD (5ピン:ES920LR3のUSART2_TX)
子機の配線
MH ET LIVE ESP32MiniKit -> 920MHz LoRa/FSK無線ブレークアウト基板のCN2
5V (CN2; 6ピン) -> 5V (3ピン)
GND (CN2; 8ピン) -> GND (1ピン)
IO17: UART2_TXD (CN2; 12ピン) -> TXD (4ピン:ES920LR3のUSART2_RX)
IO16: UART2_RXD (CN2; 10ピン) -> RXD (5ピン:ES920LR3のUSART2_TX)
MH ET LIVE ESP32MiniKit -> GPS受信機キット
5V (CN2; 6ピン) -> 5V
GND (CN2; 8ピン) -> GND
IO21: UART1_RXD (CN2; 14ピン) -> TXD
子機のMH ET LIVE ESP32MiniKit用Arduinioプログラム
TimeライブラリとTinyGPSPlusライブラリを使います。Serialはプログラム作成用、Serial1はGPSからの受信用、Serial2は通信モジュールとの通信用です。
シリアルを3本使えて、3.3V系なのがESP32を選択した理由です。
//Serial1のGPSデータを1秒間隔でSerial2に出力
#include <Arduino.h>
#include <TimeLib.h>
#include <TinyGPSPlus.h>
TinyGPSPlus gps;
const int offset = 9; // Japan Time
int lastSec=-1;
void setup()
{
Serial.begin(9600);//USB Serial
Serial1.begin(9600, SERIAL_8N1, 21, 22);//RX21,TX22
Serial2.begin(9600);//RX16,TX17
}
void loop()
{
while (Serial1.available() > 0){
if (gps.encode(Serial1.read())){
//displayInfo();
int newSec = gps.time.second();
if(newSec != lastSec){
JapanTime();
Location();
lastSec=newSec;
}
}
}
}
void JapanTime(){
if (gps.time.isValid()){
int Year = gps.date.year();
byte Month = gps.date.month();
byte Day = gps.date.day();
byte Hour = gps.time.hour();
byte Minute = gps.time.minute();
byte Second = gps.time.second();
setTime(Hour, Minute, Second, Day, Month, Year);
byte hour0=hour();//原因は分からなかったが時差を正しく表示するために必要だった
adjustTime(offset * SECS_PER_HOUR);
char date_str[32];
sprintf(date_str, "%04d/%02d/%02d,", year(), month(), day());
char time_str[32];
sprintf(time_str, "%02d:%02d:%02d,", hour(), minute(), second());
Serial.print(date_str);
Serial.print(time_str);
Serial2.print(date_str);
Serial2.print(time_str);
}
else{
Serial.print("InvalidDate,");
Serial.print("InvalidTime,");
Serial2.print("InvalidDate,");
Serial2.print("InvalidTime,");
}
}
void Location(){
if (gps.location.isValid())
{
float Lat=gps.location.lat();
float Lng=gps.location.lng();
Serial.print(Lat, 6);
Serial.print(",");
Serial.println(Lng, 6);
Serial2.print(Lat, 6);
Serial2.print(",");
Serial2.println(Lng, 6);
}
else
{
Serial.print("InvalidLat,");
Serial.println("InvalidLng");
Serial2.print("InvalidLat,");
Serial2.println("InvalidLng");
}
}
LabVIEWの読み取りプログラム(PrivateLoRa.vi)はサンプルVIにファイル書き込み用サブVI(sub_RecievedData.vi)を追加したものです。
解析プログラム(GPS_DataRead.vi)でデータファイルを読み解きます。
12-14-2021 04:01 PM
書き洩らした事項を書きます。
ES920LR3の設定に関する詳細は下記サイトから入手します。
https://easel5.com/service/products-information/products/wireless-module/es920lr3/
帯域幅と拡散率の設定で到達距離(と送信に要する時間)を変えることができます。使用した設定は下記の通り(到達距離が最長)です。
Coordinator
configuration setting is below.
-------------------------------------
Node : Coordinator
Band Width : 250kHz
Spreading Factor : 12
Effective Bitrate : 586bps
Channel : 1
PAN ID : F000
Own Node ID : 0000
Destination ID : FFFF
Acknowledge : ON
Retry count : 3
Transfer Mode : Payload
Receive Node ID information : ON
RSSI information : ON
Config/Operation : Operation
UART baudrate : 9600
Sleep Mode : No Sleep
Sleep Time : 50
Output Power : 13dBm
Format : ASCII
Send Time : 0
Send Data :
AES Key : 00000000000000000000000000000000
RF Mode : TxRx
Protocol Type : Private LoRa
Rx Boosted : ON
EndDevice
configuration setting is below.
-------------------------------------
Node : EndDevice
Band Width : 250kHz
Spreading Factor : 12
Effective Bitrate : 586bps
Channel : 1
PAN ID : F000
Own Node ID : 0001
Destination ID : 0000
Acknowledge : ON
Retry count : 3
Transfer Mode : Payload
Receive Node ID information : OFF
RSSI information : OFF
Config/Operation : Operation
UART baudrate : 9600
Sleep Mode : No Sleep
Sleep Time : 50
Output Power : 13dBm
Format : ASCII
Send Time : 0
Send Data :
AES Key : 00000000000000000000000000000000
RF Mode : TxRx
Protocol Type : Private LoRa
Rx Boosted : ON
子機で1秒間隔で送信するプログラムですが、送信時間がかかるのか送信量が大きすぎるのか確認していませんが、2秒間隔で送信されています。
親機がPCに繋がっていると持ち出しにくいのでハンディなものに置き換える予定です。
12-14-2021 06:20 PM
12-14-2021 10:57 PM
関心を持っていただいてありがとうございます。
木造家屋の2階とか風呂場とか、家の外の敷地の中を子機を持って歩いてみましたが、最低で-85dBm(-120dBmがほぼ下限)でしたので、我が家の周囲は問題ないと思います。
鉄筋のオフィスとは状況が異なると思いますが、ハンディーな親機ができたら試してみたいと思います。
12-17-2021 10:43 PM
12-18-2021 07:26 AM
親機からSDカードに記録できるように変更して見晴らしの良い場所に設置してみました。あいにく雪でした。
モバイルバッテリーは前の晩から動作を続けていたので信頼していたのですが、寒さで給電の閾値が変化したようで事前テストでは途中で給電を停止しました。本番は低電流でも給電停止しないcheroo Canvasに変更しました。
設置場所は見通しが良い緯度、経度が(39.761139,141.1784)のポイントにしました。
結果はQGISで国土地理院ベクトルタイルを使った地図で示します。親機が緑の丸印で、車に乗せられた子機が通信できたポイントが赤丸です。スクリーンショットには距離目盛がありませんがグーグルマップなどで確認ください。
SDカードに記録したデータをLabVIEWで解析してみました。Data Positionのレバーを動かすと経過が分かりやすく表示されます。2秒間隔で送信しているので、データがないところは受信できていないことを示します。(残念ながら受信できなかった位置は表示されていません。)
VIとSDで記録したデータを添付します。
ESP32をコントローラにして、親機から受けた文字列をSDカードに記録するArduinoプログラムも以下添付します。これでも動きましたという程度のプログラムなので参考程度にどうぞ。
//Log GPS data of End Device
#include <Arduino.h>
#include "FS.h"
#include "SD.h"
#include "SPI.h"
File myFile;
String fileName;
String OneLine;
String dateString;
void setup()
{
Serial.begin(9600);//USB Serial
Serial2.begin(9600);//RX16,TX17
if(!SD.begin()){
Serial.println("Card Mount Failed");
return;
}
pinMode(2, OUTPUT);//onboard Blue LED
}
void loop()
{
boolean SD_write=false;
if (Serial2.available()){
digitalWrite(2, HIGH);
OneLine = Serial2.readStringUntil('\n');
dateString=OneLine.substring(15,21);
fileName=String("/log/") + String(dateString) + String(".txt");
Serial.println(OneLine);
Serial.println(dateString);
Serial.println(fileName);
char BufA[50];
fileName.toCharArray(BufA, 50);
char BufB[50];
OneLine.toCharArray(BufB, 50);
appendFileln(SD,BufA,BufB);
}
digitalWrite(2, LOW);
}
void appendFileln(fs::FS &fs, const char * path, const char * message){
File file = fs.open(path, FILE_APPEND);
if(!file){
Serial.println("Failed to open file for appending");
return;
}
if(file.println(message)){
//Serial.println("Message appended");
} else {
Serial.println("Append failed");
}
file.close();
}
MH-ET Live Mini Kit <--> SD
3.3V<--> 3.3V
IO5<--> CS
IO23<--> SDI
IO19<--> SDO
IO18<--> CLK
GND<--> GND
親機との接続ピンは子機同様です。
実験の結果は期待通りでした。母屋のそばの農業ハウスや鶏舎なら十分いけそうな気がします。見通しが良ければ1Km程度はカバーできそうで、もっと飛ばしたい時には外付けアンテナを検討する必要があるでしょう。
状況によりかなり違うと思いますので、試された方はコメントいただけると嬉しいです。
02-13-2022 09:20 AM