ESP-IDFを使ってみる

WiFi Power Save機能


esp32にはWiFiのPower Save機能が有りますが、これが原因でWiFi通信が正常にできないことが有ります。
私の場合、UDPのBroadcastメッセージを受信するアプリがどうしても動かなったので、
espressifの技術者に問合せして、WiFiのPower Save機能をOFFにすることで解決しました。

WiFiのPower Save機能では以下の3つのモードを選ぶことができますが、デフォルトでは「WIFI_PS_MIN_MODEM」になっています。
・WIFI_PS_NONE
節電なし
・WIFI_PS_MIN_MODEM
モデム省電力。このモードでは、ステーションはDTIM期間ごとにビーコンを受信するために起動します。
・WIFI_PS_MAX_MODEM
最大モデム省電力。このモードでは、ビーコンを受信する間隔は、wifi_sta_config_tのlisten_intervalパラメー ター によって決まります。

「WIFI_PS_MIN_MODEM」の状態では、UDPのメッセージ受信が正しく動きませんでした。
そこで、以下の様にWiFiの初期化関数の中で、節電なしのモードに変更することで正しく動くようになりました。
void wifi_init_sta()
{
    xEventGroup = xEventGroupCreate();

    tcpip_adapter_init();
    ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL) );

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = EXAMPLE_ESP_WIFI_SSID,
            .password = EXAMPLE_ESP_WIFI_PASS
        },
    };

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );

    wifi_ps_type_t type;
    ESP_ERROR_CHECK(esp_wifi_get_ps(&type));
    ESP_LOGI(TAG,"esp_wifi_get_ps=%d",type);
    if (type == WIFI_PS_NONE) {
        ESP_LOGI(TAG,"WIFI_PS_NONE");
    } else if (type == WIFI_PS_MIN_MODEM) {
        ESP_LOGI(TAG,"WIFI_PS_MIN_MODEM");
    } else if (type == WIFI_PS_MAX_MODEM) {
        ESP_LOGI(TAG,"WIFI_PS_MAX_MODEM");
    }

    ESP_ERROR_CHECK(esp_wifi_set_ps(WIFI_PS_NONE));


    ESP_ERROR_CHECK(esp_wifi_start() );

    ESP_LOGI(TAG, "wifi_init_sta finished.");
    ESP_LOGI(TAG, "connect to ap SSID:%s password:%s",
             EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
}

WiFiのPower Save機能については、こ ちらに少しだけ説明が有りますが、分かるまでメチャクチャはまりました。



こ ちらにWifi Power Saveの公式サンプルが公開されています。
そこで、各モードのping応答時間を測定してみました。
節電なしの時は2ミリ秒ぐらいで応答が戻りますが、モデム省電力モードの時は36ミリ秒ぐらい、
最大省電力モードのときは16ミリ秒ぐらいになります。
最大省電力モードのときは、listen intervalとbeacon timeoutを指定します。
listen interval=3、beacon timeout=6で測定しましたが、これを変えればもっと差が出るかもしれません。

こ ちらのグラフでは、節電なしの時の消費電流は32.18mA、省電力モードの時の消費電流は18.33mAとなっているので、
省電力モードにしたところで、長時間のバッテリー駆動はできません。

・WIFI_PS_NONE 節電なし
$ ping 192.168.10.153 -c 10
PING 192.168.10.153 (192.168.10.153) 56(84) バイトのデータ
64 バイト応答 送信元 192.168.10.153: icmp_seq=1 ttl=64 時間=3.75ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=2 ttl=64 時間=2.74ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=3 ttl=64 時間=2.85ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=4 ttl=64 時間=2.32ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=5 ttl=64 時間=6.12ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=6 ttl=64 時間=2.45ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=7 ttl=64 時間=4.39ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=8 ttl=64 時間=2.39ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=9 ttl=64 時間=2.36ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=10 ttl=64 時間=2.37ミリ秒

--- 192.168.10.153 ping 統計 ---
送信パケット数 10, 受信パケット数 10, パケット損失 0%, 時間 9016ミリ秒
rtt 最小/平均/最大/mdev = 2.323/3.173/6.116/1.179ミリ秒

・WIFI_PS_MIN_MODEM モデム省電力モード
$ ping 192.168.10.153 -c 10
PING 192.168.10.153 (192.168.10.153) 56(84) バイトのデータ
64 バイト応答 送信元 192.168.10.153: icmp_seq=1 ttl=64 時間=36.6ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=2 ttl=64 時間=54.4ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=3 ttl=64 時間=73.6ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=4 ttl=64 時間=94.6ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=5 ttl=64 時間=117 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=6 ttl=64 時間=446 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=7 ttl=64 時間=577 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=8 ttl=64 時間=86.3ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=9 ttl=64 時間=105 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=10 ttl=64 時間=130 ミリ秒

--- 192.168.10.153 ping 統計 ---
送信パケット数 10, 受信パケット数 10, パケット損失 0%, 時間 9013ミリ秒
rtt 最小/平均/最大/mdev = 36.566/172.004/576.777/174.202ミリ秒

・WIFI_PS_MAX_MODEM 最大モデム省電力モード
$ ping 192.168.10.153 -c 10
PING 192.168.10.153 (192.168.10.153) 56(84) バイトのデータ
64 バイト応答 送信元 192.168.10.153: icmp_seq=1 ttl=64 時間=284 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=2 ttl=64 時間=83.5ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=3 ttl=64 時間=311 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=4 ttl=64 時間=130 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=5 ttl=64 時間=358 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=6 ttl=64 時間=77.6ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=7 ttl=64 時間=198 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=8 ttl=64 時間=16.4ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=9 ttl=64 時間=245 ミリ秒
64 バイト応答 送信元 192.168.10.153: icmp_seq=10 ttl=64 時間=64.6ミリ秒

--- 192.168.10.153 ping 統計 ---
送信パケット数 10, 受信パケット数 10, パケット損失 0%, 時間 9011ミリ秒
rtt 最小/平均/最大/mdev = 16.376/176.807/358.042/112.447ミリ秒

続く...