ESP32 IDF development application article? Use of Wifi STA mode and AP mode

ESP32 IDF Development Application Chapter? The use of Wifi STA mode and AP mode

  • 1. The blogger’s purpose for writing this technical article:
    • 2. Overview
    • 3. Introduction to Wifi library
    • 4. Software design of Wifi sta mode and ap mode
    • 5. Wifi st mode example
    • 6. Wifi ap mode example


Don’t get lost-Navigation bar
Quickly navigate to find what you want (article directory)


If this article is useful to you, please like and save it. Your support is the motivation for the blogger to persist.

1. The blogger’s purpose of writing this technical article:

(1) Understand the 3 working modes of WIFI;
(2) Master the basic use of esp32wifi;

2. Overview

In the previous chapter, we have introduced the basic applications of ESP32 to you, and you already have a basic understanding of the idf framework. Starting from this chapter, we will lead you to explore the core function of esp32, wifi.
(1) Wifi’s 3 working modes
?Station mode, also called site mode;
?AP mode, also called Soft-AP mode, can be understood as WiFi hotspot mode;
?The above two aggregation modes, Station and Soft-AP, are also the basis for the implementation of Mesh NetWork;
Any WiFi function development based on ESP32 is developed based on one of the above working modes. Therefore, they are the focus of our basic WiFi learning.
(2) What is STA mode
Station is similar to a wireless terminal. Station itself does not accept wireless access. It can be connected to an AP. Generally, wireless network cards work in this mode.
(3) What is AP mode
Access Point provides wireless access services, allows other wireless devices to access, and provides data access. General wireless routers/bridges work in this mode. APs are allowed to connect to each other.
Simply understand that AP is a router, STA is a mobile phone, and STA is connected to AP.

3. Introduction to Wifi library

For detailed wifi functions, please refer to esp-idf\components\esp_wifi\include\esp_wifi.h
Here I will only explain a few important and frequently used API functions.
(1) wifi initialization, mainly initializing the wifi_init_config_t structure

/**
  * @brief Initialize WiFi
  *Allocated memory for WiFi driver, such as WiFi control structures, RX/TX buffers, WiFi NVS structures, etc. This WiFi will also start WiFi tasks
  * @Note 1. This API must be called before all other WiFi APIs can be called
  * @Note 2. Always use the WIFI_INIT_CONFIG_DEFAULT macro to initialize the configuration to default values
  * When adding more fields to wifi_init_config_t, ensure that all fields have correct values
  * In a future release. If you want to set the initial value of the owner, override the default value
  * Set by WIFI_INIT_CONFIG_DEFAULT, please note
  * wifi_init_config_t should always be WIFI_INIT_CONFIG_MAGIC!
  * @param configures a pointer to the WiFi initialization configuration structure
  * @return
  * - ESP_OK: succeed
  * - ESP_ERR_NO_MEM: Out of memory
  */
esp_err_t esp_wifi_init(const wifi_init_config_t *config);

(2) Set wifi mode

/**
   * @brief Set WiFi operating mode
   * Set WiFi operating mode to station, soft-AP or station + soft-AP,
   *Default mode is soft AP mode.
   * @param mode WiFi operation mode
   * @return
   *-ESP_OK: Success
   *-ESP_ERR_WIFI_NOT_INIT: WiFi not initialized by esp_wifi_init
   *-ESP_ERR_INVALID_ARG: invalid argument
   * - Others: see error codes in esp_err.h
   */
esp_err_t esp_wifi_set_mode(wifi_mode_t mode);

(3) Set the wifi wifi_config_t structure

/**
  * @brief Set the configuration of ESP32 STA or AP
  * @Note 1. This API can only be called when the specified interface is enabled, otherwise, the API will fail
  * @Note 2. For workstation configurations, bssid_set needs to be 0; otherwise it is 0. It only needs to be set to 1 if the user needs to check the MAC address of the AP.
  * @Note 3. ESP32 is limited to one channel, so in soft-AP + station mode, soft-AP will automatically adjust its channel to the channel with the ESP32 station.
  * @param interface
  * @param conf workstation or soft-AP configuration
  *
  * @return
  *-ESP_OK: Success
  *-ESP_ERR_WIFI_NOT_INIT: WiFi not initialized by esp_wifi_init
  *-ESP_ERR_INVALID_ARG: invalid argument
  *-ESP_ERR_WIFI_IF: Invalid interface
  *-ESP_ERR_WIFI_MODE: invalid mode
  *-ESP_ERR_WIFI_PASSWORD: Invalid password
  *-ESP_ERR_WIFI_NVS: WiFi internal NVS error
  * - Others: see error codes in esp_err.h
  */
