ESP32省電模式連接WIFI筆記


基於ESP-IDF4.1版本

main.c文件如下:

#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#include "esp_pm.h"

#include "lwip/err.h"
#include "lwip/sys.h"


//值在sdkconfig中配置
#define ESP_WIFI_SSID      CONFIG_ESP_WIFI_SSID
#define ESP_WIFI_PASS      CONFIG_ESP_WIFI_PASSWORD
#define ESP_MAXIMUM_RETRY  CONFIG_ESP_MAXIMUM_RETRY

#define DEFAULT_LISTEN_INTERVAL CONFIG_WIFI_LISTEN_INTERVAL
#define DEFAULT_PS_MODE WIFI_PS_MIN_MODEM

//事件的位,連接成功和失敗
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1

//FreeRTOS事件組用於表示什么時候建立連接
static EventGroupHandle_t s_wifi_event_group;

static const char *TAG = "wifi station";

static int s_retry_num = 0;

//事件處理服務
static void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        if (s_retry_num < ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else {
            //事件組置位
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    } else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
        //事件組置位
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

//wifi初始化
void wifi_init_sta(void)
{
    //創建事件組
    s_wifi_event_group = xEventGroupCreate();

    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    //注冊事件處理服務
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler, NULL));

    wifi_config_t wifi_config = {
        .sta = {
            .ssid = ESP_WIFI_SSID,
            .password = ESP_WIFI_PASS,
            //設備從AP監聽信標的間隔
            .listen_interval = DEFAULT_LISTEN_INTERVAL, 
            //設置密碼意味着設備將會連接所有安全的模式,包括WEP、WPA。然而這些模式不建議使用,如果你的接入點不支持WPA2,注釋以下行來啟用其他模式
            .threshold.authmode = WIFI_AUTH_WPA2_PSK,

            .pmf_cfg = {
                .capable = true,
                .required = false
            },
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
    ESP_ERROR_CHECK(esp_wifi_start() );
    ESP_LOGI(TAG, "esp_wifi_set_ps().");
    esp_wifi_set_ps(DEFAULT_PS_MODE);
    ESP_LOGI(TAG, "wifi_init_sta finished.");

    //事件組等待位,等到連接建立或者超過最大重連數后連接仍然失敗。位的設置是通過事件處理服務
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            portMAX_DELAY);

    //通過事件組等待位返回位的值,判斷事件做了什么
    if (bits & WIFI_CONNECTED_BIT) {
        ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                 ESP_WIFI_SSID, ESP_WIFI_PASS);
    } else if (bits & WIFI_FAIL_BIT) {
        ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
                 ESP_WIFI_SSID, ESP_WIFI_PASS);
    } else {
        ESP_LOGE(TAG, "UNEXPECTED EVENT");
    }

    //注銷事件處理服務,注銷后,即便此前已注冊的事件再次被發送時,也不會再執行了。
    ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler));
    ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler));
    vEventGroupDelete(s_wifi_event_group);
}

//啟動
void app_main(void)
{
    //初始化非易失性存儲
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
      ESP_ERROR_CHECK(nvs_flash_erase());
      ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    //配置動態頻率縮放:最高頻率和最低頻率在sdkconfig中配置
    esp_pm_config_esp32_t pm_config = {
            .max_freq_mhz = CONFIG_MAX_CPU_FREQ_MHZ,
            .min_freq_mhz = CONFIG_MIN_CPU_FREQ_MHZ,
            .light_sleep_enable = true
    };

    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
    wifi_init_sta();
}

 

 

Kconfig.projbuild文件如下:

menu "Example Configuration"

    config ESP_WIFI_SSID
        string "WiFi SSID"
        default "wifissid"
        help
            SSID (network name) for the example to connect to.

    config ESP_WIFI_PASSWORD
        string "WiFi Password"
        default "wifipassword"
        help
            WiFi password (WPA or WPA2) for the example to use.

    config ESP_MAXIMUM_RETRY
        int "Maximum retry"
        default 5
        help
            Set the Maximum retry to avoid station reconnecting to the AP unlimited when the AP is really inexistent.

    config WIFI_LISTEN_INTERVAL
        int "WiFi listen interval"
        default 3
        help
            Interval for station to listen to beacon from AP. The unit of listen interval is one beacon interval.
            For example, if beacon interval is 100 ms and listen interval is 3, the interval for station to listen
            to beacon is 300 ms.

    choice POWER_SAVE_MODE
        prompt "power save mode"
        default POWER_SAVE_MIN_MODEM
        help
            Power save mode for the esp32 to use. Modem sleep mode includes minimum and maximum power save modes.
            In minimum power save mode, station wakes up every DTIM to receive beacon. Broadcast data will not be
            lost because it is transmitted after DTIM. However, it can not save much more power if DTIM is short
            for DTIM is determined by AP.
            In maximum power save mode, station wakes up every listen interval to receive beacon. Broadcast data
            may be lost because station may be in sleep state at DTIM time. If listen interval is longer, more power
            is saved but broadcast data is more easy to lose.

        config POWER_SAVE_NONE
            bool "none"
        config POWER_SAVE_MIN_MODEM
            bool "minimum modem"
        config POWER_SAVE_MAX_MODEM
            bool "maximum modem"
    endchoice

    choice MAX_CPU_FREQ
        prompt "Maximum CPU frequency"
        default MAX_CPU_FREQ_80
        help
            Maximum CPU frequency to use for dynamic frequency scaling.

        config MAX_CPU_FREQ_80
            bool "80 MHz"
        config MAX_CPU_FREQ_160
            bool "160 MHz"
        config MAX_CPU_FREQ_240
            bool "240 MHz"
    endchoice

    config MAX_CPU_FREQ_MHZ
        int
        default 80 if MAX_CPU_FREQ_80
        default 160 if MAX_CPU_FREQ_160
        default 240 if MAX_CPU_FREQ_240

    choice MIN_CPU_FREQ
        prompt "Minimum CPU frequency"
        default MIN_CPU_FREQ_10M
        help
            Minimum CPU frequency to use for dynamic frequency scaling.
            Should be set to XTAL frequency or XTAL frequency divided by integer.

        config MIN_CPU_FREQ_40M
            bool "40 MHz (use with 40MHz XTAL)"
            depends on ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO
        config MIN_CPU_FREQ_20M
            bool "20 MHz (use with 40MHz XTAL)"
            depends on ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO
        config MIN_CPU_FREQ_10M
            bool "10 MHz (use with 40MHz XTAL)"
            depends on ESP32_XTAL_FREQ_40 || ESP32_XTAL_FREQ_AUTO
        config MIN_CPU_FREQ_26M
            bool "26 MHz (use with 26MHz XTAL)"
            depends on ESP32_XTAL_FREQ_26 || ESP32_XTAL_FREQ_AUTO
        config MIN_CPU_FREQ_13M
            bool "13 MHz (use with 26MHz XTAL)"
            depends on ESP32_XTAL_FREQ_26 || ESP32_XTAL_FREQ_AUTO
    endchoice

    config MIN_CPU_FREQ_MHZ
        int
        default 40 if MIN_CPU_FREQ_40M
        default 20 if MIN_CPU_FREQ_20M
        default 10 if MIN_CPU_FREQ_10M
        default 26 if MIN_CPU_FREQ_26M
        default 13 if MIN_CPU_FREQ_13M

endmenu

 

原文:https://gitee.com/EspressifSystems/esp-idf


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM