单片机
返回首页

ESP32省电模式连接WIFI笔记

2025-09-10 来源:cnblogs

基于ESP-IDF4.1版本


main.c文件如下:


#include

#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


进入单片机查看更多内容>>
相关视频
  • 【TI MSPM0 应用实战】智能小车+工业角度编码器+血氧仪+烟雾探测器!硬核参考设计详解!

  • 2022 Digi-Key KOL 系列: 你见过1GHz主频的单片机吗?Teensy 4.1开发板介绍

  • TI 新一代 C2000™ 微控制器:全方位助力伺服及马达驱动应用

  • MSP430电容触摸技术 - 防水Demo演示

  • 直播回放: Microchip Timberwolf™ 音频处理器在线研讨会

  • 基于灵动MM32W0系列MCU的指夹血氧仪控制及OTA升级应用方案分享

精选电路图
  • 设计汽车集群电源

  • 6晶体管H桥

  • USB自供电声卡

  • AVR LCD温度计—LM35

  • AVR PC步进电机驱动器

  • AVR温度计TCN75

    相关电子头条文章