ESP8266 + E32 LoRa


E32（EBYTE製）はRxd，TxDを接続するだけで，無線でシリアル通信が出来るデバイスです．UARTが使えればどのマイコンからも簡単に利用できます．SEMTECのSX1276を使っており，無線通信方式はLoraです．
　電源電圧とI/O電圧は3.3～5Vに対応しているので，どのマイコンからでも使いやすいです．

　上記の通り，ただブロードキャストするだけならUARTを接続するだけですが，通信相手を指定するなどの通信パラメータを変えるには，レジストリの設定などが必要です．E32のデータシート（というか取説）は公開されており,ドライバを書けばよいのですが,信号のタイミングを取ったりするのは面倒です．
　ネットで探すと,このための素晴らしいライブラリ<sup>(1)</sup>が公開されているので，これを利用して実験します．ライブラリは高機能であり，その説明用のサイト<sup>(2)</sup>も素晴らしいものですが，いかんせん英語ですので，忘備録としてここにまとめます．

　マイコンはESP8266を使いました．PCとの通信用にハードウェア・シリアルを使っており，通信モジュールのE32とのUART通信にはソフトウェア・シリアルを使いました．espsoftwareserialというライブラリがありますが，今回使用したE32のライブラリとの相性なのかバージョンが古いとうまく動かないとの報告があります．バージョン6.8.0以降であれば問題なく動くようです．

#結線
##ブロードキャストは簡単
　RxD,TxDの2本をつなぎ,E32に3.3～5Vの電源を与えれば動作します．
これだけなら特にライブラリもいらないですね．シリアル通信LoRa電波バラまき機（チャネルだけ合わせれば受信できる）として使えます．
##細かい設定はモード4で
　E32の動作モードは4つあり,M0とM1ピンで設定します．

 モード | 説明 | ピン設定（M1, M0）
|---|---|---|
Mode0 | 通信可能 | 0, 0
Mode1 | 通信可能．送信データにはスリープ端末を起動させるプリアンブルが付く | 0, 1
Mode2 | スリープ．起動プリアンブル付きのデータ受信で起動する | 1, 0
Mode3 | 通信不可．設定を行うモード | 1, 1

　E32では送信出力などの設定もできますが,設定するにはMode3に設定しなければなりません．
そのためM0,M1ピンもマイコンと接続します．AUXピンはバッファの状態を通知したり,いくつか機能がありますが,この際全部結線しておきましょう．

#サンプル・コード
 ホストから文字を受け取って，LoRaで投げるだけです．
逆も同様で，LoRaで受信したら，ホストに投げます．同じ端末を2つ用意して実験してください．
　今回は通信相手を指定せず,ブロードキャストしています．同じチャネルのデバイス全てが受信します．

```C++
#include <Arduino.h>

//#define LoRa_E32_DEBUG
#define FREQUENCY_915  //920MHz帯に設定
#define E32_TTL_100
#include "SoftwareSerial.h"  //espsoftwareserialを利用（ver6．8.0以上）
#include "LoRa_E32.h"

SoftwareSerial mySerial(0, 4); // RX, TX（ピンの設定）
LoRa_E32 e32ttl(&mySerial, 14, 13, 12);  //AUX, M0, M1

void printParameters(struct Configuration configuration);

void setup() {
  Serial.begin(9600);  //ホスト(PC)との通信用
  delay(500);

  e32ttl.begin();    //LoRaモジュール初期化
  
	ResponseStructContainer c;
	c = e32ttl.getConfiguration();
	Configuration configuration = *(Configuration*) c.data;  //設定用オブジェクト取得
	Serial.println(c.status.getResponseDescription());
  	Serial.println(c.status.code);
    Serial.println("======Parameters======");
    printParameters(configuration);  //設定前のパラメータ表示

	configuration.ADDL = 0x01;
	configuration.ADDH = 0x00;
	configuration.CHAN = 0x0F;  //915Mhz (900 + 0x0F * 1MHz = 915MHz)
	configuration.OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION;
	configuration.OPTION.fec = FEC_0_OFF;
  	configuration.SPED.uartBaudRate = UART_BPS_9600;
	configuration.SPED.airDataRate = 10;

	ResponseStatus rs = e32ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE);  //オブジェクトを渡してE32に設定を反映させる
  	Serial.println(rs.getResponseDescription());
 	Serial.println(rs.code);
    Serial.println("======New Parameters======");
  	printParameters(configuration);  //設定後のパラメータ表示
}

void loop() {
	// E32受信処理(E32->Serial)
  if (e32ttl.available()>1) {
	  Serial.println("e32ttl.avialable");
	  // read the String message
	ResponseContainer rc = e32ttl.receiveMessage();
	// エラー表示
	if (rc.status.code!=1){
		rc.status.getResponseDescription();
	}else{
		// シリアルに受信したメッセージを投げる
		Serial.println(rc.data);
	}
  }
    //シリアル受信処理（Serial->E32）
  if (Serial.available()) {
	  Serial.println("Serial.available");
	  String input = Serial.readString();
	  ResponseStatus rs = e32ttl.sendMessage(input);
	  Serial.println(rs.getResponseDescription());
  }
}

//E32の設定値を整形して表示
void printParameters(struct Configuration configuration) {
Serial.println("----------------------------------------");
Serial.print(F("HEAD BIN: "));  Serial.print(configuration.HEAD, BIN);Serial.print(" ");Serial.print(configuration.HEAD, DEC);Serial.print(" ");Serial.println(configuration.HEAD, HEX);
Serial.println(F(" "));
Serial.print(F("AddH BIN: "));  Serial.println(configuration.ADDH, BIN);
Serial.print(F("AddL BIN: "));  Serial.println(configuration.ADDL, BIN);
Serial.print(F("Chan BIN: "));  Serial.print(configuration.CHAN, DEC); Serial.print(" -> "); Serial.println(configuration.getChannelDescription());
Serial.println(F(" "));
Serial.print(F("SpeedParityBit BIN    : "));  Serial.print(configuration.SPED.uartParity, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getUARTParityDescription());
Serial.print(F("SpeedUARTDataRate BIN : "));  Serial.print(configuration.SPED.uartBaudRate, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getUARTBaudRate());
Serial.print(F("SpeedAirDataRate BIN  : "));  Serial.print(configuration.SPED.airDataRate, BIN);Serial.print(" -> "); Serial.println(configuration.SPED.getAirDataRate());
Serial.print(F("OptionTrans BIN       : "));  Serial.print(configuration.OPTION.fixedTransmission, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getFixedTransmissionDescription());
Serial.print(F("OptionPullup BIN      : "));  Serial.print(configuration.OPTION.ioDriveMode, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getIODroveModeDescription());
Serial.print(F("OptionWakeup BIN      : "));  Serial.print(configuration.OPTION.wirelessWakeupTime, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getWirelessWakeUPTimeDescription());
Serial.print(F("OptionFEC BIN         : "));  Serial.print(configuration.OPTION.fec, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getFECDescription());
Serial.print(F("OptionPower BIN       : "));  Serial.print(configuration.OPTION.transmissionPower, BIN);Serial.print(" -> "); Serial.println(configuration.OPTION.getTransmissionPowerDescription());
Serial.println("----------------------------------------");
}
```

