203-ESP32_SDK开发-softAP+station共存模式
<p><iframe name="ifd" src="https://mnifdv.cn/resource/cnblogs/LearnESP32" frameborder="0" scrolling="auto" width="100%" height="1500"></iframe></p>
说明
这节测试一下模组softAP+station共存模式
代码文件
#define event_handler_c_ #include <stdio.h> #include <string.h> #include "event_handler.h" //----------------------------------------- static const char *TAG = "event_handler"; /*重新连接热点*/ void WIFI_EVENT_STA_DISCONNECTED_FUN(void) { esp_wifi_connect();//连接热点 ESP_LOGI(TAG,"connect to the AP fail"); } /*有设备连接上ESP32的热点*/ void WIFI_EVENT_AP_STACONNECTED_FUN( void* event_data ) { wifi_event_ap_staconnected_t* event = (wifi_event_ap_staconnected_t*) event_data; /*打印连接设备的MAC地址*/ ESP_LOGI(TAG, "station "MACSTR" join, AID=%d", MAC2STR(event->mac), event->aid); } /*有设备断开和ESP32的热点*/ void WIFI_EVENT_AP_STADISCONNECTED_FUN( void* event_data ) { wifi_event_ap_stadisconnected_t* event = (wifi_event_ap_stadisconnected_t*) event_data; /*打印断开设备的MAC地址*/ ESP_LOGI(TAG, "station "MACSTR" leave, AID=%d",MAC2STR(event->mac), event->aid); } /*连接上路由器(获取到了分配的IP地址)*/ void IP_EVENT_STA_GOT_IP_FUN( void* event_data ) { ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data; ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip)); } /*WiFi事件回调*/ void wifi_event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data) { /* 事件剥离 */ if( event_base == WIFI_EVENT ) { switch ( event_id ) { case WIFI_EVENT_STA_START: esp_wifi_connect(); break; // STA START case WIFI_EVENT_STA_STOP: ESP_LOGI(TAG,"WIFI_EVENT_STA_STOP"); break; // STA STOP case WIFI_EVENT_STA_DISCONNECTED: WIFI_EVENT_STA_DISCONNECTED_FUN(); break; //和路由器断开 case WIFI_EVENT_AP_START: ESP_LOGI(TAG,"WIFI_EVENT_AP_START"); break; // AP START case WIFI_EVENT_AP_STOP: ESP_LOGI(TAG,"WIFI_EVENT_AP_STOP"); break; // AP STOP case WIFI_EVENT_AP_STACONNECTED: WIFI_EVENT_AP_STACONNECTED_FUN( event_data ); break; //有设备连接上ESP32的热点 case WIFI_EVENT_AP_STADISCONNECTED: WIFI_EVENT_AP_STADISCONNECTED_FUN(event_data ); break; //有设备断开和ESP32的热点 default: break; } } else if( event_base == IP_EVENT ) // 路由事件ID 组 { switch ( event_id ) { case IP_EVENT_STA_GOT_IP: IP_EVENT_STA_GOT_IP_FUN(event_data); break; //获取到指定IP case IP_EVENT_STA_LOST_IP: ESP_LOGI(TAG,"IP_EVENT_STA_LOST_IP"); break; case IP_EVENT_AP_STAIPASSIGNED: ESP_LOGI(TAG,"IP_EVENT_AP_STAIPASSIGNED"); break; default: break; } } }
#ifndef event_handler_h_ #define event_handler_h_ #ifndef event_handler_c_ #define event_handler_c_ extern #else #define event_handler_c_ #endif #include "esp_system.h" #include "esp_wifi.h" #include "nvs_flash.h" #include "esp_log.h" #include "wifi_softap_sta.h" /*WiFi事件回调*/ void wifi_event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data); #endif
#define wifi_softap_c_ #include <stdio.h> #include <string.h> #include "wifi_softap_sta.h" //----------------------------------------- /*配置模组自身的无线热点*/ #define ESP_WIFI_AP_SSID "ESP32_WIFI" //设置模块发出的无线名称 #define ESP_WIFI_AP_PASS "11223344" //无线密码 #define ESP_WIFI_AP_CHANNEL 11 //信道(默认1) #define ESP_WIFI_AP_MAX_COUNT 5 //最大连接数(最大10个) /*配置模组连接的路由器*/ #define ESP_WIFI_STA_SSID "QQQQQ" //设置模块发出的无线名称 #define ESP_WIFI_STA_PASS "11223344" //无线密码 void wifi_init_softap_sta(void) { esp_event_handler_instance_t instance_any_id = {0}; //处理ID 实例句柄 esp_event_handler_instance_t instance_got_ip = {0}; //处理IP 实例句柄 esp_netif_create_default_wifi_ap();//创建有 TCP/IP 堆栈的默认网络接口实例绑定AP。 esp_netif_create_default_wifi_sta();//创建有 TCP/IP 堆栈的默认网络接口实例绑定STA。 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg));//创建 Wi-Fi 驱动程序任务,并初始化 Wi-Fi 驱动程序。 /*注册系统事件回调函数*/ ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, //WiFi事件函数 ESP_EVENT_ANY_ID, //事件ID &wifi_event_handler, //回调函数 NULL, &instance_any_id)); /*注册系统事件回调函数*/ ESP_ERROR_CHECK( esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &wifi_event_handler, NULL, &instance_got_ip) ); /*配置连接的热点参数*/ wifi_config_t wifi_config_sta = { .sta = { .threshold.authmode = WIFI_AUTH_WPA2_PSK,//加密方式 /*配置pmf,当前最新加密技术*/ .pmf_cfg = { .capable = true, //告诉热点这边有能力使用PMF进行加密通信(防止窃听密码) .required = false //告诉热点这边不强制要求使用PMF进行加密通信(防止窃听密码) }, }, }; strcpy( (char *) wifi_config_sta.sta.ssid , ESP_WIFI_STA_SSID ); if(strlen(ESP_WIFI_STA_PASS)==0)//没有密码 { wifi_config_sta.sta.threshold.authmode = WIFI_AUTH_OPEN;//加密方式 } else{ strcpy( (char *) wifi_config_sta.sta.password , ESP_WIFI_STA_PASS); } /*配置热点*/ wifi_config_t wifi_config_ap = { .ap = { // .ssid = ESP_WIFI_AP_SSID, // .ssid_len = strlen(ESP_WIFI_AP_SSID), .channel = ESP_WIFI_AP_CHANNEL, // .password = ESP_WIFI_AP_PASS, .max_connection = ESP_WIFI_AP_MAX_COUNT, .authmode = WIFI_AUTH_WPA_WPA2_PSK }, }; strcpy( (char *) wifi_config_ap.ap.ssid , ESP_WIFI_AP_SSID ); wifi_config_ap.ap.ssid_len = strlen(ESP_WIFI_AP_SSID); strcpy( (char *) wifi_config_ap.ap.password , ESP_WIFI_AP_PASS); /*如果密码长度是0,则不设置密码*/ if (strlen(ESP_WIFI_AP_PASS) == 0) { wifi_config_ap.ap.authmode = WIFI_AUTH_OPEN; } ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));//设置AP+STA模式 // 设置AP模式配置 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP , &wifi_config_ap) ); // 设置STA模式配置 ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config_sta) ); ESP_ERROR_CHECK(esp_wifi_start());//启动 }
#ifndef wifi_softap_h_ #define wifi_softap_h_ #ifndef wifi_softap_c_ #define wifi_softap_c_ extern #else #define wifi_softap_c_ #endif #include "event_handler.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" #include "esp_log.h" void wifi_init_softap_sta(void); #endif
使用
1,把文件放到自己的工程里面
列如,我放到了工程的main文件夹里面
2,在CMakeLists.txt 文件里面包含下
3,调用
#include <stdio.h> #include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/queue.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" #include "nvs_flash.h" #include "esp_log.h" #include "wifi_softap_sta.h" void app_main(void) { //初始化 NVS(配置WiFi的参数存储需要用到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); //初始化内部的lwip ESP_ERROR_CHECK(esp_netif_init()); //创建系统事件任务 ESP_ERROR_CHECK(esp_event_loop_create_default()); //初始化配置AP+STA wifi_init_softap_sta(); }
4,根据自己的情况设置下参数
5,编译下载并观看日志
日志上会显示模组连接路由器以后分配的IP地址
也可以看到有了一个名称为 ESP32_WIFI 的热点