<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 的熱點