esp_err_t esp_wifi_set_config(wifi_interface_t interface, wifi_config_t *conf);

(4) Start wifi

/**
   * @brief Start WiFi based on current configuration
   *If the mode is WIFI_MODE_STA, create the site control block and start the site
   *If the mode is WIFI_MODE_AP, the soft-AP control block will be created and soft-AP will be started
   *If the mode is WIFI_MODE_APSTA, create soft-AP and site control blocks and start soft-AP and site
   *
   * @return
   *-ESP_OK: Success
   *-ESP_ERR_WIFI_NOT_INIT: WiFi not initialized by esp_wifi_init
   *-ESP_ERR_INVALID_ARG: Invalid argument
   *-ESP_ERR_NO_MEM: Out of memory
   *-ESP_ERR_WIFI_CONN: WiFi internal error, station or soft-AP control block error
   *-ESP_FAIL: Other WiFi internal error
   */
esp_err_t esp_wifi_start(void);

(4) wifi callback function, please refer to for specific analysis:
[ESP32 IDF development application? Special topic on connecting Wifi callback function esp_event_handler_register]

/**
 * @brief Register event handler to the system event loop.
 *
 *This function can be used to register any of the following handlers: (1) specific events,
 *(2) All events based on an event, or (3) All events known to the system event loop.
 *
 *-Specific event: specify the exact event_base and event_id
 * - All events with a specific base: specify the exact event_base and use ESP_EVENT_ANY_ID as event_id
 * - Loop through all known events: use ESP_EVENT_ANY_BASE as event_base and ESP_EVENT_ANY_ID as event_id
 *
 *Multiple handlers can be registered to an event. Registering a single handler to multiple events is
 *Also available. However, registering the same handler multiple times to the same event will result in
 *Previous registrations will be overwritten.
 *
 * @param [in] The base ID of the event_base event, used to register handlers for it
 * @param [in] event_id The ID of the event for which a handler is to be registered
 * @param [in] event_handler handler function, which will be called when an event is dispatched
 * @param [in] event_handler_arg data, in addition to event data, is passed to the handler when calling
 *
 * @note The event loop library does not maintain a copy of event_handler_arg, so users should
 * Make sure event_handler_arg still points to a valid location when the handler is called
 *
 * @return
 *-ESP_OK: Success
 *-ESP_ERR_NO_MEM: Unable to allocate memory for handler
 *-ESP_ERR_INVALID_ARG: Invalid combination of event library and event ID
 *-Other: failed
 */
esp_err_t esp_event_handler_register(esp_event_base_t event_base,
                                        int32_t event_id,
                                        esp_event_handler_t event_handler,
                                        void* event_handler_arg);

4. Software design of Wifi sta mode and ap mode

?sta mode
(1) Create a wifi connection event group;
(2) Initialize wifi and register callback function
Mainly initializes 2 structures
The wifi_init_config_t structure generally uses the system’s default parameters, and uses the function WIFI_INIT_CONFIG_DEFAULT() to assign values.

wifi_init_config_t cfg =WIFI_INIT_CONFIG_DEFAULT();//Initialize the system default data for the wifi_init_config_t structure

Structure content:

/**
 * @brief WiFi stack configuration parameters passed to esp_wifi_init call.
 */
