概要
ESP-NOWは通信速度がデフォルトで1Mbpsに設定されています。速度を変更しつつ、どの程度時間が変わるのかを検証してみました。
検証に利用したコード
#include <esp_now.h>
#include <esp_wifi.h>
#include <WiFi.h>
esp_now_peer_info_t slave;
QueueHandle_t xQueueMailbox;
void onDataSent(const uint8_t* mac_addr, esp_now_send_status_t status) {
xQueueSend(xQueueMailbox, nullptr, 0);
}
void setup() {
Serial.begin(115200);
delay(1000);
Serial.println("================================================");
xQueueMailbox = xQueueCreate(1, (size_t)0);
WiFi.mode(WIFI_STA);
esp_wifi_set_channel(1, WIFI_SECOND_CHAN_NONE);
Serial.print("STA MAC: ");
Serial.println(WiFi.macAddress());
Serial.print("STA CHANNEL ");
Serial.println(WiFi.channel());
WiFi.disconnect();
esp_now_init();
esp_wifi_config_espnow_rate(WIFI_IF_STA, WIFI_PHY_RATE_54M);
esp_now_register_send_cb(onDataSent);
for (int i = 0; i < 6; ++i) {
slave.peer_addr[i] = (uint8_t)0xff;
}
esp_err_t addStatus = esp_now_add_peer(&slave);
}
void loop() {
uint8_t data[250] = {};
size_t sizeList[] = { 1, 50, 100, 150, 200, 250 };
//size_t sizeList[] = { 1, 250 };
static size_t size = 0;
static uint8_t speed = 0;
char* speedList[] = {
"WIFI_PHY_RATE_1M_L",
"WIFI_PHY_RATE_2M_L",
"WIFI_PHY_RATE_5M_L",
"WIFI_PHY_RATE_11M_L",
"",
"WIFI_PHY_RATE_2M_S",
"WIFI_PHY_RATE_5M_S",
"WIFI_PHY_RATE_11M_S",
"WIFI_PHY_RATE_48M",
"WIFI_PHY_RATE_24M",
"WIFI_PHY_RATE_12M",
"WIFI_PHY_RATE_6M",
"WIFI_PHY_RATE_54M",
"WIFI_PHY_RATE_36M",
"WIFI_PHY_RATE_18M",
"WIFI_PHY_RATE_9M",
""
};
int count = 1000;
unsigned long time = 0;
unsigned long minTime = 9999999;
unsigned long maxTime = 0;
esp_wifi_config_espnow_rate(WIFI_IF_STA, (wifi_phy_rate_t)speed);
for (int i = 0; i < count; i++) {
unsigned long startTime = micros();
esp_err_t result = esp_now_send(slave.peer_addr, data, sizeList[size]);
xQueueReceive(xQueueMailbox, nullptr, portMAX_DELAY);
unsigned long oneTime = micros() - startTime;
time += oneTime;
minTime = min(minTime, oneTime);
maxTime = max(maxTime, oneTime);
}
Serial.printf("speed = %s(0x%02x), count = %d, size = %d, time = %d, time/count = %d, minTime = %d, maxTime = %d\n", speedList[speed], speed, count, sizeList[size], time, time / count, minTime, maxTime);
if (sizeList[size] == 250) {
size = 0;
speed++;
if (speed == 0x10) {
while (1) {
delay(1);
}
}
} else {
size++;
}
delay(100);
}
速度と送信長を変更しつつ1000回送信するプログラムです。送信完了するとコールバック関数が呼ばれるのでキューを使って、送信完了待ちをしています。
送信先はブロードキャストのff:ff:ff:ff:ff:ffですので、送信は投げっぱなしで受信確認はしていません。
速度1Mbpsで送信長別の送信時間
送信長(バイト) | 平均送信時間(us) | 最小送信時間(us) | 最大送信時間(us) |
---|---|---|---|
1 | 884 | 754 | 5,434 |
50 | 1,282 | 1,155 | 4,675 |
100 | 1,719 | 1,545 | 5,293 |
150 | 2,144 | 1,955 | 5,571 |
200 | 2,571 | 2,349 | 8,714 |
250 | 2,975 | 2,751 | 9,114 |
ESP-NOWは1バイトから250バイトまでのデータを送信できるので、送信長別に送信にかかった速度を計測しています。単位はμ秒になります。概ね送信長に比例して送信時間が伸びています。最小の1バイトでは1ミリ秒弱、最長の250バイトで3ミリ秒弱かかっています。
特記事項として、ESP-NOWは送信しっぱなしなのですが、送信時間にばらつきがあります。最大のところをみてみると5ミリ秒から9ミリ秒程度送信にかかっている場合があります。このへんは周りの電波状況等に応じて変わってくるところだと思います。
速度別1バイト送信
速度 | 平均送信時間(us) | 最小送信時間(us) | 最大送信時間(us) |
---|---|---|---|
WIFI_PHY_RATE_54M(0x0c) | 314 | 228 | 3,825 |
WIFI_PHY_RATE_36M(0x0d) | 321 | 232 | 3,984 |
WIFI_PHY_RATE_48M(0x08) | 324 | 237 | 3,930 |
WIFI_PHY_RATE_24M(0x09) | 335 | 243 | 4,957 |
WIFI_PHY_RATE_18M(0x0e) | 343 | 244 | 4,040 |
WIFI_PHY_RATE_12M(0x0a) | 349 | 252 | 3,939 |
WIFI_PHY_RATE_9M(0x0f) | 349 | 265 | 2,988 |
WIFI_PHY_RATE_6M(0x0b) | 380 | 284 | 3,968 |
WIFI_PHY_RATE_11M_S(0x07) | 447 | 338 | 4,030 |
WIFI_PHY_RATE_5M_S(0x06) | 462 | 369 | 4,408 |
WIFI_PHY_RATE_11M_L(0x03) | 535 | 437 | 4,106 |
WIFI_PHY_RATE_5M_L(0x02) | 571 | 465 | 4,192 |
WIFI_PHY_RATE_2M_S(0x05) | 590 | 482 | 4,263 |
WIFI_PHY_RATE_2M_L(0x01) | 701 | 577 | 5,623 |
WIFI_PHY_RATE_1M_L(0x00) | 884 | 754 | 5,434 |
送信長を最小の1バイトに固定して、通信速度を変更した例になります。1Mbpsから54Mbpsまで選択が可能ですが、速度の比と比べると送信時間の差はあまりありません。そして最大送信時間は4ミリ秒程度であまり変わっていません。
速度別250バイト送信
速度 | 平均送信時間(us) | 最小送信時間(us) | 最大送信時間(us) |
---|---|---|---|
WIFI_PHY_RATE_54M(0x0c) | 362 | 278 | 4,238 |
WIFI_PHY_RATE_48M(0x08) | 371 | 287 | 3,871 |
WIFI_PHY_RATE_36M(0x0d) | 387 | 306 | 3,905 |
WIFI_PHY_RATE_24M(0x09) | 440 | 322 | 5,701 |
WIFI_PHY_RATE_18M(0x0e) | 441 | 365 | 3,802 |
WIFI_PHY_RATE_12M(0x0a) | 546 | 442 | 4,243 |
WIFI_PHY_RATE_9M(0x0f) | 585 | 488 | 3,853 |
WIFI_PHY_RATE_11M_S(0x07) | 619 | 521 | 4,013 |
WIFI_PHY_RATE_11M_L(0x03) | 731 | 620 | 4,462 |
WIFI_PHY_RATE_6M(0x0b) | 740 | 630 | 4,306 |
WIFI_PHY_RATE_5M_S(0x06) | 886 | 744 | 5,971 |
WIFI_PHY_RATE_5M_L(0x02) | 994 | 838 | 9,826 |
WIFI_PHY_RATE_2M_S(0x05) | 1,647 | 1,481 | 5,103 |
WIFI_PHY_RATE_2M_L(0x01) | 1,755 | 1,573 | 5,350 |
WIFI_PHY_RATE_1M_L(0x00) | 2,975 | 2,751 | 9,114 |
最長の250バイトを送信する場合には速度の設定で時間に差ができています。
LとS?
2Mと5Mと11MにはLとSがあり、Sの方が少し早いです。
上記の説明がわかりやすかったのですが、PLCPプリアンブルのデータの違いによります。その無線パケットの通信速度を渡すためのデータで、ここは低速で通信され、実際のデータ部分は指定した速度で高速通信するような形になっていました。
そしてロングとショートがあり、ショートの方が通信速度も早いようです。ただし、ロングの標準的で、オプションとしてショートがある関係性のようです。
まとめ
受信や速度に応じて消費電力や距離なども調べたかったですが現在準備中のarduino-esp32の3系(ESP-IDF5.1系)でESP-NOWまわりの関数群がガラッと変わっていましたので新しいバージョンがでたら検証しなおしてみたいと思います。
コメント