ESP32 WIFI 概述

  • WIFI 库支持配置及监控 ESP32 WIFI 连网功能。
  • 支持配置
  • station 模式(即 STA 模式或 WIFI 客户端模式),此时 ESP32 连接到接入点(AP)。
  • AP 模式(即 soft-AP 模式或接入点模式),此时 station 接入点 ESP32。
  • AP-STA 共存模式(ESP32 既是接入点,同时又作为 station 连接到另一个接入点)。
  • 上述模式的各种安全模式(WPA、WPA2 及 WEP 等)。
  • 扫描接入点(包括主动扫描和被动扫描)。
  • 使用混杂模式监控 IEEE802.11 WIFI 数据包。

宏定义 WIFI_INIT_CONFIG_DEFAULT

  • 配置

 wifi_init_config_t 结构体的默认值。

#define WIFI_INIT_CONFIG_DEFAULT() { \
        .event_handler = &esp_event_send_internal, \
        .osi_funcs = &g_wifi_osi_funcs, \
        .wpa_crypto_funcs = g_wifi_default_wpa_crypto_funcs, \
        .static_rx_buf_num = CONFIG_ESP32_WIFI_STATIC_RX_BUFFER_NUM,\
        .dynamic_rx_buf_num = CONFIG_ESP32_WIFI_DYNAMIC_RX_BUFFER_NUM,\
        .tx_buf_type = CONFIG_ESP32_WIFI_TX_BUFFER_TYPE,\
        .static_tx_buf_num = WIFI_STATIC_TX_BUFFER_NUM,\
        .dynamic_tx_buf_num = WIFI_DYNAMIC_TX_BUFFER_NUM,\
        .cache_tx_buf_num = WIFI_CACHE_TX_BUFFER_NUM,\
        .csi_enable = WIFI_CSI_ENABLED,\
        .ampdu_rx_enable = WIFI_AMPDU_RX_ENABLED,\
        .ampdu_tx_enable = WIFI_AMPDU_TX_ENABLED,\
        .amsdu_tx_enable = WIFI_AMSDU_TX_ENABLED,\
        .nvs_enable = WIFI_NVS_ENABLED,\
        .nano_enable = WIFI_NANO_FORMAT_ENABLED,\
        .rx_ba_win = WIFI_DEFAULT_RX_BA_WIN,\
        .wifi_task_core_id = WIFI_TASK_CORE_ID,\
        .beacon_max_len = WIFI_SOFTAP_BEACON_MAX_LEN, \
        .mgmt_sbuf_num = WIFI_MGMT_SBUF_NUM, \
        .feature_caps = g_wifi_feature_caps, \
        .sta_disconnected_pm = WIFI_STA_DISCONNECTED_PM_ENABLED,  \
        .magic = WIFI_INIT_CONFIG_MAGIC\
};

函数 esp_wifi_init

  • esp_err_t esp_wifi_init(wifi_init_config_t *config)
  • 为 WiFi 驱动初始化 WiFi 分配资源,如 WiFi 控制结构、RX/TX 缓冲区、WiFi NVS 结构等,这个 WiFi 也启动 WiFi 任务。
  • 必须先调用此 API,然后才能调用所有其他 WiFi API。
  • 推荐使用 WIFI_INIT_CONFIG_DEFAULT 宏将配置初始化为默认值。
  • wifi_init_config_t
  • WIFI 初始化结构体。传递给

 esp_wifi_init 调用的 WiFi 堆栈配置参数。

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                    cache_tx_buf_num;       /**< WiFi TX cache 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                    amsdu_tx_enable;        /**< WiFi AMSDU TX feature enable flag */
        int                    nvs_enable;             /**< WiFi NVS flash enable flag */
        int                    nano_enable;            /**< Nano option for printf/scan family enable flag */
        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 */
        bool                   sta_disconnected_pm;    /**< WiFi Power Management for station at disconnected status */
        int                    magic;                  /**< WiFi init magic number, it should be the last field */
} wifi_init_config_t;
  • config
  • 结构体指针。指向 WIFI 初始化配置结构体。
  • return
  • ESP_OK: 成功
  • ESP_ERR_WIFI_NO_MEM: 内存不足
  • others: esp_err.h