typedef struct {<!-- -->
    system_event_handler_t event_handler; /**< WiFi event handler */
    wifi_osi_funcs_t* osi_funcs; /**< WiFi OS functions */
    wpa_crypto_funcs_t wpa_crypto_funcs; /**< WiFi station crypto functions when connect */
    int static_rx_buf_num; /**< WiFi static RX buffer number */
    int dynamic_rx_buf_num; /**< WiFi dynamic RX buffer number */
    int tx_buf_type; /**< WiFi TX buffer type */
    int static_tx_buf_num; /**< WiFi static TX buffer number */
    int dynamic_tx_buf_num; /**< WiFi dynamic TX buffer number */
    int csi_enable; /**< WiFi channel state information enable flag */
    int ampdu_rx_enable; /**< WiFi AMPDU RX feature enable flag */
    int ampdu_tx_enable; /**< WiFi AMPDU TX feature enable flag */
    int nvs_enable; /**< WiFi NVS flash enable flag */
    int nano_enable; /**< Nano option for printf/scan family enable flag */
    int tx_ba_win; /**< WiFi Block Ack TX window size */
    int rx_ba_win; /**< WiFi Block Ack RX window size */
    int wifi_task_core_id; /**< WiFi Task Core ID */
    int beacon_max_len; /**< WiFi softAP maximum length of the beacon */
    int mgmt_sbuf_num; /**< WiFi management short buffer number, the minimum value is 6, the maximum value is 32 */
    uint64_t feature_caps; /**< Enables additional WiFi features and capabilities */
    int magic; /**< WiFi init magic number, it should be the last field */
} wifi_init_config_t;

The wifi_config_t structure only needs to set the SSID and PASSWORD of sta and ap modes.

typedef union {<!-- -->
    wifi_ap_config_t ap; /**< configuration of AP */
    wifi_sta_config_t sta; /**< configuration of STA */
} wifi_config_t;

wifi_ap_config_t

/** @brief ESP32 Soft-AP configuration settings */
typedef struct {<!-- -->
    uint8_t ssid[32]; /**< SSID If the ssid_len field is 0, the string must be a Null-terminated string. Otherwise, set the length according to ssid_len. */
    uint8_t password[64]; /**< password.*/
    uint8_t ssid_len; /**< Optional length of SSID field. */
    uint8_t channel; /**< ESP32 soft-AP channel */
    wifi_auth_mode_t authmode; /**< ESP32 soft-AP authentication method. AUTH_WEP is not supported in soft AP mode */
    uint8_t ssid_hidden; /**< Whether to broadcast SSID, the default is 0, broadcast SSID */
    uint8_t max_connection; /**<the maximum number of stations allowed to connect, the default is 4, the maximum is 4 */
    uint16_t beacon_interval; /**< Beacon interval 100?60000 ms, default 100 ms */
} wifi_ap_config_t;

wifi_sta_config_t

/** @brief ESP32 STA configuration settings */
typedef struct {<!-- -->
    uint8_t ssid[32]; /**< SSID of the target AP. Null terminated string. */
    uint8_t password[64]; /**< Password of the target AP. Null terminated string. */
    wifi_scan_method_t scan_method; /**< Perform all channel scan or quick scan */
    bool bssid_set; /**< Whether to set the MAC address of the target AP. Normally, station_config.bssid_set needs to be 0; otherwise it is 0. It only needs to be set to 1 if the user needs to check the MAC address of the AP. */
    uint8_t bssid[6]; /**< MAC address of target AP*/
    uint8_t channel; /**< Channel of the target AP. Set to 1~13 to start scanning from the specified channel before connecting to the AP. If the AP's channel is unknown, set it to 0. */
    uint16_t listen_interval; /**<the listening interval for the ESP32 station to receive beacons when setting WIFI_PS_MAX_MODEM. Unit: AP beacon interval. If set to 0, the default is 3. */
    wifi_sort_method_t sort_method; /**< Sort connected APs in the list by rssi or security mode */
    wifi_scan_threshold_t threshold; /**< When sort_method is set, only APs with an authentication mode more secure than the selected authentication mode and a signal stronger than the minimum RSSI will be used. */
    wifi_pmf_config_t pmf_cfg; /**< Configuration for Protected Management Frame. Will be advertized in RSN Capabilities in RSN IE. */
} wifi_sta_config_t;

(3) Wait for the wifi connection to print the connection message

5. Wifi sta mode example

Method 1
Copy the project in the esp-idf\examples\wifi\getting_started\station directory to your own directory and change the name to idf_wifi_sta. The file name is changed to i idf_wifi_sta.C. The makefile file is also changed to PROJECT_NAME:= idf_wifi_sta. Yes, then copy the code to test.

In make menuconfig
Example Configuration ->
WiFi SSID: Set up account
WiFi Password: Set password
Maximum retry: number of repeated connections
Then save and exit

Method 2: How to add compilation menu in menuconfig
Copy the original project and change the name
Add Kconfig.projbuild
in the main directory of the project

Then add in Kconfig.projbuild
menu “Example Configuration”

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

configESP_WIFI_PASSWORD
    string "WiFi Password"
    default "mypassword"
    help
        WiFi password (WPA or WPA2) for the example to use.

configESP_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.

endmenu
In this way, there will be an Example Configuration option when making menuconfig
config ESP_WIFI_PASSWORD, config ESP_WIFI_PASSWORD, config ESP_MAXIMUM_RETRY are the macros used in the program

/********************************************** ************************
* File name: idf_wifi_sta.c
*               founder:            
* Creation date:
* Modified by:
* Modification date:
* Version number: V1.1
*               Remark:
*               company:
*************************************************** ******************/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "nvs.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "lwip/err.h"
#include "lwip/sys.h"
static const char *TAG = "WIFI_STA";

//event flag group
static EventGroupHandle_t xCreatedEventGroup_WifiConnect = NULL;
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static int retry_num = 0;
/****************************************************** **********************
* Function:
* Description: wifi callback function
* Parameters:
* Return: None
* Remark:
*************************************************** ************************/
static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{<!-- -->
    ESP_LOGI(TAG, "event_base: %s ; event_id : %d",event_base,event_id);
    if (event_base == WIFI_EVENT & amp; & amp; event_id == WIFI_EVENT_STA_START)
    {<!-- -->
        esp_wifi_connect();//Start connecting
    }
    else if (event_base == WIFI_EVENT & amp; & amp; event_id == WIFI_EVENT_STA_DISCONNECTED) //When wifi is disconnected
    {<!-- -->
        if (retry_num < CONFIG_ESP_MAXIMUM_RETRY) //Number of reconnections
        {<!-- -->
            esp_wifi_connect();
            retry_num + + ;
            ESP_LOGI(TAG, "retry to connect to the AP");
        }
        else
        {<!-- -->
            xEventGroupSetBits(xCreatedEventGroup_WifiConnect, WIFI_FAIL_BIT);
            xEventGroupClearBits(xCreatedEventGroup_WifiConnect, WIFI_CONNECTED_BIT);
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    }
    else if (event_base == IP_EVENT & amp; & amp; event_id == IP_EVENT_STA_GOT_IP)//Get IP
    {<!-- -->
        ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
        ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR( & amp;event->ip_info.ip));
        retry_num = 0;
        xEventGroupSetBits(xCreatedEventGroup_WifiConnect, WIFI_CONNECTED_BIT);
        xEventGroupClearBits(xCreatedEventGroup_WifiConnect, WIFI_FAIL_BIT);
    }
}
/****************************************************** **********************
* Function:
* Description: The wifi st initialization code is relatively fixed and generally does not need to be modified.
* Parameters:
* Return: None
* Remark:
*************************************************** ************************/
void wifi_init_sta(void)
{<!-- -->
    ESP_ERROR_CHECK(esp_netif_init()); //Initialize TCP/IP stack and esp-netif
    ESP_ERROR_CHECK(esp_event_loop_create_default()); //Create the default event loop
    esp_netif_create_default_wifi_sta();//Create the default WIFI STA.

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();//Initialize the system default data for the wifi_init_config_t structure
    ESP_ERROR_CHECK(esp_wifi_init( & amp;cfg));//Initialize wifi using default parameters

    //Register callback function during wifi connection process
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, & amp;event_handler, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, & amp;event_handler, NULL));
    //Set the account and password in menuconfig
    wifi_config_t wifi_config = {<!-- -->
        .sta = {<!-- -->
            .ssid = CONFIG_ESP_WIFI_SSID,
            .password = CONFIG_ESP_WIFI_PASSWORD
            //.ssid = "ssid",
            //.password = "password"
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );//Set to sta mode
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, & amp;wifi_config) );
    ESP_ERROR_CHECK(esp_wifi_start() );//Start

    ESP_LOGI(TAG, "wifi_init_sta finished.");
}
/****************************************************** **********************
* Function:
* Description: Main function
* Parameters:
* Return: None
* Remark:
*************************************************** ************************/
void app_main()
{<!-- -->
    //Initialize NVS
   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);

    ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
    //Create an event flag group to wait for wifi connection
    xCreatedEventGroup_WifiConnect = xEventGroupCreate();
    //WIFI st initialization
    wifi_init_sta();
    //Waiting for a successful connection, or if the connection is already disconnected, this function will always block until there is a connection.
   EventBits_t bits = xEventGroupWaitBits(xCreatedEventGroup_WifiConnect,//Event flag group handle
    WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, // Wait for bit0 and bit1 to be set
    pdFALSE, //bit0 and bit1 are cleared when TRUE exits, bit0 and bit1 are not cleared when pdFALSE exits
    pdFALSE, //Set to pdTRUE to wait for both bit1 and bit0 to be set, pdFALSE to wait for either bit1 or bit0 to be set
    portMAX_DELAY); //Wait for the delay time and keep waiting

    if (bits & WIFI_CONNECTED_BIT)
    {<!-- -->
        ESP_LOGI(TAG, "connected to ap" );
    }
    else if (bits & WIFI_FAIL_BIT)
    {<!-- -->
        ESP_LOGI(TAG, "Failed to connect");
    }
    //Logout delete event
    ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, & amp;event_handler));
    ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, & amp;event_handler));
    vEventGroupDelete(xCreatedEventGroup_WifiConnect);
}

