1.总体描述
普通单片机实现以太网联网,需采用「内置 MAC + 外接 PHY 芯片」的硬件方案:单片机内置 MAC 与外接 PHY 通过 RMII 接口通信,PHY 芯片外接网络变压器后,即可接入路由器 / 交换机加入局域网。但这种方案需要开发者自行编写 PHY 驱动、移植 lwIP 协议栈、绑定 MAC 与 lwIP,开发难度大、周期长。
而 ESP32-S3 将 WiFi 射频与 MAC 硬件集成在单芯片内,同时通过函数库封装了硬件操作,还完成了 lwIP 协议栈与硬件库的适配绑定。开发者仅需初始化 lwIP 并调用硬件库初始化 WiFi,即可直接进行 TCP/UDP 等网络编程。
|-------------|--------------------------|-------------------------|------------------------------|
| 层级 | 负责内容 | ESP-IDF 对应组件 | 代码里的体现 |
| 物理层 (PHY) | 无线信号收发、调制解调 | 内置 WiFi PHY / 外接以太网 PHY | 封装为库 |
| 数据链路层 (MAC) | 帧封装 / 解封装、MAC 地址、CSMA/CA | ESP32 硬件 WiFi MAC + 驱动 | esp_wifi_init() 初始化硬件 MAC |
| 网络层 (IP) | IP 地址、ARP、ICMP、路由 | lwIP 协议栈 | esp_netif_init() 初始化 lwIP 核心 |
| 传输层 | TCP/UDP 可靠传输、端口 | lwIP TCP/UDP 实现 | httpd 底层调用 lwIP 的 TCP Socket |
| 应用层 | HTTP/MQTT/RTSP 等业务协议 | ESP-IDF 封装的应用层组件 | TCP UDP数据流 |
2.wifi扫描示例
参考idf sdk的 < esp-idf-v5.5.4\examples\wifi\scan\main\scan.c >
cpp
/* Scan 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.
*/
/*
This example shows how to scan for available set of APs.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/event_groups.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "esp_event.h"
#include "nvs_flash.h"
#include "regex.h"
#define DEFAULT_SCAN_LIST_SIZE 5 //注意一定不能写太大,这个会占用大量的栈空间
#ifdef CONFIG_EXAMPLE_USE_SCAN_CHANNEL_BITMAP
#define USE_CHANNEL_BITMAP 1
#define CHANNEL_LIST_SIZE 3
static uint8_t channel_list[CHANNEL_LIST_SIZE] = {1, 6, 11};
#endif /*CONFIG_EXAMPLE_USE_SCAN_CHANNEL_BITMAP*/
static const char *TAG = "scan";
static void print_auth_mode(int authmode)
{
switch (authmode) {
case WIFI_AUTH_OPEN:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_OPEN");
break;
case WIFI_AUTH_OWE:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_OWE");
break;
case WIFI_AUTH_WEP:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WEP");
break;
case WIFI_AUTH_WPA_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_PSK");
break;
case WIFI_AUTH_WPA2_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_PSK");
break;
case WIFI_AUTH_WPA_WPA2_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_WPA2_PSK");
break;
case WIFI_AUTH_ENTERPRISE:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_ENTERPRISE");
break;
case WIFI_AUTH_WPA3_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_PSK");
break;
case WIFI_AUTH_WPA2_WPA3_PSK:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_PSK");
break;
case WIFI_AUTH_WPA3_ENTERPRISE:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_ENTERPRISE");
break;
case WIFI_AUTH_WPA2_WPA3_ENTERPRISE:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_ENTERPRISE");
break;
case WIFI_AUTH_WPA3_ENT_192:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_ENT_192");
break;
default:
ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_UNKNOWN");
break;
}
}
static void print_cipher_type(int pairwise_cipher, int group_cipher)
{
switch (pairwise_cipher) {
case WIFI_CIPHER_TYPE_NONE:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_NONE");
break;
case WIFI_CIPHER_TYPE_WEP40:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP40");
break;
case WIFI_CIPHER_TYPE_WEP104:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP104");
break;
case WIFI_CIPHER_TYPE_TKIP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP");
break;
case WIFI_CIPHER_TYPE_CCMP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_CCMP");
break;
case WIFI_CIPHER_TYPE_TKIP_CCMP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
break;
case WIFI_CIPHER_TYPE_AES_CMAC128:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_AES_CMAC128");
break;
case WIFI_CIPHER_TYPE_SMS4:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_SMS4");
break;
case WIFI_CIPHER_TYPE_GCMP:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_GCMP");
break;
case WIFI_CIPHER_TYPE_GCMP256:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_GCMP256");
break;
default:
ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
break;
}
switch (group_cipher) {
case WIFI_CIPHER_TYPE_NONE:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_NONE");
break;
case WIFI_CIPHER_TYPE_WEP40:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP40");
break;
case WIFI_CIPHER_TYPE_WEP104:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP104");
break;
case WIFI_CIPHER_TYPE_TKIP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP");
break;
case WIFI_CIPHER_TYPE_CCMP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_CCMP");
break;
case WIFI_CIPHER_TYPE_TKIP_CCMP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
break;
case WIFI_CIPHER_TYPE_SMS4:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_SMS4");
break;
case WIFI_CIPHER_TYPE_GCMP:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_GCMP");
break;
case WIFI_CIPHER_TYPE_GCMP256:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_GCMP256");
break;
default:
ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_UNKNOWN");
break;
}
}
#ifdef USE_CHANNEL_BITMAP
static void array_2_channel_bitmap(const uint8_t channel_list[], const uint8_t channel_list_size, wifi_scan_config_t *scan_config) {
for(uint8_t i = 0; i < channel_list_size; i++) {
uint8_t channel = channel_list[i];
scan_config->channel_bitmap.ghz_2_channels |= (1 << channel);
}
}
#endif /*USE_CHANNEL_BITMAP*/
/* Initialize Wi-Fi as sta and set scan method */
static void wifi_scan(void)
{
ESP_ERROR_CHECK(esp_netif_init());//网络协议栈初始化
ESP_ERROR_CHECK(esp_event_loop_create_default());//创建默认事件循环(处理WiFi/IP等事件)
esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();//创建WiFi STA模式网络接口(绑定WiFi硬件与lwIP)
assert(sta_netif);
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();//WiFi初始化参数(默认配置)
ESP_ERROR_CHECK(esp_wifi_init(&cfg));//初始化WiFi硬件与驱动
uint16_t number = DEFAULT_SCAN_LIST_SIZE;
wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
uint16_t ap_count = 0;
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));//设置WiFi模式为STA(站点模式)
ESP_ERROR_CHECK(esp_wifi_start());//启动WiFi
while (1)
{
/* code */
memset(ap_info, 0, sizeof(ap_info));//清空AP信息缓存
#ifdef USE_CHANNEL_BITMAP
wifi_scan_config_t *scan_config = (wifi_scan_config_t *)calloc(1,sizeof(wifi_scan_config_t));
if (!scan_config) {
ESP_LOGE(TAG, "Memory Allocation for scan config failed!");
return;
}
array_2_channel_bitmap(channel_list, CHANNEL_LIST_SIZE, scan_config);
esp_wifi_scan_start(scan_config, true);//按指定信道扫描(阻塞式)
free(scan_config);
#else
esp_wifi_scan_start(NULL, true);//全信道扫描(阻塞式)
#endif /*USE_CHANNEL_BITMAP*/
ESP_LOGI(TAG, "Max AP number ap_info can hold = %u", number);
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));//获取扫描到的AP数量
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));//获取扫描到的AP信息
ESP_LOGI(TAG, "Total APs scanned = %u, actual AP number ap_info holds = %u", ap_count, number);
for (int i = 0; i < number&&i<ap_count; i++) {
ESP_LOGI(TAG,"AP list:------------------------------------------------");
ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);
ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);
print_auth_mode(ap_info[i].authmode);//打印认证模式(Open/WPA2/WPA3等)
if (ap_info[i].authmode != WIFI_AUTH_WEP) {
print_cipher_type(ap_info[i].pairwise_cipher, ap_info[i].group_cipher);//打印加密类型
}
ESP_LOGI(TAG, "Channel \t\t%d", ap_info[i].primary);
}
vTaskDelay(pdMS_TO_TICKS(1000));//每秒扫描一次
}
}
void klp_wifi_scan(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 );
wifi_scan();
}
只需要在app_main中调用 klp_wifi_scan() 即可扫描打印wifi
cpp
#include <stdio.h>
#include "klpgpio.h"
#include "klpws2812.h"
#include "klpcamera.h"
#include "klpwifiscan.h"
void app_main(void)
{
// ws2812();
// klpgpio();
// klpcamera();
klp_wifi_scan();
}
wifi信息打印如图:

3.wifi的AP和sta共存功能
- AP(热点,供其他设备连接)
- STA(站点,访问热点联网)
这里使用了napt功能,类似于路由器:
|------|----------------------------------|------------------|----------------------------------|
| 类型 | 全称 | 转换内容 | 适用场景 |
| NAT | Network Address Translation | 只转换 IP 地址 | 一个公网 IP 对应一个内网设备 |
| NAPT | Network Address Port Translation | 同时转换 IP 地址 + 端口号 | 一个公网 IP 对应 多个内网设备(最常用,家庭路由器都是这个) |
注意:必须开启 Enable L2 to L3 copy (AP+STA必须开) LWIP的NAPT,如图所示:


不开启以上功能会报错《E (5393) WiFi Sta: NAPT not enabled on the netif: 0x3fcbb464》,会导致连接AP的设备不能通过esp32s3的sta连接的路由器上网。
cpp
#include <stdio.h>
#include "klpwifiapsta.h"
/*
* SPDX-FileCopyrightText: 2023-2025 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Unlicense OR CC0-1.0
*/
/* WiFi softAP & station 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.
*/
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_mac.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "esp_netif_net_stack.h"
#include "esp_netif.h"
#include "nvs_flash.h"
#include "lwip/inet.h"
#include "lwip/netdb.h"
#include "lwip/sockets.h"
#if IP_NAPT
#include "lwip/lwip_napt.h"
#endif
#include "lwip/err.h"
#include "lwip/sys.h"
/* The examples use WiFi configuration that you can set via project configuration menu.
If you'd rather not, just change the below entries to strings with
the config you want - ie #define EXAMPLE_ESP_WIFI_STA_SSID "mywifissid"
*/
/* STA Configuration */
#define EXAMPLE_ESP_WIFI_STA_SSID "klp123456"
#define EXAMPLE_ESP_WIFI_STA_PASSWD "18902101360"
#define EXAMPLE_ESP_MAXIMUM_RETRY 5 // 最多重试5次
/* AP Scan Configuration */
#define ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK
/* AP Configuration */
#define EXAMPLE_ESP_WIFI_AP_SSID "esp32s3"
#define EXAMPLE_ESP_WIFI_AP_PASSWD "18902101360"
#define EXAMPLE_ESP_WIFI_CHANNEL 0//6 // 用6信道(干扰少),0自动信道
#define EXAMPLE_MAX_STA_CONN 4 // 最多连4个设备
/* The event group allows multiple bits for each event, but we only care about two events:
* - we are connected to the AP with an IP
* - we failed to connect after the maximum amount of retries */
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
/*DHCP server option*/
#define DHCPS_OFFER_DNS 0x02
static const char *TAG_AP = "WiFi SoftAP";
static const char *TAG_STA = "WiFi Sta";
static int s_retry_num = 0;
/* FreeRTOS event group to signal when we are connected/disconnected */
static EventGroupHandle_t s_wifi_event_group;
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_AP_STACONNECTED) {
wifi_event_ap_staconnected_t *event = (wifi_event_ap_staconnected_t *) event_data;
ESP_LOGI(TAG_AP, "Station "MACSTR" joined, AID=%d",
MAC2STR(event->mac), event->aid);
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_AP_STADISCONNECTED) {
wifi_event_ap_stadisconnected_t *event = (wifi_event_ap_stadisconnected_t *) event_data;
ESP_LOGI(TAG_AP, "Station "MACSTR" left, AID=%d, reason:%d",
MAC2STR(event->mac), event->aid, event->reason);
} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
esp_wifi_connect();
ESP_LOGI(TAG_STA, "Station started");
} 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_STA, "Got IP:" IPSTR, IP2STR(&event->ip_info.ip));
s_retry_num = 0;
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
}
// else if (event_base == IP_EVENT && event_id == IP_EVENT_ASSIGNED_IP_TO_CLIENT) {
// const ip_event_assigned_ip_to_client_t *e = (const ip_event_assigned_ip_to_client_t *)event_data;
// ESP_LOGI(TAG_AP, "Assigned IP to client: " IPSTR ", MAC=" MACSTR ", hostname='%s'",
// IP2STR(&e->ip), MAC2STR(e->mac), e->hostname);
// }
}
/* Initialize soft AP */
esp_netif_t *wifi_init_softap(void)
{
esp_netif_t *esp_netif_ap = esp_netif_create_default_wifi_ap();
wifi_config_t wifi_ap_config = {
.ap = {
.ssid = EXAMPLE_ESP_WIFI_AP_SSID,
.ssid_len = strlen(EXAMPLE_ESP_WIFI_AP_SSID),
.channel = EXAMPLE_ESP_WIFI_CHANNEL,
.password = EXAMPLE_ESP_WIFI_AP_PASSWD,
.max_connection = EXAMPLE_MAX_STA_CONN,
.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg = {
.required = false,
},
},
};
if (strlen(EXAMPLE_ESP_WIFI_AP_PASSWD) == 0) {
wifi_ap_config.ap.authmode = WIFI_AUTH_OPEN;
}
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_ap_config));
ESP_LOGI(TAG_AP, "wifi_init_softap finished. SSID:%s password:%s channel:%d",
EXAMPLE_ESP_WIFI_AP_SSID, EXAMPLE_ESP_WIFI_AP_PASSWD, EXAMPLE_ESP_WIFI_CHANNEL);
return esp_netif_ap;
}
/* Initialize wifi station */
esp_netif_t *wifi_init_sta(void)
{
esp_netif_t *esp_netif_sta = esp_netif_create_default_wifi_sta();
wifi_config_t wifi_sta_config = {
.sta = {
.ssid = EXAMPLE_ESP_WIFI_STA_SSID,
.password = EXAMPLE_ESP_WIFI_STA_PASSWD,
.scan_method = WIFI_ALL_CHANNEL_SCAN,
.failure_retry_cnt = EXAMPLE_ESP_MAXIMUM_RETRY,
/* Authmode threshold resets to WPA2 as default if password matches WPA2 standards (password len => 8).
* If you want to connect the device to deprecated WEP/WPA networks, Please set the threshold value
* to WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK and set the password with length and format matching to
* WIFI_AUTH_WEP/WIFI_AUTH_WPA_PSK standards.
*/
.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,
.sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
},
};
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_sta_config) );
ESP_LOGI(TAG_STA, "wifi_init_sta finished.");
return esp_netif_sta;
}
void softap_set_dns_addr(esp_netif_t *esp_netif_ap,esp_netif_t *esp_netif_sta)
{
esp_netif_dns_info_t dns;
esp_netif_get_dns_info(esp_netif_sta,ESP_NETIF_DNS_MAIN,&dns);
uint8_t dhcps_offer_option = DHCPS_OFFER_DNS;
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_stop(esp_netif_ap));
ESP_ERROR_CHECK(esp_netif_dhcps_option(esp_netif_ap, ESP_NETIF_OP_SET, ESP_NETIF_DOMAIN_NAME_SERVER, &dhcps_offer_option, sizeof(dhcps_offer_option)));
ESP_ERROR_CHECK(esp_netif_set_dns_info(esp_netif_ap, ESP_NETIF_DNS_MAIN, &dns));
ESP_ERROR_CHECK_WITHOUT_ABORT(esp_netif_dhcps_start(esp_netif_ap));
}
void klp_wifi_ap_sta(void)
{
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
//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);
/* Initialize event group */
s_wifi_event_group = xEventGroupCreate();
/* Register Event handler */
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,
ESP_EVENT_ANY_ID,
&wifi_event_handler,
NULL,
NULL));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
IP_EVENT_STA_GOT_IP,
&wifi_event_handler,
NULL,
NULL));
// ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,
// IP_EVENT_ASSIGNED_IP_TO_CLIENT,
// &wifi_event_handler,
// NULL,
// NULL));
/*Initialize WiFi */
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));
/* Initialize AP */
ESP_LOGI(TAG_AP, "ESP_WIFI_MODE_AP");
esp_netif_t *esp_netif_ap = wifi_init_softap();
/* Initialize STA */
ESP_LOGI(TAG_STA, "ESP_WIFI_MODE_STA");
esp_netif_t *esp_netif_sta = wifi_init_sta();
/* Start WiFi */
ESP_ERROR_CHECK(esp_wifi_start() );
/*
* Wait until either the connection is established (WIFI_CONNECTED_BIT) or
* connection failed for the maximum number of re-tries (WIFI_FAIL_BIT).
* The bits are set by event_handler() (see above)
*/
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
pdFALSE,
pdFALSE,
portMAX_DELAY);
/* xEventGroupWaitBits() returns the bits before the call returned,
* hence we can test which event actually happened. */
if (bits & WIFI_CONNECTED_BIT) {
ESP_LOGI(TAG_STA, "connected to ap SSID:%s password:%s",
EXAMPLE_ESP_WIFI_STA_SSID, EXAMPLE_ESP_WIFI_STA_PASSWD);
softap_set_dns_addr(esp_netif_ap,esp_netif_sta);
} else if (bits & WIFI_FAIL_BIT) {
ESP_LOGI(TAG_STA, "Failed to connect to SSID:%s, password:%s",
EXAMPLE_ESP_WIFI_STA_SSID, EXAMPLE_ESP_WIFI_STA_PASSWD);
} else {
ESP_LOGE(TAG_STA, "UNEXPECTED EVENT");
return;
}
/* Set sta as the default interface */
esp_netif_set_default_netif(esp_netif_sta);
/* Enable napt on the AP netif */
if (esp_netif_napt_enable(esp_netif_ap) != ESP_OK) {
ESP_LOGE(TAG_STA, "NAPT not enabled on the netif: %p", esp_netif_ap);
}
while (1)
{
/* code */
vTaskDelay(pdMS_TO_TICKS(1000));
}
}
同样 wifi扫描示例一样,也需要在 app_main 函数添加 klp_wifi_ap_sta 函数:
cpp
#include <stdio.h>
#include "klpgpio.h"
#include "klpws2812.h"
#include "klpcamera.h"
#include "klpwifiscan.h"
#include "klpwifiapsta.h"
void app_main(void)
{
// ws2812();
// klpgpio();
// klpcamera();
// klp_wifi_scan();
klp_wifi_ap_sta();
}