マイコン間無線通信は、この1年ESP-NOWに集中して使ってきました。しかし、1パケット250Byteの制限があって使えない用途があったので、WiFiを使った他の通信方式を調査してみました。TCPとUDPがあって、違いは、こちらに解説記事がありました。必要なのは高速(460800bps以上)低遅延(1msec以内)とロス率が低い(3σ以上)
ですので、TCPは遅延(数十~百msec)が大きすぎて使えませんのでUDPとなります。
信州MAKRESでの、UDPカテゴリ記事群 https://shinshu-makers.net/shinshu_makers/?s=UDP
※2024/2/16 スキー場でUDPを使った計測成功しました。=>1-2m距離で使う用途のみでOKで、5mも離れるとデータ落ち1ー2%発生します。
UDPは、1~2m距離以内で使えばデータ落ちの確率は3σ以下に収まります。スキーにつけたESP32から背中のタブレットまでのUDP通信が実使用OKでした。
スキー滑走計測4年目で、初めてUDPを採用しましたが、ESP-NOW、Bluetoothより信頼性が高かったです。足元から背中のタブレットまでの1-2m距離なら、センサ系のデータロス率が0.4-0.1%でUDPのパケットロスは皆無でした。
【STA24】スキー場実測その1<この4年で最高品質>
●SIM無しのポケットWifiを使って、マイコンとPC、タブレット間で通信する方法でデータをログしてます。マイコン側SDカード省略できました。【STA24】ESP32デバッグとUDP端末IP固定設定<ポケットWifi2個使い>
◎1-2m距離間の無線通信なら、UDPがおすすめです。ポケットWiFiさえあれば、UDPは、気軽に使えます。(SIM無しで使えます)
=>UDPは、電波状態でエラー率がコロコロ変わるので、アンテナ性能が良いものを使えば距離を稼げるのではないかと思います。
※2024年正月休みに2年ぶりにUDPをいじってみました
。UDP採用すると計測システムの断捨離が進みます。速さは正義です。
ESP32にGNSS F9PとIMU BNO085を接続してデータをリアルタイムにPCへUDP送信してます。数十cmの近距離ならデータ信頼性は上がります。5m離すと桁違いにデータ落ち増えます。ここでのパケットサイズ172byteで速度は1-3Mbpsでばらつきます。120Kbpsの格安低速SIMのポケットWiFiで接続してますが速いです。
【STA24】ESP32ベースでBNO085とRTKF9PデータUDP無線ログ<シンプルにした>
【STA24】UDP採用でシステムを断捨離その1<Teensy廃止ESP32のみでトライ>
●UDPの調査
User Datagram Protocol https://www.nic.ad.jp/ja/basics/terms/udp.html
送信するだけ、受信するだけで、互いに確認する手段をもたないシンプルな通信方式です。
2線のシリアル通信も確認手段をもたないので同じですが、有線なので、ノイズなど外乱が少ないので安定した通信ができますが、無線規格で確認手段を持たないのは不安です。
ちなみに現在使っているESP-NOWでは、CallBack機能がついているので一応確認機能がありますが、パケットサイズが大きくなるとロス率が大きくなる傾向があります。
他に検索した記事
第7回 TCPとUDPの違い, 深層の真相
https://gihyo.jp/admin/serial/01/net_prac_tech/0007
TCPとUDPの違いとは?~Ethernet接続におけるオーバーヘッド削減ノウハウ~https://hldc.co.jp/blog/2019/07/11/2819/
おなじみLangShip様の解説 分かり易いです。感謝!
UDPによりデータの送受信(VisualStudio)を行うhttps://dobon.net/vb/dotnet/internet/udpclient.html
ESP32のAsyncUDPを調べる https://lang-ship.com/blog/work/esp32-asyncudp/
●探しあてたサンプルコード
ESP32でのUDP記事は、ルーター無しで、ESP32同士接続する事例は非常に少なかったです。その中でようやく探しあてたのが
ceramie様のブログに感謝です。ESP32同士によるwifiUDP通信
ここでは、ESP32同士で2個のESP32でUDP通信テストプログラムあります。
サーバーとクライアントと呼んでいて、UDPでは、クライアントが送信して
受信するのがサーバーというのが普通だそうです。
※コードが非常にシンプルで、ESP-NOWよりシンプルでこれでいいのか不安になるくらいです。
●オリジナルコードに対してデータ落ち実験用に変更した箇所
①送信側クライアント:0~255を繰り返して1000バイト作って1パケットとして送信するようにしました。
送信側クライアント:https://gist.github.com/dj1711572002/2e054faa4a89bed895deb1c818a2fafc
送信処理は3行だけです。wifiUdp.beginPacket /wifiUdp.write()/wifiUdp.endPacket
void setup() { Serial_setup(); WiFi_setup();for (i=0;i<1000;i++) { tim[i]=i%255; Serial.print(“tim[“); Serial.print(i); Serial.print(“]=”); Serial.println(tim[i]); } }void loop() { wifiUdp.beginPacket(kRemoteIpadr, kRmoteUdpPort); wifiUdp.write(tim,999); //10進数のASCiiで送信される どういうわけか1000だとエラーになる wifiUdp.endPacket(); delay(1); } |
②受信側サーバー:受信データ数とタイムスタンプをSerial.printするようになってます。
受信側サーバー:https://gist.github.com/dj1711572002/7ca7fbbe680265121e57be141433bd1b
void loop() { j=udp.parsePacket();//受信バイト数if (j>1) { uint8_t k = udp.read(data,1000); //1000バイト読み込むSerial.print(“,j=”); Serial.print(j); Serial.print(“,”); Serial.print(millis()); Serial.println(“,msec”);} |
●受信信頼性実験
上記999バイトパケットを1msecDelayで10分間送受信したログを解析
パケットで999バイト入っているか、受信周期ばらつきが一定範囲にはいっているかで判定しました。
使ったCPUは、ESP32-DevKit2個間とM5Atomlite2個間とCPUを2種類で実験
①ESP32-DevKitを2個間でUDP通信
10分間で、34万7千パケット受信
結果1:1msecDelayで1.73msec±1.336msec周期で受信できているのでmsec以下で1KByte送受信できている=>8000bit/msec=8000000bit/sec相当シリアル460800bpsの17倍速い
結果2:パケットデータ落ちはゼロ
=>結果が良すぎるので、これからいろいろいじめてみないと実力がわからない
②M5Atom liteを2個間でUDP通信
結果1:パケット周期2.026±4.02msecとESP32よりばらつきが倍以上悪い
結果2:パケットデータ落ちはゼロ
結果3:ESP32より通信信頼性が劣るのは、CPU性能が効いていると思われる
=>ESP32は、ESP32 Wroom32D M5Atom lite はESP32-PICO-D4でハード仕様は
ほとんど同じなので、外だしアンテナが大きなものがついているESP32DEVKITのほうが無線の外乱に強いからではないかと思います。
●以後
実際のF9P RTKシステムで、MovingBaseモードでBaseとRover間を現在460800bpsシリアルで接続しているのをUDPで接続してみて、RTKデータの精度がどうなるか実験検証していきます。