6. Wifi ap mode example

/********************************************** ************************
* File name: idf_wifi_sta.c
*               founder:            
* Creation date:
* Modified by:
* Modification date:
* Version number: V1.1
*               Remark:
*               company:
*************************************************** ******************/
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "nvs.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "lwip/err.h"
#include "lwip/sys.h"
static const char *TAG = "WIFI_AP";

/****************************************************** **********************
* Function:
* Description: wifi callback function
* Parameters:
* Return: None
* Remark:
*************************************************** ************************/
static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)
{<!-- -->
    ESP_LOGI(TAG, "event_base: %s ; event_id : %d",event_base,event_id);
    if (event_id == WIFI_EVENT_AP_STACONNECTED) //There is STA connection
    {<!-- -->
        wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data;
        ESP_LOGI(TAG, "station "MACSTR" join, AID=%d",
                 MAC2STR(event->mac), event->aid);
    }
    else if (event_id == WIFI_EVENT_AP_STADISCONNECTED) //STA disconnects
    {<!-- -->
        wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data;
        ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",
                 MAC2STR(event->mac), event->aid);
    }
}
/****************************************************** **********************
* Function:
* Description: The wifi st initialization code is relatively fixed and generally does not need to be modified.
* Parameters:
* Return: None
* Remark:
*************************************************** ************************/
void wifi_init_ap(void)
{<!-- -->
    ESP_ERROR_CHECK(esp_netif_init()); //Initialize TCP/IP stack and esp-netif
    ESP_ERROR_CHECK(esp_event_loop_create_default()); //Create the default event loop
    esp_netif_create_default_wifi_ap();//Create the default WIFI ap.

    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();//Initialize the system default data for the wifi_init_config_t structure
    ESP_ERROR_CHECK(esp_wifi_init( & amp;cfg));//Initialize wifi using default parameters

    //Register callback function during wifi connection process
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, ESP_EVENT_ANY_ID, & amp;event_handler, NULL));
    //Set the account and password in menuconfig
    wifi_config_t wifi_config = {<!-- -->
        .ap = {<!-- -->
            .ssid = "idf_wifi_ap",
            .password = "123456789",//The password length here cannot be less than 8 characters
            .max_connection = 1,
            .authmode = WIFI_AUTH_WPA_WPA2_PSK
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP) );//Set to sta mode
    ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, & amp;wifi_config) );
    ESP_ERROR_CHECK(esp_wifi_start() );//Start

    ESP_LOGI(TAG, "wifi_init_AP finished.");
}
/****************************************************** **********************
* Function:
* Description: Main function
* Parameters:
* Return: None
* Remark:
*************************************************** ************************/
void app_main()
{<!-- -->
    //Initialize NVS
   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);

    ESP_LOGI(TAG, "ESP_WIFI_MODE_AP");

    //WIFI st initialization
    wifi_init_ap();
}

During the startup process, you need to pay attention to the fact that the password cannot be less than 8 characters. If it is less than 8 characters, the system will always restart.



Source code of all articles: https://download.csdn.net/download/lu330274924/88518092