函数esp_wifi_set_mode

  • esp_err_t esp_wifi_set_mode(wifi_mode_t mode)
  • 设置 WIFI 操作模式。
  • 可以设置为 station、soft-AP 或 station + soft-AP 模式,默认为 soft-AP 模式。
  • wifi_mode_t
  • WIFI 配置模式枚举。

ty

typedef enum {
    WIFI_MODE_NULL = 0,  /**< null mode */
    WIFI_MODE_STA,       /**< WiFi station mode */
    WIFI_MODE_AP,        /**< WiFi soft-AP mode */
    WIFI_MODE_APSTA,     /**< WiFi station + soft-AP mode */
    WIFI_MODE_MAX
} wifi_mode_t;
  • mode
  • WIFI 操作模式。
  • return
  • ESP_OK: 成功
  • ESP_ERR_WIFI_NOT_INT: WIFI 未由 

esp_wifi_init 初始化

  • ESP_ERR_WIFI_ARG: 无效的参数
  • other: esp_err.h

函数esp_wifi_set_config

  • esp_err_t esp_wifi_set_config(wifi_interface_t interface, wifi_config_t *conf)
  • 设置 ESP32 STA 或 AP 的配置。
  • 该 API 只有在指定接口开启时才能调用,否则 API 失败。
  • ESP32 仅限于一个通道,因此在 soft-AP + station 模式下,soft-AP 会自动调整其通道与 station 的通道相同。
  • wifi_interface_t
  • 指定接口枚举。
  • 该 API 只有在指定接口开启时才能调用,否则 API 失败
typedef enum {
    WIFI_IF_STA = ESP_IF_WIFI_STA,
    WIFI_IF_AP  = ESP_IF_WIFI_AP,
} wifi_interface_t;
  • interface
  • 接口
  • wifi_config_t
  • WIFI 配置。
  • 账号、密码等。
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
  • soft-AP 模式配置结构体。
typedef struct {
      uint8_t ssid[32];           /**< SSID of ESP32 soft-AP. If ssid_len field is 0, this must be a Null terminated string. Otherwise, length is set according to ssid_len. */
      uint8_t password[64];       /**< Password of ESP32 soft-AP. */
      uint8_t ssid_len;           /**< Optional length of SSID field. */
      uint8_t channel;            /**< Channel of ESP32 soft-AP */
      wifi_auth_mode_t authmode;  /**< Auth mode of ESP32 soft-AP. Do not support AUTH_WEP in soft-AP mode */
      uint8_t ssid_hidden;        /**< Broadcast SSID or not, default 0, broadcast the SSID */
      uint8_t max_connection;     /**< Max number of stations allowed to connect in, default 4, max 10 */
      uint16_t beacon_interval;   /**< Beacon interval which should be multiples of 100. Unit: TU(time unit, 1 TU = 1024 us). Range: 100 ~ 60000. Default value: 100 */
      wifi_cipher_type_t pairwise_cipher;   /**< pairwise cipher of SoftAP, group cipher will be derived using this. cipher values are valid starting from WIFI_CIPHER_TYPE_TKIP, enum values before that will be considered as invalid and default cipher suites(TKIP+CCMP) will be used. Valid cipher suites in softAP mode are WIFI_CIPHER_TYPE_TKIP, WIFI_CIPHER_TYPE_CCMP and WIFI_CIPHER_TYPE_TKIP_CCMP. */
      bool ftm_responder;         /**< Enable FTM Responder mode */
} wifi_ap_config_t;
  • wifi_sta_config_t
  • station 模式配置结构体。
