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();。
受信してすぐに送信機側に受信したことを知らせるメッセージを送り、また待機に入ります。
上記コードでとりあえずモジュールで送受信の確認ができました。何か参考になれば幸いです。
これで割と長距離の通信ができることがわかったのでセンサーか電力監視か何かに使えれば面白そうだなーと思っています。
屋内PC横→コンクリの建物3棟ほど隔てて見通せない場所になると100mほどで通信出来なくなる。LoRaにしてもこの条件だときついか。設定次第でもう少し伸ばせるかな?
— yoshi💉💉💉 (@yoshi96648555) 2023年3月19日
これ持ってウロウロしてたから何度か通行人に二度見された・・・w通報されていないことを祈る・・・ pic.twitter.com/rlPvDuUYuJ