【ESP32-S3 从入门到精通-06】2026 最新 Wi-Fi 网络开发与配网技术全实战(Station/AP/TCP/UDP/SmartConfig)
写在前面大家好我是 EmbeddedCore。上一讲我们学习了 FreeRTOS 实时操作系统掌握了多任务编程、任务间通信与同步的核心技术。从这一讲开始我们将正式进入物联网的核心 ——网络开发。Wi-Fi 是 ESP32-S3 最具竞争力的功能之一也是物联网设备连接云端、实现智能化的基础。无论是远程控制设备、数据上传云端还是固件 OTA 升级都离不开 Wi-Fi 网络的支持。本讲将从最基础的 Wi-Fi 连接讲起一步步带你掌握 ESP32-S3 的所有 Wi-Fi 相关功能。我们不仅会学习如何连接路由器和创建热点还会深入学习 TCP/UDP 网络通信、HTTP 协议以及各种智能配网技术。学完本讲你将能够独立开发出能够连接互联网的物联网设备。一、Wi-Fi 基础与 ESP32-S3 Wi-Fi 架构1.1 Wi-Fi 基本概念Wi-Fi 是一种基于 IEEE 802.11 标准的无线局域网技术它使用 2.4GHz 和 5GHz 频段进行数据传输。ESP32-S3 支持 Wi-Fi 4802.11b/g/n标准最高传输速率可达 150Mbps。1.2 ESP32-S3 Wi-Fi 工作模式ESP32-S3 支持三种 Wi-Fi 工作模式表格工作模式描述适用场景Station 模式站点模式ESP32-S3 作为一个无线终端连接到路由器等 Wi-Fi 热点大多数物联网应用设备需要连接互联网AP 模式接入点模式ESP32-S3 自己创建一个 Wi-Fi 热点其他设备可以连接到它智能配网、设备直连、无路由器环境混合模式StationAPESP32-S3 同时作为站点和接入点设备在连接路由器的同时也允许其他设备连接自己1.3 ESP-IDF Wi-Fi 事件驱动架构ESP-IDF 的 Wi-Fi 子系统采用事件驱动架构这是 ESP-IDF v5.0 之后最重要的变化之一。当 Wi-Fi 状态发生变化时如连接成功、断开连接、获取 IP 地址等系统会发送相应的事件我们只需要注册事件处理函数来响应这些事件即可。这种架构的优点是代码结构清晰逻辑分明不需要在主循环中轮询 Wi-Fi 状态响应及时效率高ESP-IDF 中最重要的两个事件组是WIFI_EVENTWi-Fi 相关事件如WIFI_EVENT_STA_CONNECTED、WIFI_EVENT_STA_DISCONNECTED等IP_EVENTIP 相关事件如IP_EVENT_STA_GOT_IP、IP_EVENT_STA_LOST_IP等二、Wi-Fi Station 模式开发连接路由器Station 模式是最常用的 Wi-Fi 工作模式它允许 ESP32-S3 连接到现有的 Wi-Fi 路由器从而访问互联网。2.1 Wi-Fi Station 初始化流程ESP32-S3 Wi-Fi Station 模式的初始化流程如下初始化 NVS Flash用于存储 Wi-Fi 配置信息初始化网络接口创建默认事件循环创建默认 Wi-Fi Station 网络接口初始化 Wi-Fi 驱动注册 Wi-Fi 事件和 IP 事件处理函数配置 Wi-Fi 参数SSID 和密码设置 Wi-Fi 模式为 Station 模式启动 Wi-Fi 驱动2.2 实战项目 1Wi-Fi 自动连接与重连这是最基础的 Wi-Fi 实验我们将实现 ESP32-S3 自动连接到指定的 Wi-Fi 路由器并在断开连接时自动重连。完整代码c运行#include stdio.h #include freertos/FreeRTOS.h #include freertos/task.h #include esp_wifi.h #include esp_event.h #include nvs_flash.h #include esp_log.h static const char *TAG WIFI_STA; #define WIFI_SSID 你的Wi-Fi名称 #define WIFI_PASS 你的Wi-Fi密码 // Wi-Fi事件处理函数 static 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) { // Wi-Fi启动完成开始连接 ESP_LOGI(TAG, Wi-Fi started, connecting to %s..., WIFI_SSID); esp_wifi_connect(); } else if (event_base WIFI_EVENT event_id WIFI_EVENT_STA_CONNECTED) { // 连接成功 ESP_LOGI(TAG, Connected to %s successfully, WIFI_SSID); } else if (event_base WIFI_EVENT event_id WIFI_EVENT_STA_DISCONNECTED) { // 连接断开自动重连 ESP_LOGW(TAG, Wi-Fi disconnected, retrying...); esp_wifi_connect(); } else if (event_base IP_EVENT event_id IP_EVENT_STA_GOT_IP) { // 获取到IP地址 ip_event_got_ip_t* event (ip_event_got_ip_t*) event_data; ESP_LOGI(TAG, Got IP address: IPSTR, IP2STR(event-ip_info.ip)); ESP_LOGI(TAG, Gateway: IPSTR, IP2STR(event-ip_info.gw)); ESP_LOGI(TAG, Netmask: IPSTR, IP2STR(event-ip_info.netmask)); } } void wifi_init_sta(void) { // 1. 初始化NVS Flash 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); // 2. 初始化网络接口 ESP_ERROR_CHECK(esp_netif_init()); // 3. 创建默认事件循环 ESP_ERROR_CHECK(esp_event_loop_create_default()); // 4. 创建默认Wi-Fi Station网络接口 esp_netif_create_default_wifi_sta(); // 5. 初始化Wi-Fi驱动 wifi_init_config_t cfg WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(cfg)); // 6. 注册事件处理函数 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)); // 7. 配置Wi-Fi参数 wifi_config_t wifi_config { .sta { .ssid WIFI_SSID, .password WIFI_PASS, .threshold.authmode WIFI_AUTH_WPA2_PSK, // 只连接WPA2加密的热点 }, }; // 8. 设置Wi-Fi模式为Station模式 ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); // 9. 配置Wi-Fi参数 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, wifi_config)); // 10. 启动Wi-Fi ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, Wi-Fi Station initialization completed); } void app_main(void) { wifi_init_sta(); }代码说明我们使用了 ESP-IDF 的日志系统ESP_LOGI、ESP_LOGW来输出调试信息比printf更专业添加了自动重连功能当 Wi-Fi 断开连接时会自动尝试重新连接设置了认证模式为WIFI_AUTH_WPA2_PSK只连接安全的 WPA2 加密热点打印了详细的网络信息包括 IP 地址、网关和子网掩码实验步骤将代码中的WIFI_SSID和WIFI_PASS修改为你自己的 Wi-Fi 名称和密码编译烧录代码到 ESP32-S3 开发板打开串口监控你将看到类似以下的输出plaintextI (27) wifi:wifi driver task: 3ffc1d88, prio:23, stack:3584, core0 I (31) system_api: Base MAC address is not set, read default base MAC address from BLK0 of EFUSE I (41) wifi:wifi firmware version: 7d240d5 I (45) wifi:wifi certification version: v7.0 I (49) wifi:config NVS flash: enabled I (53) wifi:config nano formating: disabled I (57) wifi:Init data frame dynamic rx buffer num: 32 I (62) wifi:Init management frame dynamic rx buffer num: 32 I (67) wifi:Init management frame dynamic tx buffer num: 32 I (72) wifi:Init static rx buffer size: 1600 I (76) wifi:Init static rx buffer num: 10 I (80) wifi:Init dynamic rx buffer num: 32 I (84) wifi_init: rx ba win: 6 I (88) wifi_init: tcpip mbox: 32 I (92) wifi_init: udp mbox: 6 I (96) wifi_init: tcp mbox: 6 I (100) wifi_init: tcp tx win: 5744 I (104) wifi_init: tcp rx win: 5744 I (108) wifi_init: tcp mss: 1440 I (112) wifi_init: WiFi IRAM OP enabled I (116) wifi_init: WiFi RX IRAM OP enabled I (121) phy_init: phy_version 4670,phy0 Jun 21 2025,13:29:07 I (130) wifi:set rx active PTI: 0, rx ack PTI: 0, and default PTI: 0 I (136) wifi:mode : sta (7c:df:a1:xx:xx:xx) I (140) wifi:enable tsf I (143) WIFI_STA: Wi-Fi started, connecting to your_ssid... I (148) wifi:new:1,0, old:1,0, ap:255,255, sta:1,0, prof:1 I (856) wifi:state: init - auth (b0) I (860) wifi:state: auth - assoc (0) I (864) wifi:state: assoc - run (10) I (872) wifi:connected with your_ssid, aid 1, channel 1, BW20, bssid xx:xx:xx:xx:xx:xx I (881) wifi:security: WPA2-PSK, phy: bgn, rssi: -58 I (886) WIFI_STA: Connected to your_ssid successfully I (891) wifi:pm start, type: 1 I (957) wifi:APs beacon interval 102400 us, DTIM period 1 I (1456) esp_netif_handlers: sta ip: 192.168.1.100, mask: 255.255.255.0, gw: 192.168.1.1 I (1465) WIFI_STA: Got IP address: 192.168.1.100 I (1471) WIFI_STA: Gateway: 192.168.1.1 I (1476) WIFI_STA: Netmask: 255.255.255.0恭喜你你的 ESP32-S3 已经成功连接到 Wi-Fi 网络了2.3 Wi-Fi 扫描功能ESP32-S3 还支持 Wi-Fi 扫描功能可以扫描周围所有可用的 Wi-Fi 热点。Wi-Fi 扫描代码c运行void wifi_scan(void) { ESP_LOGI(TAG, Scanning Wi-Fi networks...); wifi_scan_config_t scan_config { .ssid NULL, .bssid NULL, .channel 0, .show_hidden true }; ESP_ERROR_CHECK(esp_wifi_scan_start(scan_config, true)); uint16_t ap_count 0; ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(ap_count)); wifi_ap_record_t *ap_records (wifi_ap_record_t *)malloc(sizeof(wifi_ap_record_t) * ap_count); ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(ap_count, ap_records)); ESP_LOGI(TAG, Found %d Wi-Fi networks:, ap_count); for(int i 0; i ap_count; i) { ESP_LOGI(TAG, %d. SSID: %s, Channel: %d, RSSI: %d dBm, i1, ap_records[i].ssid, ap_records[i].primary, ap_records[i].rssi); } free(ap_records); }三、Wi-Fi AP 模式开发创建热点AP 模式允许 ESP32-S3 自己创建一个 Wi-Fi 热点其他设备如手机、电脑可以连接到这个热点实现设备之间的直接通信。3.1 实战项目 2创建 Wi-Fi 热点完整代码c运行#include stdio.h #include freertos/FreeRTOS.h #include freertos/task.h #include esp_wifi.h #include esp_event.h #include nvs_flash.h #include esp_log.h #include esp_netif.h static const char *TAG WIFI_AP; #define AP_SSID ESP32-S3-AP #define AP_PASS 12345678 #define AP_CHANNEL 1 #define AP_MAX_CONN 4 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 connected, 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 disconnected, AID: %d, MAC2STR(event-mac), event-aid); } } void wifi_init_ap(void) { ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_ap(); 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_config_t wifi_config { .ap { .ssid AP_SSID, .ssid_len strlen(AP_SSID), .password AP_PASS, .channel AP_CHANNEL, .authmode WIFI_AUTH_WPA2_PSK, .max_connection AP_MAX_CONN, }, }; ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, wifi_config)); ESP_ERROR_CHECK(esp_wifi_start()); ESP_LOGI(TAG, Wi-Fi AP started); ESP_LOGI(TAG, SSID: %s, AP_SSID); ESP_LOGI(TAG, Password: %s, AP_PASS); ESP_LOGI(TAG, Channel: %d, AP_CHANNEL); ESP_LOGI(TAG, Max connections: %d, AP_MAX_CONN); } void app_main(void) { wifi_init_ap(); }实验现象编译烧录代码后ESP32-S3 会创建一个名为 ESP32-S3-AP 的 Wi-Fi 热点你可以用手机或电脑搜索并连接这个热点密码是 12345678当有设备连接或断开时串口会打印相应的信息四、TCP/UDP 网络通信Wi-Fi 连接成功后我们就可以进行网络通信了。TCP 和 UDP 是互联网中最常用的两种传输层协议。4.1 TCP vs UDP表格特性TCPUDP连接方式面向连接无连接可靠性可靠保证数据按序到达不可靠不保证数据到达和顺序速度较慢较快适用场景文件传输、网页浏览、邮件视频通话、语音通话、实时数据传输4.2 实战项目 3TCP 服务器我们将创建一个 TCP 服务器监听端口 8080接收客户端发送的数据并原样返回回显服务器。完整代码c运行#include stdio.h #include string.h #include freertos/FreeRTOS.h #include freertos/task.h #include esp_wifi.h #include esp_event.h #include nvs_flash.h #include esp_log.h #include lwip/sockets.h #include lwip/netdb.h static const char *TAG TCP_SERVER; #define WIFI_SSID 你的Wi-Fi名称 #define WIFI_PASS 你的Wi-Fi密码 #define TCP_PORT 8080 #define BUF_SIZE 1024 // Wi-Fi初始化代码同上此处省略 void wifi_init_sta(void) { ... } void tcp_server_task(void *pvParameters) { char rx_buffer[BUF_SIZE]; char addr_str[128]; int addr_family AF_INET; int ip_protocol IPPROTO_IP; struct sockaddr_in dest_addr; dest_addr.sin_addr.s_addr htonl(INADDR_ANY); dest_addr.sin_family AF_INET; dest_addr.sin_port htons(TCP_PORT); // 创建socket int listen_sock socket(addr_family, SOCK_STREAM, ip_protocol); if(listen_sock 0) { ESP_LOGE(TAG, Unable to create socket: errno %d, errno); vTaskDelete(NULL); return; } // 绑定socket int err bind(listen_sock, (struct sockaddr *)dest_addr, sizeof(dest_addr)); if(err ! 0) { ESP_LOGE(TAG, Socket unable to bind: errno %d, errno); close(listen_sock); vTaskDelete(NULL); return; } // 开始监听 err listen(listen_sock, 1); if(err ! 0) { ESP_LOGE(TAG, Error occurred during listen: errno %d, errno); close(listen_sock); vTaskDelete(NULL); return; } ESP_LOGI(TAG, TCP server listening on port %d, TCP_PORT); while(1) { struct sockaddr_in source_addr; socklen_t addr_len sizeof(source_addr); // 等待客户端连接 int sock accept(listen_sock, (struct sockaddr *)source_addr, addr_len); if(sock 0) { ESP_LOGE(TAG, Unable to accept connection: errno %d, errno); break; } // 转换客户端IP地址为字符串 inet_ntoa_r(source_addr.sin_addr, addr_str, sizeof(addr_str) - 1); ESP_LOGI(TAG, Client connected: %s, addr_str); // 处理客户端数据 while(1) { // 接收数据 int len recv(sock, rx_buffer, sizeof(rx_buffer) - 1, 0); if(len 0) { ESP_LOGE(TAG, Error occurred during recv: errno %d, errno); break; } else if(len 0) { ESP_LOGI(TAG, Client disconnected); break; } // 处理数据 rx_buffer[len] \0; ESP_LOGI(TAG, Received %d bytes from %s: %s, len, addr_str, rx_buffer); // 回显数据 send(sock, rx_buffer, len, 0); } // 关闭连接 close(sock); } close(listen_sock); vTaskDelete(NULL); } void app_main(void) { wifi_init_sta(); // 创建TCP服务器任务 xTaskCreate(tcp_server_task, tcp_server, 4096, NULL, 5, NULL); }实验步骤修改代码中的 Wi-Fi 名称和密码编译烧录代码打开串口监控记录 ESP32-S3 的 IP 地址打开电脑上的网络调试助手如 NetAssist选择 TCP 客户端模式输入 ESP32-S3 的 IP 地址和端口 8080点击连接发送任意数据你将收到 ESP32-S3 原样返回的数据4.3 实战项目 4UDP 客户端我们将创建一个 UDP 客户端向指定的服务器发送数据。完整代码c运行#include stdio.h #include string.h #include freertos/FreeRTOS.h #include freertos/task.h #include esp_wifi.h #include esp_event.h #include nvs_flash.h #include esp_log.h #include lwip/sockets.h #include lwip/netdb.h static const char *TAG UDP_CLIENT; #define WIFI_SSID 你的Wi-Fi名称 #define WIFI_PASS 你的Wi-Fi密码 #define UDP_SERVER_IP 192.168.1.100 // 你的电脑IP地址 #define UDP_SERVER_PORT 8080 #define BUF_SIZE 1024 // Wi-Fi初始化代码同上此处省略 void wifi_init_sta(void) { ... } void udp_client_task(void *pvParameters) { char tx_buffer[BUF_SIZE]; int count 0; struct sockaddr_in dest_addr; dest_addr.sin_family AF_INET; dest_addr.sin_port htons(UDP_SERVER_PORT); inet_pton(AF_INET, UDP_SERVER_IP, dest_addr.sin_addr); // 创建socket int sock socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); if(sock 0) { ESP_LOGE(TAG, Unable to create socket: errno %d, errno); vTaskDelete(NULL); return; } ESP_LOGI(TAG, UDP client started, sending to %s:%d, UDP_SERVER_IP, UDP_SERVER_PORT); while(1) { // 构造数据 sprintf(tx_buffer, Hello from ESP32-S3! Count: %d, count); // 发送数据 int err sendto(sock, tx_buffer, strlen(tx_buffer), 0, (struct sockaddr *)dest_addr, sizeof(dest_addr)); if(err 0) { ESP_LOGE(TAG, Error occurred during sendto: errno %d, errno); } else { ESP_LOGI(TAG, Sent %d bytes: %s, err, tx_buffer); } vTaskDelay(pdMS_TO_TICKS(1000)); } close(sock); vTaskDelete(NULL); } void app_main(void) { wifi_init_sta(); // 创建UDP客户端任务 xTaskCreate(udp_client_task, udp_client, 4096, NULL, 5, NULL); }五、HTTP 客户端开发HTTP 是互联网中最常用的应用层协议我们可以使用 HTTP 协议访问互联网上的各种 API。5.1 ESP-IDF HTTP 客户端组件ESP-IDF 提供了一个功能强大的 HTTP 客户端组件esp_http_client它支持 GET、POST、PUT、DELETE 等 HTTP 方法支持 HTTPS支持重定向支持 Cookie 等。5.2 实战项目 5HTTP 客户端获取天气信息我们将使用 HTTP 客户端访问和风天气 API获取实时天气信息。完整代码c运行#include stdio.h #include string.h #include freertos/FreeRTOS.h #include freertos/task.h #include esp_wifi.h #include esp_event.h #include nvs_flash.h #include esp_log.h #include esp_http_client.h #include cJSON.h static const char *TAG HTTP_CLIENT; #define WIFI_SSID 你的Wi-Fi名称 #define WIFI_PASS 你的Wi-Fi密码 #define WEATHER_API_KEY 你的和风天气API密钥 #define CITY_ID 101010100 // 北京的城市ID // Wi-Fi初始化代码同上此处省略 void wifi_init_sta(void) { ... } // HTTP事件处理函数 esp_err_t http_event_handler(esp_http_client_event_t *evt) { static char *response_buffer NULL; static int response_len 0; switch(evt-event_id) { case HTTP_EVENT_ON_DATA: // 接收HTTP响应数据 if(!esp_http_client_is_chunked_response(evt-client)) { // 重新分配缓冲区 response_buffer realloc(response_buffer, response_len evt-data_len 1); memcpy(response_buffer response_len, evt-data, evt-data_len); response_len evt-data_len; response_buffer[response_len] \0; } break; case HTTP_EVENT_ON_FINISH: // HTTP请求完成解析JSON数据 if(response_buffer ! NULL) { ESP_LOGI(TAG, HTTP response: %s, response_buffer); // 解析JSON cJSON *root cJSON_Parse(response_buffer); if(root ! NULL) { cJSON *now cJSON_GetObjectItemCaseSensitive(root, now); if(now ! NULL) { cJSON *temp cJSON_GetObjectItemCaseSensitive(now, temp); cJSON *text cJSON_GetObjectItemCaseSensitive(now, text); if(temp ! NULL text ! NULL) { ESP_LOGI(TAG, ); ESP_LOGI(TAG, 北京天气: %s, text-valuestring); ESP_LOGI(TAG, 温度: %s℃, temp-valuestring); ESP_LOGI(TAG, ); } } cJSON_Delete(root); } free(response_buffer); response_buffer NULL; response_len 0; } break; default: break; } return ESP_OK; } void http_client_task(void *pvParameters) { char url[256]; // 构造API请求URL sprintf(url, https://devapi.qweather.com/v7/weather/now?location%skey%s, CITY_ID, WEATHER_API_KEY); esp_http_client_config_t config { .url url, .event_handler http_event_handler, .skip_cert_common_name_check true, // 跳过证书验证仅用于测试 }; while(1) { ESP_LOGI(TAG, Fetching weather information...); esp_http_client_handle_t client esp_http_client_init(config); esp_err_t err esp_http_client_perform(client); if(err ESP_OK) { ESP_LOGI(TAG, HTTP request successful, status code: %d, esp_http_client_get_status_code(client)); } else { ESP_LOGE(TAG, HTTP request failed: %s, esp_err_to_name(err)); } esp_http_client_cleanup(client); vTaskDelay(pdMS_TO_TICKS(300000)); // 每5分钟更新一次天气 } vTaskDelete(NULL); } void app_main(void) { wifi_init_sta(); // 创建HTTP客户端任务 xTaskCreate(http_client_task, http_client, 8192, NULL, 5, NULL); }注意你需要先到和风天气官网和风天气开发服务 ~ 强大、丰富的天气数据服务注册账号获取免费的 API 密钥将代码中的WEATHER_API_KEY替换为你自己的 API 密钥你可以在和风天气官网查询你所在城市的 ID替换CITY_ID六、智能配网技术在实际的物联网产品中我们不可能将 Wi-Fi 名称和密码硬编码到固件中。我们需要一种方式让用户能够方便地将设备连接到自己的 Wi-Fi 网络这就是智能配网技术。ESP32-S3 支持多种智能配网方式SmartConfig 一键配网手机 APP 发送包含 Wi-Fi 名称和密码的广播包ESP32-S3 监听并解析这些广播包AP 配网ESP32-S3 创建一个热点用户用手机连接这个热点然后通过网页或 APP 将 Wi-Fi 信息发送给 ESP32-S3BLE 配网通过蓝牙低功耗将 Wi-Fi 信息发送给 ESP32-S36.1 实战项目 6SmartConfig 一键配网SmartConfig 是最常用的配网方式用户只需要在手机 APP 中输入 Wi-Fi 密码点击配网即可完成设备连接。完整代码c运行#include stdio.h #include string.h #include freertos/FreeRTOS.h #include freertos/task.h #include esp_wifi.h #include esp_event.h #include nvs_flash.h #include esp_log.h #include esp_smartconfig.h static const char *TAG SMARTCONFIG; static EventGroupHandle_t s_wifi_event_group; const int WIFI_CONNECTED_BIT BIT0; const int ESPTOUCH_DONE_BIT BIT1; static 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) { xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } else if (event_base WIFI_EVENT event_id WIFI_EVENT_STA_DISCONNECTED) { ESP_LOGW(TAG, Wi-Fi disconnected); esp_wifi_connect(); xEventGroupClearBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } 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 address: IPSTR, IP2STR(event-ip_info.ip)); xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT); } } static void smartconfig_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data) { 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; 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)); ESP_LOGI(TAG, SSID: %s, wifi_config.sta.ssid); ESP_LOGI(TAG, Password: %s, wifi_config.sta.password); // 配置Wi-Fi ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, wifi_config)); // 连接Wi-Fi ESP_ERROR_CHECK(esp_wifi_connect()); } else if (event_base SC_EVENT event_id SC_EVENT_SEND_ACK_DONE) { xEventGroupSetBits(s_wifi_event_group, ESPTOUCH_DONE_BIT); } } void smartconfig_task(void *pvParameters) { EventBits_t uxBits; // 启动SmartConfig ESP_ERROR_CHECK(esp_smartconfig_set_type(SC_TYPE_ESPTOUCH)); smartconfig_start_config_t cfg SMARTCONFIG_START_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_smartconfig_start(cfg)); while(1) { // 等待Wi-Fi连接和SmartConfig完成 uxBits xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | ESPTOUCH_DONE_BIT, true, false, portMAX_DELAY); if(uxBits WIFI_CONNECTED_BIT) { ESP_LOGI(TAG, Wi-Fi connected); } if(uxBits ESPTOUCH_DONE_BIT) { ESP_LOGI(TAG, SmartConfig completed); esp_smartconfig_stop(); vTaskDelete(NULL); } } } void app_main(void) { ESP_ERROR_CHECK(nvs_flash_init()); ESP_ERROR_CHECK(esp_netif_init()); ESP_ERROR_CHECK(esp_event_loop_create_default()); s_wifi_event_group xEventGroupCreate(); 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)); ESP_ERROR_CHECK(esp_event_handler_register(SC_EVENT, ESP_EVENT_ANY_ID, smartconfig_event_handler, NULL)); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_start()); // 创建SmartConfig任务 xTaskCreate(smartconfig_task, smartconfig, 4096, NULL, 5, NULL); }实验步骤编译烧录代码到 ESP32-S3 开发板打开手机上的 ESP-Touch APP可以在应用商店搜索下载确保手机连接到你想要让 ESP32-S3 连接的 Wi-Fi 网络在 APP 中输入 Wi-Fi 密码点击 确认 开始配网观察串口输出当看到 SmartConfig completed 时说明配网成功七、Wi-Fi 开发最佳实践使用事件驱动架构不要在主循环中轮询 Wi-Fi 状态使用事件处理函数响应 Wi-Fi 状态变化实现自动重连当 Wi-Fi 断开连接时自动尝试重新连接合理设置任务优先级网络相关任务的优先级应该高于一般的应用任务注意内存管理网络通信会使用大量内存及时释放不需要的内存处理网络错误网络通信是不可靠的一定要处理各种可能的错误情况使用 HTTPS在生产环境中一定要使用 HTTPS 协议进行数据传输保证数据安全八、常见问题解答与避坑指南8.1 Wi-Fi 连接失败怎么办解决方案检查 Wi-Fi 名称和密码是否正确确保 Wi-Fi 路由器工作正常确保 ESP32-S3 在 Wi-Fi 信号覆盖范围内检查 Wi-Fi 加密方式是否支持ESP32-S3 不支持 WEP 加密尝试重启 ESP32-S3 和路由器8.2 获取不到 IP 地址怎么办解决方案检查路由器的 DHCP 服务是否开启确保路由器的 IP 地址池没有用完尝试重启路由器尝试使用静态 IP 地址8.3 TCP 通信不稳定怎么办解决方案检查网络连接是否稳定增加数据重传机制合理设置 socket 超时时间避免在网络任务中执行耗时操作8.4 SmartConfig 配网失败怎么办解决方案确保手机和 ESP32-S3 在同一个 2.4GHz Wi-Fi 网络下ESP32-S3 不支持 5GHz Wi-Fi 配网确保 Wi-Fi 名称和密码不包含特殊字符尝试靠近路由器增强信号尝试重启手机和 ESP32-S3尝试使用 AP 配网方式8.5 HTTP 请求失败怎么办解决方案检查网络连接是否正常检查 URL 是否正确检查 API 密钥是否正确确保 API 服务器正常工作尝试增加超时时间九、课后作业基础练习实现 ESP32-S3 连接到 Wi-Fi 路由器进阶练习创建一个 TCP 服务器接收电脑发送的数据并回显综合练习实现 HTTP 客户端获取天气信息并显示在 OLED 显示屏上挑战练习实现 SmartConfig 一键配网功能配网成功后自动连接到 Wi-Fi 并上报设备信息十、下期预告第 7 讲将学习蓝牙 BLE 开发这是 ESP32-S3 另一个重要的无线通信功能。我们将详细讲解 BLE 广播、连接、服务与特征值、数据传输等核心概念并通过实战项目演示如何实现 ESP32-S3 与手机之间的 BLE 通信。写在最后Wi-Fi 网络开发是物联网开发的核心技能也是 ESP32-S3 最强大的功能之一。希望通过本讲的学习你能够熟练掌握 ESP32-S3 的 Wi-Fi 开发技术能够独立开发出能够连接互联网的物联网设备。本讲的所有实战代码我已经上传到了我的 GitHub 仓库大家可以在评论区留言获取。如果你在学习过程中遇到任何问题欢迎在评论区留言讨论。点赞收藏不迷路关注我带你从零基础成为 ESP32-S3 开发高手ESP32-S3、ESP-IDF v5.5、Wi-Fi Station、Wi-Fi AP、TCP 通信、UDP 通信、HTTP 客户端、SmartConfig 一键配网、物联网