typedef struct {
      uint8_t ssid[32];      /**< SSID of target AP. */
      uint8_t password[64];  /**< Password of target AP. */
      wifi_scan_method_t scan_method;    /**< do all channel scan or fast scan */
      bool bssid_set;        /**< whether set MAC address of target AP or not. Generally, station_config.bssid_set needs to be 0; and it needs to be 1 only when users need to check the MAC address of the AP.*/
      uint8_t bssid[6];     /**< MAC address of target AP*/
      uint8_t channel;       /**< channel of target AP. Set to 1~13 to scan starting from the specified channel before connecting to AP. If the channel of AP is unknown, set it to 0.*/
      uint16_t listen_interval;   /**< Listen interval for ESP32 station to receive beacon when WIFI_PS_MAX_MODEM is set. Units: AP beacon intervals. Defaults to 3 if set to 0. */
      wifi_sort_method_t sort_method;    /**< sort the connect AP in the list by rssi or security mode */
      wifi_scan_threshold_t  threshold;     /**< When sort_method is set, only APs which have an auth mode that is more secure than the selected auth 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. */
      uint32_t rm_enabled:1;        /**< Whether Radio Measurements are enabled for the connection */
      uint32_t btm_enabled:1;       /**< Whether BSS Transition Management is enabled for the connection */
      uint32_t reserved:30;         /**< Reserved for future feature set */
} wifi_sta_config_t;
  • conf
  • 结构体指针。指向 wifi_config_t WIFI 配置结构体。
  • return
  • ESP_OK: 成功
  • ESP_ERR_WIFI_NOT_INIT: WIFI 没有被 esp_wifi_init 初始化
  • ESP_ERR_INVALID_ARG: 无效的参数
  • ESP_ERR_WIFI_IF: 无效的接口
  • ESP_ERR_WIFI_MODE: 无效的模式
  • ESP_ERR_WIFI_PASSWORD: 无效的密码
  • ESP_ERR_WIFI_NVS: WIFI 内部 NVS 错误
  • other: esp_err.h

函数esp_wifi_start

  • esp_err_t esp_wifi_start(void)
  • 根据当前配置启动 WIFI。
  • 如果为 WIFI_MODE_STA 模式,则创建 station 控制块并启动 station。
  • 如果为 WIFI_MODE_AP 模式,则创建 soft-AP 控制块并启动 soft-AP。
  • 如果为 WIFI_MODE_APSTA 模式,则创建 soft-AP 和 station 控制块并启动 soft-AP 和 station。
  • return
  • ESP_OK: 成功
  • ESP_ERR_WIFI_NOT_INIT: WIFI 没有被 esp_wifi_init 初始化
  • ESP_ERR_INVALID_ARG: 无效的参数
  • ESP_ERR_NO_MEM: 内存不足
  • ESP_ERR_WIFI_CONN: WIFI 内部错误、station 或 soft-AP控制块错误
  • other: esp_err.h

配网存储并清除配网信息接口

如果使用 esp_wifi_set_config 在恢复出厂设置时不知如何擦除flash 因为flash中保存有SN。

t

typedef enum {
    wifi_unconfiged = 0,
    wifi_configed   = 0xAA,
}wifi_info_storage_t;
#define     ID_AND_PWD_LEN      (32+64)
/**********************************************
 * *函数名:clearWifiConfigFlag
 * *功能描述:清除配网标记,如果运行这个函数,可以配合esp_restart(),复位系统。重新配网
 * *   --  主要是取代nvs_flash_erase()函数,这个函数把所有的数据都擦除,是不对的。
 * *******************************************/
void clearWifiConfigFlag(void)
{
    nvs_handle my_handle;
    //  0.打开
    nvs_open("WIFI_CONFIG", NVS_READWRITE, &my_handle); 
    //  1.写入标记 0x00,清除配网标记
    nvs_set_u8(my_handle, "WifiConfigFlag", wifi_unconfiged);
    //  2.提交 并保存表的内容
    ESP_ERROR_CHECK(nvs_commit(my_handle)); 
    //  3.关闭nvs退出
    nvs_close(my_handle);  
}
//保存wifi配置参数结构体变量wifi_config到nvs
static void saveWifiConfig(wifi_config_t *wifi_config)
{
    nvs_handle my_handle;
    //  0.打开
    nvs_open("WIFI_CONFIG", NVS_READWRITE, &my_handle); 
    //  1.写入标记 0xaa,表示已经配过网
    nvs_set_u8(my_handle, "WifiConfigFlag", wifi_configed);
    //  2.写入AP ID和AP password
    ESP_ERROR_CHECK(nvs_set_blob(my_handle, "wifi_config", wifi_config, ID_AND_PWD_LEN));
    //  3.提交 并保存表的内容
    ESP_ERROR_CHECK(nvs_commit(my_handle)); 
    //  4.关闭nvs退出
    nvs_close(my_handle);                   
}

