M5StickCでESP-NOW その2

現時点の情報です。最新情報はM5StickC非公式日本語リファレンスを確認してみてください。

概要

ESP-NOWの消費電力を検証しました。想定よりかなり省電力でした。

新規作成の空の状態から、コードを追加していって、どれだけ消費電力が変わるのかを確認しました。

検証したスケッチ

#include <M5StickC.h>
#include <esp_now.h>
#include <WiFi.h>

esp_now_peer_info_t slave;

// 送信コールバック
void OnDataSent(const uint8_t *mac_addr, esp_now_send_status_t status) {
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.print("Last Packet Sent to: ");
  Serial.println(macStr);
  Serial.print("Last Packet Send Status: ");
  Serial.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");

  // 画面にも描画
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.print("Last Packet Sent to: \n  ");
  M5.Lcd.println(macStr);
  M5.Lcd.print("Last Packet Send Status: \n  ");
  M5.Lcd.println(status == ESP_NOW_SEND_SUCCESS ? "Delivery Success" : "Delivery Fail");
}

// 受信コールバック
void OnDataRecv(const uint8_t *mac_addr, const uint8_t *data, int data_len) {
  char macStr[18];
  snprintf(macStr, sizeof(macStr), "%02X:%02X:%02X:%02X:%02X:%02X",
           mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]);
  Serial.printf("Last Packet Recv from: %s\n", macStr);
  Serial.printf("Last Packet Recv Data(%d): ", data_len);
  for ( int i = 0 ; i < data_len ; i++ ) {
    Serial.print(data[i]);
    Serial.print(" ");
  }
  Serial.println("");

  // 画面にも描画
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setCursor(0, 0);
  M5.Lcd.print("Last Packet Recv from: \n  ");
  M5.Lcd.println(macStr);
  M5.Lcd.printf("Last Packet Recv Data(%d): \n  ", data_len);
  for ( int i = 0 ; i < data_len ; i++ ) {
    M5.Lcd.print(data[i]);
    M5.Lcd.print(" ");
  }
}

void setup() {
  M5.begin();
  M5.Lcd.fillScreen(BLACK);
  M5.Lcd.setRotation(3);
  M5.Lcd.print("ESP-NOW Test\n");

  // ESP-NOW初期化
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  if (esp_now_init() == ESP_OK) {
    Serial.println("ESPNow Init Success");
    M5.Lcd.print("ESPNow Init Success\n");
  } else {
    Serial.println("ESPNow Init Failed");
    M5.Lcd.print("ESPNow Init Failed\n");
    ESP.restart();
  }

  // マルチキャスト用Slave登録
  memset(&slave, 0, sizeof(slave));
  for (int i = 0; i < 6; ++i) {
    slave.peer_addr[i] = (uint8_t)0xff;
  }
  esp_err_t addStatus = esp_now_add_peer(&slave);
  if (addStatus == ESP_OK) {
    // Pair success
    Serial.println("Pair success");
  }

  // ESP-NOWコールバック登録
  esp_now_register_send_cb(OnDataSent);
  esp_now_register_recv_cb(OnDataRecv);
}

void loop() {
  M5.update();

  // ボタンを押したら送信
  if ( M5.BtnA.wasPressed() ) {
    uint8_t data[2] = {123, 234};
    esp_err_t result = esp_now_send(slave.peer_addr, data, sizeof(data));
    Serial.print("Send Status: ");
    if (result == ESP_OK) {
      Serial.println("Success");
    } else if (result == ESP_ERR_ESPNOW_NOT_INIT) {
      Serial.println("ESPNOW not Init.");
    } else if (result == ESP_ERR_ESPNOW_ARG) {
      Serial.println("Invalid Argument");
    } else if (result == ESP_ERR_ESPNOW_INTERNAL) {
      Serial.println("Internal Error");
    } else if (result == ESP_ERR_ESPNOW_NO_MEM) {
      Serial.println("ESP_ERR_ESPNOW_NO_MEM");
    } else if (result == ESP_ERR_ESPNOW_NOT_FOUND) {
      Serial.println("Peer not found.");
    } else {
      Serial.println("Not sure what happened");
    }
  }

  delay(1);
}

スケッチは基本その1と変わっていません。

実験結果

状態消費電力差分備考
空プロジェクト48.754
delay(1)30.225-18.529
M5.begin()53.25223.027
WiFi.mode(WIFI_STA)55.2261.974ブレ有り
WiFi.disconnect()55.7120.486ブレ有り
esp_now_init()+CB56.6070.895ブレ有り
100ms間隔送信56.6070ブレ有り
10ms間隔送信59.4072.8ブレ有り

空プロジェクト

新規作成したmain()とloop()が空の状態。この状態からの差分を検証しています。

AXP192などの状態が前回実行した物が残っている可能性がありますので、一度スケッチを転送したあとに電源を切って、AXP192が初期状態で立ち上がっている状態で測定しています。

delay(1)

loop()にdelay(1)を追加した状態。delay(1)がないと無限ループでずーっと実行しているので、最低限1を入れたほうがいいです。

この数値を大きくすると、若干は消費電力が下がりますが、0.1mA単位の変更ですのであまり差はありませんでした。

M5.begin()

main()にてM5.begin()を追加して、AXP192の初期化を行います。これにより画面に電力が供給されるので20mA以上消費電力が増加します。

主に画面で利用されているので、明るさを落とすことでより省電力になります。

WiFi.mode(WIFI_STA)

main()にてWiFi.mode(WIFI_STA)を追加しました。Wi-Fiの初期化だけですが、2mA程度消費電力が増加しました。思ったより少ないですね。

Wi-FiをONにしてからの消費電力は波があり、0.5mA程度は増減しているので、ここ以降は少し測定精度が低いです。一応30秒以上計測した平均を計測しています。

WiFi.disconnect()

さらにWiFi.disconnect()を追加しましたが、消費電力に差は見られませんでした。

esp_now_init()+CB

さらにESP-NOWの初期化と、コールバック関数の追加を行いました。ここでも大きな消費電力の増減はありませんでした。

100ms間隔送信

手で送信を連打しても消費電力に差は見られなかったので、100ms間隔で送信するように書き換えましたが、それでも消費電力に明確な差は見られませんでした。

10ms間隔送信

10msまで送信頻度をあげたところ、やっと消費電力の増加がわかりました。

上記がテスト中の画像ですが、未送信と100msではほとんど差がわかりません。10msになると消費電力が上がっているのがわかります。数値が低下しているのがUSB経由でプログラムを書き込んでいる時間です。

まとめ

ESP-NOWを利用すると、100ms間隔ぐらいまでの送信であれば3mA程度の消費電流があります。10ms間隔にすると更に3mA程度消費電流が増えますが、かなり省電力で通信ができるのでびっくりです。

コメント

  1. n_shinichi より:

    よく参考にさせて頂いてます。ありがとうございます。

    ESP-01(ESP8266)でESP-NOW使った時の消費電流調べられたことはありますでしょうか。