ESP32的WiFi有三种模式,AP模式、STA模式与smart_config。为了方便管理,我把这三种模式的初始化集成到了一个文件中,方便后面使用。
工程目录
moqi@5d30a855738f:~/project/esp32-demo/project$ tree
├── CMakeLists.txt
├── components
│ └── hardware
│ ├── CMakeLists.txt
│ ├── component.mk
│ ├── inc
│ │ └── Wifi_Hardware.h
│ └── src
│ └── Wifi_Hardware.c
├── main
│ ├── CMakeLists.txt
│ ├── inc
│ │ └── main.h
│ └── src
│ └── main.c
└── readme.md
工程文件内容
components/hardware/inc/Wifi_Hardware.h
#ifndef __WIFI_HARDWARE_H__
#define __WIFI_HARDWARE_H__
#include <esp_mac.h>
#include <esp_wifi.h>
#include <esp_smartconfig.h>
typedef enum {
Wifi_ConfigAirkissMode,
Wifi_ConfigApMode,
Wifi_ConfigStaMode,
}Wifi_ConfigMode;
void Wifi_Init(int Wifimode, esp_event_handler_t event_handler);
void Wifi_ConfigSoftap(char *SSID, char *PASS);
void Wifi_ConfigSta(char *SSID, char *PASS);
void Wifi_ConfigAirkiss(void);
#endif
/* __WIFI_HARDWARE_H__ */
components/hardware/src/Wifi_Hardware.c
#include <string.h>
#include "Wifi_Hardware.h"
static void Dev_GetMac(uint8_t *base_mac_addr)
{
esp_err_t ret = ESP_OK;
if ( base_mac_addr == NULL ) {
return;
}
#ifdef CONFIG_BASE_MAC_STORED_EFUSE_BLK3
//Get base MAC address from EFUSE BLK3
ret = esp_read_mac(base_mac_addr, ESP_MAC_EFUSE_CUSTOM);
if (ret != ESP_OK) {
#ifdef CONFIG_BASE_MAC_STORED_EFUSE_BLK3_ERROR_ABORT
abort();
#else
ESP_ERROR_CHECK(esp_read_mac(base_mac_addr, ESP_MAC_EFUSE_FACTORY));
#endif//CONFIG_BASE_MAC_STORED_EFUSE_BLK3_ERROR_ABORT
}
#elif defined(CONFIG_BASE_MAC_STORED_OTHER_EXTERNAL_STORAGE)
//Get base MAC address from other external storage, or set by software
ret = external_storage_mac_get(base_mac_addr);
if (ret != ESP_OK) {
abort();
}
#else
//Get base MAC address from EFUSE BLK0(default option)
ret = esp_read_mac(base_mac_addr, ESP_MAC_EFUSE_FACTORY);
if (ret != ESP_OK) {
abort();
}
#endif
}
void Wifi_Init(int Wifimode, esp_event_handler_t event_handler)
{
char hostname[16];
uint8_t mac_addr[6] = {0};
esp_netif_t *netif;
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
memset (hostname, 0, 16);
Dev_GetMac(mac_addr);
sprintf (hostname, "Moqi_%.2X%.2X%.2X",
mac_addr[3], mac_addr[4], mac_addr[5]);
switch (Wifimode)
{
case Wifi_ConfigApMode:
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_ap();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
event_handler,
NULL,
NULL));
break;
case Wifi_ConfigStaMode:
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
netif = esp_netif_create_default_wifi_sta();
esp_netif_set_hostname(netif, hostname);
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
event_handler,
NULL,
NULL));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
event_handler,
NULL,
NULL));
ESP_ERROR_CHECK(esp_wifi_start());
break;
case Wifi_ConfigAirkissMode:
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
netif = esp_netif_create_default_wifi_sta();
esp_netif_set_hostname(netif, hostname);
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));
ESP_ERROR_CHECK(esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, event_handler, NULL));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());
break;
default:
break;
}
}
void Wifi_ConfigSoftap(char *SSID, char *PASS)
{
wifi_config_t wifi_config = {
.ap = {
.channel = 1,
.max_connection = 3,
.authmode = WIFI_AUTH_WPA_WPA2_PSK},
};
uint8_t mac_addr[6] = {0};
Dev_GetMac(mac_addr);
if (strlen(SSID)==0)
{
sprintf (SSID, "ESP32_%.2X%.2X%.2X",
mac_addr[3], mac_addr[4], mac_addr[5]);
}
memset(wifi_config.ap.ssid, 0, 32);
memcpy(wifi_config.ap.ssid, SSID, strlen(SSID));
if (strlen(PASS) == 0)
{
wifi_config.ap.authmode = WIFI_AUTH_OPEN;
}
memset(wifi_config.ap.password, 0, 32);
memcpy(wifi_config.ap.password, PASS, strlen(PASS));
wifi_config.ap.ssid_len = strlen(SSID);
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
void Wifi_ConfigSta(char *SSID, char *PASS)
{
wifi_config_t wifi_config = {
.sta = {
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.capable = true,
.required = false},
},
};
memset(wifi_config.sta.ssid, 0, 32);
memcpy(wifi_config.sta.ssid, SSID, strlen(SSID));
memset(wifi_config.sta.password, 0, 32);
memcpy(wifi_config.sta.password, PASS, strlen(PASS));
ESP_ERROR_CHECK(esp_wifi_disconnect());
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
esp_wifi_connect();
}
void Wifi_ConfigAirkiss(void)
{
ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_AIRKISS));
smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_smartconfig_start(&cfg));
}
components/hardware/CMakeLists.txt
idf_build_get_property(idf_target IDF_TARGET)
set(board_srcs "src/Wifi_Hardware.c")
idf_component_register(SRCS "${board_srcs}"
PRIV_REQUIRES esp_wifi
INCLUDE_DIRS "./inc")
components/hardware/component.mk
#
# Component Makefile
#
COMPONENT_ADD_INCLUDEDIRS += inc
COMPONENT_SRCDIRS += src
main/CMakeLists.txt
set(board_srcs "src/main.c")
idf_component_register(SRCS "${board_srcs}"
INCLUDE_DIRS "./inc")
main文件代码内容
不同的模式下的main.c内容不同,需要分别来设置。
AP模式
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <esp_log.h>
#include <esp_event.h>
#include <nvs_flash.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include "Wifi_Hardware.h"
#include "main.h"
#define TAG "main"
#define WIFI_IP_LENGTH 16
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data);
char StaIP[WIFI_IP_LENGTH];
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);
memset (StaIP, 0, WIFI_IP_LENGTH);
Wifi_Init(Wifi_ConfigApMode, &wifi_event_handler);
Wifi_ConfigSoftap("ap123", "12345678");
}
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (event_id == WIFI_EVENT_AP_STACONNECTED) {
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) {
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);
} else 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) {
esp_wifi_connect();
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;
memset(StaIP, 0, WIFI_IP_LENGTH);
sprintf(StaIP, IPSTR, IP2STR(&event->ip_info.ip));
ESP_LOGI(TAG, "got StaIP: %s", StaIP);
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
ESP_LOGI(TAG, "Scan done");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
ESP_LOGI(TAG, "Found channel");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
ESP_LOGI(TAG, "Got SSID and password");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
ESP_LOGI(TAG, "esptouch done");
}
}
STA模式
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <esp_log.h>
#include <esp_event.h>
#include <nvs_flash.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include "Wifi_Hardware.h"
#include "main.h"
#define TAG "main"
#define WIFI_IP_LENGTH 16
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data);
char StaIP[WIFI_IP_LENGTH];
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);
memset (StaIP, 0, WIFI_IP_LENGTH);
Wifi_Init(Wifi_ConfigApMode, &wifi_event_handler);
Wifi_ConfigSoftap("ap123", "12345678");
}
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (event_id == WIFI_EVENT_AP_STACONNECTED) {
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) {
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);
} else 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) {
esp_wifi_connect();
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;
memset(StaIP, 0, WIFI_IP_LENGTH);
sprintf(StaIP, IPSTR, IP2STR(&event->ip_info.ip));
ESP_LOGI(TAG, "got StaIP: %s", StaIP);
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
ESP_LOGI(TAG, "Scan done");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
ESP_LOGI(TAG, "Found channel");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
ESP_LOGI(TAG, "Got SSID and password");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
ESP_LOGI(TAG, "esptouch done");
}
}
smart_config
#include <stdio.h>
#include <stdio.h>
#include <string.h>
#include <esp_log.h>
#include <esp_event.h>
#include <nvs_flash.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <freertos/event_groups.h>
#include "Wifi_Hardware.h"
#include "main.h"
#define TAG "main"
#define WIFI_IP_LENGTH 16
#define WIFI_SSID_LENGTH 64
#define WIFI_PASS_LENGTH 128
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data);
char StaIP[WIFI_PASS_LENGTH];
char StaSSID[WIFI_SSID_LENGTH];
char StaPASS[WIFI_PASS_LENGTH];
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);
memset (StaIP, 0, WIFI_IP_LENGTH);
memset (StaSSID, 0, WIFI_SSID_LENGTH);
memset (StaPASS, 0, WIFI_PASS_LENGTH);
Wifi_Init(Wifi_ConfigAirkissMode, &wifi_event_handler);
}
static void wifi_event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
{
if (event_id == WIFI_EVENT_AP_STACONNECTED) {
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) {
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);
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
if (strlen (StaSSID) == 0 ) {
Wifi_ConfigAirkiss();
ESP_LOGI(TAG, "config Airkiss");
} else {
esp_wifi_connect();
ESP_LOGI(TAG, "connect WiFi");
}
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
esp_wifi_connect();
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;
memset(StaIP, 0, WIFI_IP_LENGTH);
sprintf(StaIP, IPSTR, IP2STR(&event->ip_info.ip));
ESP_LOGI(TAG, "got StaIP: %s", StaIP);
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SCAN_DONE) {
ESP_LOGI(TAG, "Scan done");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_FOUND_CHANNEL) {
ESP_LOGI(TAG, "Found channel");
} else if (event_base == SC_EVENT && event_id == SC_EVENT_GOT_SSID_PSWD) {
ESP_LOGI(TAG, "Got SSID and password");
smartconfig_event_got_ssid_pswd_t *evt = (smartconfig_event_got_ssid_pswd_t *)event_data;
memset(StaSSID, 0, WIFI_SSID_LENGTH);
memset(StaPASS, 0, WIFI_PASS_LENGTH);
memcpy(StaSSID, evt->ssid, sizeof(evt->ssid));
memcpy(StaPASS, evt->password, sizeof(evt->password));
Wifi_ConfigSta(StaSSID, StaPASS);
} else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE) {
ESP_LOGI(TAG, "esptouch done");
esp_smartconfig_stop();
}
}