ESP32S3基于espidf手动接入网络配置介绍
- 📍相关参考《【快速上手ESP32(基于ESP-IDF&VSCode)】10-事件循环&&WiFi》
- 🎈官方相关wifi驱动文档说明:
https://docs.espressif.com/projects/esp-idf/zh_CN/stable/esp32/api-guides/wifi.html#wifi-programming-model
- Smartconfig配网可以参考官方demo例程:
\v5.4\esp-idf\examples\wifi\smart_config
- 🧨Smartconfig其他参考《文手把手教程–ESP32 一键配网(Smartconfig、Airkiss)》
- ✨本文不包含环境搭建等相关介绍内容,仅介绍ESP32配置Wi-Fi连接,接入网络相关的代码实现。
📗手动入网配置流程
- 包含必要的头文件
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
- 定义Wi-Fi配置
定义Wi-Fi的SSID和密码:
#define WIFI_SSID "your_SSID"//替换为自己的wifi信息
#define WIFI_PASS "your_PASSWORD"
- 初始化NVS(非易失性存储)
NVS用于存储Wi-Fi配置和其他系统参数:
void 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);
}
- 初始化Wi-Fi
初始化Wi-Fi并配置为Station模式:
#define WIFI_SSID "#######"
#define WIFI_PASS "*******"
void initialize_wifi() {
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
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, &wifi_event_handler, NULL));
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
},
};
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());
}
- 处理Wi-Fi事件
处理Wi-Fi连接事件,例如连接成功或断开连接:
void wifi_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) {
esp_wifi_connect();
} 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("WIFI", "Got IP: " IPSTR, IP2STR(&event->ip_info.ip));
}
}
📘完整入网代码实现
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"
#define WIFI_SSID "########" //注意替换wifi信息
#define WIFI_PASS "********"
void initialize_nvs() {
esp_err_t ret = nvs_flash_init();// 初始化NVS, 并检查是否需要擦除NVS
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);
}
void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) {//响应WiFi事件回调
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();
} 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("WIFI", "Got IP: " IPSTR, IP2STR(&event->ip_info.ip));
}
}
void initialize_wifi() {
esp_netif_init();
esp_event_loop_create_default();
esp_netif_create_default_wifi_sta();
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, &wifi_event_handler, NULL));// 注册WiFi事件处理程序
ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL));// 注册IP事件处理程序
wifi_config_t wifi_config = {
.sta = {
.ssid = WIFI_SSID,
.password = WIFI_PASS,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));// 设置为STA模式
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config));// 设置WiFi配置
ESP_ERROR_CHECK(esp_wifi_start());// 启动WiFi
}
// 打印 Wi-Fi 信息
void print_wifi_info() {
wifi_config_t wifi_config;
esp_wifi_get_config(ESP_IF_WIFI_STA, &wifi_config);
esp_netif_ip_info_t ip_info;
esp_netif_t* netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK) {
ESP_LOGI(TAG, "Wi-Fi SSID: %s", (char*)wifi_config.sta.ssid);
ESP_LOGI(TAG, "Wi-Fi Password: %s", (char*)wifi_config.sta.password);
ESP_LOGI(TAG, "IP Address: " IPSTR, IP2STR(&ip_info.ip));
} else {
ESP_LOGE(TAG, "Failed to get IP information");
}
}
void app_main(void)
{
initialize_nvs(); // 初始化NVS
initialize_wifi(); // 初始化Wi-Fi
while (1)
{
vTaskDelay(CONFIG_BLINK_PERIOD / portTICK_PERIOD_MS);
print_wifi_info() ;//打印wifi信息
}
}
- 调试输出信息:
📘smartconfig配网代码
- 🔧配网工具:可以直接关注
乐鑫信息科技
微信公众号,找到Airkiss设备
,手机需要提前开启定位功能才行。输入对应所连接的wifi密码,即可以向周围的设备发送wifi信息广播。esp32接收到广播发出的wifi信息,即可完成wifi连接。 - 🧬乐鑫官方下载配网专用APP链接:
https://www.espressif.com.cn/zh-hans/support/download/apps
/* Esptouch example
This example code is in the Public Domain (or CC0 licensed, at your option.)
Unless required by applicable law or agreed to in writing, this
software is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
CONDITIONS OF ANY KIND, either express or implied.
上传代码前,先对目标芯片进行全擦除操作。
python D:\ESP32\ESPidf\v5.4\esp-idf\components\esptool_py\esptool\esptool.py erase_flash
*/
#include <string.h>
#include <stdlib.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_eap_client.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_system.h"
#include "nvs_flash.h"
#include "esp_netif.h"
#include "esp_smartconfig.h"
#include "esp_mac.h"
#include "esp_sntp.h"
/* FreeRTOS event group to signal when we are connected & ready to make a request */
static EventGroupHandle_t s_wifi_event_group;
/* The event group allows multiple bits for each event,
but we only care about one event - are we connected
to the AP with an IP? */
static const int CONNECTED_BIT = BIT0;
static const int ESPTOUCH_DONE_BIT = BIT1;
static const char *TAG = "smartconfig_example";
static void smartconfig_example_task(void *parm);
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data);
static void initialize_sntp(void);
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)
{
xTaskCreate(smartconfig_example_task, "smartconfig_example_task", 4096, NULL, 3, NULL);
}
else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED)
{
ESP_LOGI(TAG, "Wi-Fi disconnected, trying to reconnect...");
esp_wifi_connect();//断网重连
if (CONNECTED_BIT & xEventGroupGetBits(s_wifi_event_group))
{
xEventGroupClearBits(s_wifi_event_group, CONNECTED_BIT);
}else{
// 如果重连失败,启动 SmartConfig
vTaskDelay(pdMS_TO_TICKS(5000)); // 等待 5 秒
if (esp_wifi_sta_get_ap_info(NULL) != ESP_OK) {
ESP_LOGI(TAG, "Reconnect failed, starting SmartConfig...");
xTaskCreate(smartconfig_example_task, "smartconfig_task", 4096, NULL, 3, NULL);
}
}
}
else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP)
{
initialize_sntp(); // 初始化 SNTP
xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
}
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;
wifi_config_t wifi_config;
uint8_t ssid[33] = {0};
uint8_t password[65] = {0};
uint8_t rvd_data[33] = {0};
bzero(&wifi_config, sizeof(wifi_config_t));
memcpy(wifi_config.sta.ssid, evt->ssid, sizeof(wifi_config.sta.ssid));
memcpy(wifi_config.sta.password, evt->password, sizeof(wifi_config.sta.password));
#ifdef CONFIG_SET_MAC_ADDRESS_OF_TARGET_AP
wifi_config.sta.bssid_set = evt->bssid_set;
if (wifi_config.sta.bssid_set == true)
{
ESP_LOGI(TAG, "Set MAC address of target AP: " MACSTR " ", MAC2STR(evt->bssid));
memcpy(wifi_config.sta.bssid, evt->bssid, sizeof(wifi_config.sta.bssid));
}
#endif
memcpy(ssid, evt->ssid, sizeof(evt->ssid));
memcpy(password, evt->password, sizeof(evt->password));
ESP_LOGI(TAG, "SSID:%s", ssid);
ESP_LOGI(TAG, "PASSWORD:%s", password);
if (evt->type == SC_TYPE_ESPTOUCH_V2)
{
ESP_ERROR_CHECK(esp_smartconfig_get_rvd_data(rvd_data, sizeof(rvd_data)));
ESP_LOGI(TAG, "RVD_DATA:");
for (int i = 0; i < 33; i++)
{
printf("%02x ", rvd_data[i]);
}
printf("\n");
}
ESP_ERROR_CHECK(esp_wifi_disconnect());
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
esp_wifi_connect();
}
else if (event_base == SC_EVENT && event_id == SC_EVENT_SEND_ACK_DONE)
{
xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT);
}
}
static void initialise_wifi(void)
{
ESP_ERROR_CHECK(esp_netif_init());
s_wifi_event_group = xEventGroupCreate();
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));
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());
}
static void smartconfig_example_task(void *parm)
{
EventBits_t uxBits;
wifi_config_t myconfig = {0};
ESP_LOGI(TAG, "creat smartconfig_example_task"); // 获取wifi配置信息,如果配置过,就直接连接wifi
esp_wifi_get_config(ESP_IF_WIFI_STA, &myconfig);
if (strlen((char *)myconfig.sta.ssid) > 0)
{
ESP_LOGI(TAG, "alrealy set, SSID is :%s,start connect", myconfig.sta.ssid);
esp_wifi_connect();
} // 如果没有配置过,就进行配网操作
else
{
ESP_LOGI(TAG, "have no set, start to config");
ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_ESPTOUCH_AIRKISS)); // 支持APP ESPTOUCH和微信AIRKISS
smartconfig_start_config_t cfg = SMARTCONFIG_START_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_smartconfig_start(&cfg));
}
while (1)
{
uxBits = xEventGroupWaitBits(s_wifi_event_group, CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY);
if (uxBits & CONNECTED_BIT)
{
ESP_LOGI(TAG, "WiFi Connected to ap");// 成功连接路由器
}
if (uxBits & ESPTOUCH_DONE_BIT)
{
ESP_LOGI(TAG, "smartconfig over");// 配网结束
esp_smartconfig_stop();
vTaskDelete(NULL);
}
}
}
// SNTP 初始化
static void initialize_sntp(void)
{
ESP_LOGI(TAG, "Initializing SNTP");
esp_netif_init(); // 初始化网络接口
#if ESP_IDF_VERSION >= ESP_IDF_VERSION_VAL(5, 0, 0)
// 设置时间服务器(默认使用 pool.ntp.org)
esp_sntp_setoperatingmode(SNTP_OPMODE_POLL);
// 添加 NTP 服务器
esp_sntp_setservername(0, "pool.ntp.org"); // 默认服务器
esp_sntp_setservername(1, "cn.pool.ntp.org"); // 中国 NTP 服务器
esp_sntp_setservername(2, "ntp1.aliyun.com"); // 阿里云 NTP 服务器
// 初始化 SNTP
esp_sntp_init();
#else
sntp_setoperatingmode(SNTP_OPMODE_POLL);
sntp_setservername(0, "pool.ntp.org");
sntp_setservername(1, "cn.pool.ntp.org");
sntp_setservername(2, "ntp1.aliyun.com");
sntp_init(); // 初始化 SNTP
#endif
// 设置时区(例如:北京时间 UTC+8)
setenv("TZ", "CST-8", 1);
tzset();
}
// 打印当前时间
void print_current_time()
{
time_t now;
struct tm timeinfo;
// char buffer[64];
// 获取当前时间戳
time(&now);
// 将时间戳转换为本地时间
localtime_r(&now, &timeinfo);
char *time_str = asctime(&timeinfo);
if (time_str != NULL)
{
// 去掉 asctime 输出的换行符
time_str[strlen(time_str) - 1] = '\0';
ESP_LOGI(TAG, "Current time: %s", time_str);
}
else
{
ESP_LOGE(TAG, "Failed to convert time to string");
}
}
// 打印 Wi-Fi 信息
void print_wifi_info()
{
wifi_config_t wifi_config;
esp_wifi_get_config(ESP_IF_WIFI_STA, &wifi_config);
esp_netif_ip_info_t ip_info;
esp_netif_t *netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
if (netif && esp_netif_get_ip_info(netif, &ip_info) == ESP_OK)
{
ESP_LOGI(TAG, "Wi-Fi SSID: %s", (char *)wifi_config.sta.ssid);
ESP_LOGI(TAG, "Wi-Fi Password: %s", (char *)wifi_config.sta.password);
ESP_LOGI(TAG, "IP Address: " IPSTR, IP2STR(&ip_info.ip));
}
else
{
ESP_LOGE(TAG, "Failed to get IP information");
}
}
void app_main(void)
{
ESP_ERROR_CHECK(nvs_flash_init());
initialise_wifi();
while (1)
{
// 检查时间是否已同步
time_t now;
struct tm timeinfo;
time(&now);
localtime_r(&now, &timeinfo);
if (timeinfo.tm_year > (2020 - 1900))
{
print_current_time();
}
else
{
ESP_LOGI(TAG, "Waiting for time synchronization...");
}
vTaskDelay(pdMS_TO_TICKS(1000));
print_wifi_info();
}
}
- 连接过程中,串口打印信息