//从nvs中读取wifi配置到给定的sta_config结构体变量
static esp_err_t readWifiConfig(wifi_config_t *sta_config)
{
    nvs_handle my_handle;
    unsigned char u8WifiConfigVal;
    //  0.打开
    nvs_open("WIFI_CONFIG", NVS_READWRITE, &my_handle); 
    //  1.读取标志位,并判断
    nvs_get_u8(my_handle, "WifiConfigFlag", &u8WifiConfigVal);
    if(u8WifiConfigVal != wifi_configed){
        // 1.1 没有配过网,关闭nvs,返回错误码
        ESP_LOGI(TAG, "no wifi config,read fail!");
        nvs_close(my_handle); 
        return ESP_FAIL;
    }else{      
        //  1.2 进入下个步骤
        ESP_LOGI(TAG, "wifi configed ,read ok!");    
    }
    //  2.读取上一次配网的ID,password
    uint32_t len = ID_AND_PWD_LEN;
    esp_err_t err = nvs_get_blob(my_handle, "wifi_config", sta_config, &len);

    ESP_LOGI(TAG, "readout  SSID:%s", sta_config->sta.ssid);
    ESP_LOGI(TAG, "readout  PASSWORD:%s", sta_config->sta.password);
     // 3.关闭nvs退出
    nvs_close(my_handle);
    return err;
}

ESP获取连接的WiFi信号强度

通过WiFi扫描接口过滤出连接的WiFi信息

wifi_sta_record* get_rssi(void)
{
    uint16_t number = 1;
    uint16_t ap_count = 0;
    wifi_sta_record* sta_record = (wifi_sta_record*) malloc (sizeof(wifi_sta_record));

    wifi_ap_record_t ap_info[1];
    wifi_config_t wifi_sta_cfg;

    BLUFI_INFO("start scan");
    memset(ap_info, 0, sizeof(ap_info));
    if (esp_wifi_get_config(WIFI_IF_STA, &wifi_sta_cfg) != ESP_OK)//获取已连接的ap参数
    {
        BLUFI_ERROR("esp_wifi_get_config err");  
        return NULL;
    }

    wifi_scan_config_t scan_config = { 0 };
    scan_config.ssid = wifi_sta_cfg.sta.ssid;//限制扫描的ap的ssid
    strcpy((char *)sta_record->ssid, (char*)wifi_sta_cfg.sta.ssid);
    scan_config.bssid = wifi_sta_cfg.sta.bssid;//限制扫描的ap的mac地址
    esp_wifi_scan_start(&scan_config, true);//阻塞扫描ap,scan_config为扫描的参数
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));//获取扫描到的ap信息
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));
    //获取扫描到的ap数量,因为限制了ssid和mac,因此最多只会扫描到1个
    for (int i = 0; (i < 1) && (i < ap_count); i++) {
        BLUFI_INFO("SSID \t\t%s", ap_info[i].ssid);
        BLUFI_INFO("RSSI \t\t%d", ap_info[i].rssi);
        ESP_LOGI(TAG, "Channel \t\t%d", ap_info[i].primary);
        ESP_LOGI(TAG, "BSSID: \t\t%02x:%02x:%02x:%02x:%02x:%02x", 
                                                        ap_info[i].bssid[0],
                                                        ap_info[i].bssid[1],
                                                        ap_info[i].bssid[2],
                                                        ap_info[i].bssid[3],
                                                        ap_info[i].bssid[4],
                                                        ap_info[i].bssid[5]);
    }
    esp_wifi_scan_stop(); 
    //from start to stop need 3210ms
    BLUFI_INFO("stop scan\r\n");

    sta_record->rssi = ap_info[0].rssi;

    return sta_record;
}

//测试使用 
wifi_sta_record* sta_info;
sta_info = get_rssi();
BLUFI_INFO("blufi sta signal strength ssid:%s, rssi:%d ",sta_info->ssid,sta_info->rssi );

方法二:直接使用乐鑫封好的API:esp_wifi_sta_get_ap_info 

wifi_sta_record* get_rssi(void)
{
    wifi_sta_record* sta_record = (wifi_sta_record*) malloc (sizeof(wifi_sta_record));

    wifi_ap_record_t ap_info[1];
    memset(ap_info, 0, sizeof(ap_info));
    //获取当前连接的WiFi信息
    if (esp_wifi_sta_get_ap_info(ap_info)!= ESP_OK)
    {
        BLUFI_ERROR("esp_wifi_sta_ap_info err");  
        return sta_record;
    }
    strcpy((char *)sta_record->ssid, (char*)ap_info[0].ssid);
    sta_record->rssi = ap_info[0].rssi;

    return sta_record;
}