電池動作での長時間化を狙って、ESP8266/ESP32での直接通信モードのESP-Nowを試してみます。
ESP-NowはEspressifの説明によれば、「ESP-NOWは、Espressifによって開発されたさらに別のプロトコルであり、Wi-Fiを使用せずに複数のデバイスが相互に通信できるようにします。このプロトコルは、ワイヤレスマウスによく使用される低電力2.4GHzワイヤレス接続に似ています。したがって、デバイス間のペアリングは、通信の前に必要です。ペアリングが完了すると、接続は安全でピアツーピアになり、ハンドシェイクは必要ありません。」(Google翻訳による)ということで、Wi-Fiのような複雑なプロトコルではないので、通信にかかる時間が短く=消費電力が削減されることが期待できます。
ESP-Nowのドキュメントはこちらになるのですが、今回は簡単にArduino環境のライブラリSimpleEspNowConnection(ライブラリマネージャからインストールできる)を使って、送信側にESP8266、受信側にESP32で動作させました。ESP-Nowでespressifから提供されているAPIはESP8266とESP32で異なっているのですが、SimpleEspNowConnectionはその差分も吸収してくれます。
想定する使い方は、電池で動くセンサー側から、PCもしくはRaspberry Piに接続されたホスト側に測定データを送信する、という使い方です。本来、ESP-Nowは双方向で通信ができるのですが、今回はこの使い方に絞った形でテストしてみました。
まずは受信側のコードです。これは、ライブラリのサンプルプログラム(SimpleEspNowConnectionServer.ino)をさらに簡略化したもので、ESP32で動作させました。
#include "SimpleEspNowConnection.h"
SimpleEspNowConnection simpleEspConnection(SimpleEspNowRole::SERVER);
String clientAddress;
void OnMessage(uint8_t* ad, const uint8_t* message, size_t len)
{
Serial.printf("MESSAGE:[%d]%s from %s\n", len, (char *)message, simpleEspConnection.macToStr(ad).c_str());
}
void setup()
{
Serial.begin(115200);
Serial.println();
simpleEspConnection.begin();
simpleEspConnection.setPairingBlinkPort(2);
simpleEspConnection.onMessage(&OnMessage);
Serial.println(WiFi.macAddress());
}
void loop()
{
simpleEspConnection.loop();
}
次に送信側のコードです。これも、ライブラリのサンプルプログラム(SimpleEspNowConnectionClient.ino)をさらに簡略化したもので、テストではESP8266で動作させました。
#include "SimpleEspNowConnection.h"
SimpleEspNowConnection simpleEspConnection(SimpleEspNowRole::CLIENT);
String serverAddress;
void OnSendError(uint8_t* ad)
{
Serial.println("SENDING TO '"+simpleEspConnection.macToStr(ad)+"' WAS NOT POSSIBLE!");
}
void OnSendDone(uint8_t* ad)
{
Serial.println("SENDING TO '"+simpleEspConnection.macToStr(ad)+"' WAS DONE!");
}
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.println("Setup...");
simpleEspConnection.begin();
simpleEspConnection.setPairingBlinkPort(2);
serverAddress = "012345ABCDEF"; // 受信側のMACアドレス
simpleEspConnection.setServerMac(serverAddress);
simpleEspConnection.onSendError(&OnSendError);
simpleEspConnection.onSendDone(&OnSendDone);
Serial.println(WiFi.macAddress());
}
void loop()
{
static int n=1;
static char buf[32];
simpleEspConnection.loop();
sprintf(buf,"%d",n++);
simpleEspConnection.sendMessage(buf);
delay(1000);
}
これで実際に動作させることができました。
送信に成功した場合、失敗した場合でそれぞれコールバック関数が呼ばれるので、それに応じた処理を記述することができそうです。例えば、成功した場合には2分間のディープスリープ、失敗した場合には5秒間のディープスリープとして再トライさせるなどの使い方になると思います。
分かりやすい解説ありがとうございます。
受信側のスケッチをコンパイル時に「ボードESP32 Dev Moduleに対するコンパイル時にエラーが発生しました。」でエラー停止してしまいます、エラー内容を確認するとTickerの使用時で終了しているようです、何か気付くところがあれば御指摘いただけませんでしょうか。