#E32の設定
　オブジェクトに各項目を設定していくだけです．メンバ変数への代入orセッター関数で設定可能なようです．

##オブジェクトの取得

```C++
  ResponseStructContainer c = e32ttl.getConfiguration();
  Configuration configuration = *(Configuration*) c.data;
```

##オブジェクトに設定
　取得したオブジェクトに通信用パラメータを設定する

```C++
　　configuration.ADDL = 0x01;  //デバイス固有のID（今回の使い方では意味はない）
　　configuration.ADDH = 0x00;
　　configuration.CHAN = 0x0F;  //915Mhz (900 + 0x0F * 1MHz = 915MHz)
　　configuration.OPTION.fixedTransmission = FT_TRANSPARENT_TRANSMISSION;
```

##設定値を反映

```C++
  ResponseStatus rs = e32ttl.setConfiguration(configuration, WRITE_CFG_PWR_DWN_SAVE);  //E32に設定
  Serial.println(rs.getResponseDescription());  //結果を確認（成功：Success）
  Serial.println(rs.code);  //結果を確認（成功：1）
```

##設定項目一覧

必須 | グループ | 設定項目 | 内容 | 設定値 | 設定値定数
---|---|---|---|---|---
* | SPED | uartParity | シリアル通信パラメータ（ホスト―E32） | 0 ～ 3 | MODE_00_8N1 ～ MODE_11_8N1
* | SPED | uartBaudRate | 有線通信レート（ホスト―E32） | 0 ～ 7 | UART_BPS_1200 ～ UART_BPS_115200
* | SPED | airDataRate | 無線通信レート | 0～7 | AIR_DATA_RATE_000_03～AIR_DATA_RATE_111_192
 | OPTION | fixedTransmission | 送信モード(通信相手を指定するなら1） | 0, 1 | FT_TRANSPARENT_TRANSMISSION, IO_D_MODE_OPEN_COLLECTORFT_FIXED_TRANSMISSION
 | OPTION | ioDriveMode | I/O設定 | 0, 1 | IO_D_MODE_PUSH_PULLS_PULL_UPS, IO_D_MODE_OPEN_COLLECTOR
 | OPTION | wirelessWakeupTime | スリープ復帰時間 | 0～7 | WAKE_UP_250～2000
* | OPTION | FEC | オフにした方が実効通信レートが改善するが，干渉に弱くなる．通信端末同士で設定を合わせないと通信できない | 0, 1 | FEC_0_OFF / FEC_1_ON
 | OPTION | transmissionPower | 送信出力（モジュールTTL100/TTL500/TTL1Wによって設定がことなる） | 0～4 | POWER_20～POWER_10
 | | ADDL | その端末のアドレス（下位） | uint8 | (BROADCAST_ADDRESS)
 | | ADDH | その端末のアドレス（上位） | uint8 | (BROADCAST_ADDRESS)
* | | CHAN | 通信チャネル | 0 ～ |

今日はそこまで！！
[IMG_20200429_201543.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/369631/b90a7620-0465-8bbc-af71-718817ed0576.jpeg)


参考文献
(1)E32ライブラリ
https://github.com/xreef/LoRa_E32_Series_Library

(2)How to use the Library
https://www.mischianti.org/2019/10/15/lora-e32-device-for-arduino-esp32-or-esp8266-specs-and-basic-usage-part-1/

EBYTE公式
http://www.ebyte.com/en/product-view-news.aspx?id=552

総務省 技適未取得機器を用いた実験等の特例制度
https://www.tele.soumu.go.jp/j/sys/others/exp-sp/index.htm!