energy note

色々と勉強中なので備忘録として。

E220-900T22S(JP)で遊んでみる

IoT的な電子工作して遊びたいのですが、その中でもネットにつなぐほどでもなかったりするアイディアもあったりします。
以前からLoRaの通信モジュール自体は販売されていたのですが、対のモジュールで2万円近くして、この手の部品ではなかなか高額な部類。
akizukidenshi.com
それが今では対で4000円ほどで買えるまでになっています!これで数kmもの距離を通信できるとか超胸熱ですよね!
モジュールの仕様などはHPから手に入りますしデータシートなども普通に落ちてます。
通信用のプログラムもアップされています。(E220-900T22S(JP)用ではなさそうですが使えた)
github.com
GPUの通信モジュールがあれば、住居からどのくらいまで飛ぶかなーみたいなことをやりたかったのですが、手持ちがないので受信したら受信できたぞ、と送り返すプログラムを作り、部屋に1台置いておいて、1台を持ち出してどのくらい通信できるか遊んでみました。



ネットにサンプルがあまり無いので、さきほどのGitHubのライブラリを使ったコードを載せておきます。
私はESP32で通信させましたので、以下の設定でしました。

LoRa_E220 e220ttl(&Serial2, 33, 25, 26); //  RX AUX M0 M1

TX2、RX2に接続し、AUXとM0、M1は任意のIOに接続して設定します。

次にvoid setup()内でパラメータの設定をします。(examples内の01_setConfiguration.ino参照)

//以下はvoid setup()内に置く
	configuration.ADDL = 0x00;  // First part of address
	configuration.ADDH = 0x00; // Second part

	configuration.CHAN = 0; // Communication channel

	configuration.SPED.uartBaudRate = UART_BPS_9600; // Serial baud rate
	configuration.SPED.airDataRate = AIR_DATA_RATE_010_24; // Air baud rate
	configuration.SPED.uartParity = MODE_00_8N1; // Parity bit

	configuration.OPTION.subPacketSetting = SPS_200_00; // Packet size
	configuration.OPTION.RSSIAmbientNoise = RSSI_AMBIENT_NOISE_DISABLED; // Need to send special command
	configuration.OPTION.transmissionPower = POWER_13; // Device power

	configuration.TRANSMISSION_MODE.enableRSSI = RSSI_DISABLED; // Enable RSSI info
	configuration.TRANSMISSION_MODE.fixedTransmission = FT_TRANSPARENT_TRANSMISSION; // Enable repeater mode
	configuration.TRANSMISSION_MODE.enableLBT = LBT_DISABLED; // Check interference
	configuration.TRANSMISSION_MODE.WORPeriod = WOR_2000_011; // WOR timing

前後のコードはサンプルを確認してください。上記はデフォルトで1対1で通信する設定です。
サンプルの中で書き換えなければいけない部分が

configuration.OPTION.transmissionPower = POWER_22;

の部分で、E220-900T22S(JP)だと22dBmに対応していないようなのでPOWER_13(13dBm)に変更します。
アドレスとかチャンネルは任意に変えました。

送信機はテストメッセージを送信して、受信機に送り、受信機側で受信出来たら受信出来たよ、と送信機に対してメッセージを送る形にしています。
<送信機>
ボタンON待機→メッセージ送信→受信待機→受信したら受信したことを表示
<受信機>
受信待機→受信した→受信した旨を送信機に対して送信→受信待機

以下は送信機用のコードです。(送信用コードはexamples内の02_sendTransparentTransmission.ino参照)

#define send_button_pin 27     //送信ボタンの入力ピン
int button_no = 0;

void IRAM_ATTR sendbtn() { //sendボタン
  delayMicroseconds(250);  //チャタリング防止
  if ((digitalRead(send_button_pin) == LOW) and (button_no == 0)){
    button_no = 1;
  }
}

//これはvoid setup() 内に置く
  attachInterrupt(send_button_pin, sendbtn, FALLING);  //sendボタンの割り込み

//これはvoid loop()内に置く
//受信待機
  if (e220ttl.available()>1) {
	  Serial.println("Message received!");

	  // read the String message
#ifdef ENABLE_RSSI
	ResponseContainer rc = e220ttl.receiveMessageRSSI();
#else
	ResponseContainer rc = e220ttl.receiveMessage();
#endif
	// Is something goes wrong print error
	if (rc.status.code!=1){
		Serial.println(rc.status.getResponseDescription());
	}else{
		// Print the data received
		Serial.println(rc.status.getResponseDescription());
		Serial.println(rc.data);
#ifdef ENABLE_RSSI
		Serial.print("RSSI: "); Serial.println(rc.rssi, DEC);
#endif
	}
  }
//メッセージ送信
  if(button_no == 1){

    // Send message
    ResponseStatus rs = e220ttl.sendMessage("test message");
    // Check If there is some problem of succesfully send
    Serial.println(rs.getResponseDescription());

    e220ttl.begin();
    button_no = 0;
  }

受信待機のコードは07_receiveMessages.inoから丸コピです。
ボタン回路の構成は押しボタンスイッチをプルアップしておいてONになるとGNDに落ちる(LOW)ようにしています。
その際割り込みでbutton_no = 1になるとloop内で送信用のコードが動くようになっています。
送信用コードの最後にe220ttl.begin();を付けないと数回動作を繰り返すと送受信出来なくなるので解決策として正しいかまだわかっていませんが挿入しています。(送信専用機、受信専用機、みたいな使い方だと入れなくても何の問題もなく動きます)

次に受信機側です。

    if (e220ttl.available()>1) {
      digitalWrite(ledPin, HIGH);
      Serial.println("Message received!");
      // read the String message
    ResponseContainer rc = e220ttl.receiveMessageRSSI();

    // Is something goes wrong print error
    if (rc.status.code!=1){
      Serial.println(rc.status.getResponseDescription());
    }else{
      // Print the data received
      Serial.println(rc.status.getResponseDescription());
      Serial.println(rc.data);
      Serial.print("RSSI: "); Serial.println(rc.rssi, DEC);
    }

    delay(500);
    e220ttl.begin();
    
    Serial.print("send message");
    // Send message
    ResponseStatus rs = e220ttl.sendMessage("OK!");
    // Check If there is some problem of succesfully send
    Serial.println(rs.getResponseDescription());

    digitalWrite(ledPin, LOW);

    }

ちょっとexamplesのコードを簡略化しました。(RSSIは有効になっている前提です)
受信したことをledpin(ESP32のモジュールではGPIOの2番)に出力して基板上の青色LEDを光らせました。
一応送信機側の体制を整えることも必要かとdelay(500);を入れました。その後に例のe220ttl.begin();。
受信してすぐに送信機側に受信したことを知らせるメッセージを送り、また待機に入ります。

上記コードでとりあえずモジュールで送受信の確認ができました。何か参考になれば幸いです。
これで割と長距離の通信ができることがわかったのでセンサーか電力監視か何かに使えれば面白そうだなーと思っています。