作為接入點的第一個任務是使用esp_wifi_set_mode()函數設置ESP32 函數並傳遞請求,作為接入點,可以把ESP32設置為AP或者APSTA,即
esp_wifi_set_mode(WIFI_MODE_STA)
或者
esp_wifi_set_mode(WIFI_MODE_APSTA)
接下來我們需要提供配置信息。 我們通過填充wifi_ap_config_t 來做到這一點。
該 wifi_ap_config_t 包含:
• SSID - WiFi的SSID名稱,用於連接站。
• ssid_len - SSID的字節長度,如果不是NULL終止。
• 密碼 - 用於站驗證的密碼。
• 渠道 - 這個例子中我們使用的網絡通道。
• authmode - 我們如何想站進行身份驗證(如果人)。 選擇是
◦ OPEN
◦ WEP
◦ WPA
◦ WPA2
◦ wpa_wpa2
• ssid_hidden - 我們是否應該廣播SSID我們。
• max_connection - 並發站的數量。 默認值和最大值是4。
• beacon_interval - 未知。 100。
此結構的初始化示例是:
wifi_config_t apConfig = { .ap = { .ssid="<access point name>", .ssid_len=0, .password="<password>", .channel=0, .authmode=WIFI_AUTH_OPEN, .ssid_hidden=0, .max_connection=4, .beacon_interval=100 } };
然后,我們調用
esp_wifi_set_config(WIFI_IF_AP,&apConfig);
將參數進行設置,最后調用esp_wifi_start()使WIFI開始工作。
下面是ESP32作為接入點的相關源碼:
#include <string.h> #include "freertos/FreeRTOS.h" #include "freertos/task.h" #include "freertos/event_groups.h" #include "esp_system.h" #include "esp_wifi.h" #include "esp_event_loop.h" #include "esp_log.h" #include "nvs_flash.h" #include "driver/gpio.h" #include "esp_types.h" /* FreeRTOS Task Handle -------------------------------------------------------*/ /* FreeRTOS Semaphore Handle --------------------------------------------------*/ /* FreeRTOS event group to signal when we are connected & ready to make a request */ static const char *TAG = "example"; //#define LED_GPIO_NUM GPIO_NUM_25 #define LED_GPIO_NUM GPIO_NUM_4//LED閃爍接口,為以后通過LED顯示連接狀態做拓展准備。 #define CONFIG_AP_SSID "ESP32" #define CONFIG_AP_PASSWORD "12345678"//配置AP的SSID 和password uint8_t ApMac[6];//網卡地址 /** * @brief no . * @note no. * @param no. * @retval no. */ esp_err_t event_handler(void *ctx, system_event_t *event)//等待回調事件 { switch (event->event_id)//對事件進行識別 { case SYSTEM_EVENT_STA_START: ESP_LOGI(TAG, "Connecting to AP..."); esp_wifi_connect(); break; case SYSTEM_EVENT_STA_GOT_IP: ESP_LOGI(TAG, "Connected."); break; case SYSTEM_EVENT_STA_DISCONNECTED: //ESP_LOGI(TAG, "Wifi disconnected, try to connect again..."); esp_wifi_connect(); break; default: break; } return ESP_OK; } /** * @brief no . * @note no. * @param no. * @retval no. */ void led_init( void ) { gpio_set_direction( LED_GPIO_NUM , GPIO_MODE_OUTPUT ); } /** * @brief no . * @note no. * @param no. * @retval no. */ void led_task( void *pvParameters ) { int level = 0; for( ;; ) { gpio_set_level( LED_GPIO_NUM , level); level = !level; vTaskDelay(300 / portTICK_PERIOD_MS); } } void app_main(void) { nvs_flash_init();//初始化NVS內存 led_init(); tcpip_adapter_init();//tcp/IP配置 ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );//回調,當ESP32檢測到某些類型的WiFi相關事件時調用。 wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();//定義一個名為cfg的wifi_init_config_t結構體。wifi_init_config_t中的參數可由menuconfig配置 ESP_ERROR_CHECK( esp_wifi_init(&cfg) ); ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );//指示ESP32將這些設置記錄到閃存 ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );//模式設置為AP esp_wifi_get_mac( ESP_IF_WIFI_AP , ApMac );//獲取DHCP分配的IP接口的mac。 wifi_config_t ap_config = { .ap = { // .ssid = ssid, .password = CONFIG_AP_PASSWORD, .ssid_len = 0, .max_connection = 4, .authmode = WIFI_AUTH_WPA_PSK } };//ap接入點參數配置。 sprintf( (char *)ap_config.ap.ssid , "%s_%02X%02X" , CONFIG_AP_SSID , ApMac[4] , ApMac[5] ); esp_err_t tmp = esp_wifi_set_config(WIFI_IF_AP, &ap_config); ESP_ERROR_CHECK(esp_wifi_start()); esp_wifi_connect(); xTaskCreate( &led_task, "led task", 512, NULL, 3, NULL ); }
實驗現象:
打開minicom可以看到輸出:
打開手機WIFI,可以看到名為ESP32_44F1的WIFI熱點,打開熱點,輸入設置的PASSWORD:12345678即可連接成功,說明AP接口設置
編程講解:
使用連接站
當我們的ESP32是接入點時,我們說我們希望允許電台
合作 nnect它。 這帶來了管理這些電台的故事。 常見的事情
我們可能想做的是:
• 確定新車站何時連接
• 確定以前連接的電台何時離開
• 列出當前連接的電台
• 斷開ÒNE 或多個當前連接的站
我們可以注冊一個事件處理程序來檢測新站連接和與現有站斷開。 當我們成為接入點時,會產生ESP32 WiFi事件SYSTEM_EVENT_AP_START。當一個站連接時,ESP32西港島線提高 SYSTEM_EVENT_AP_STACONNECTED事件。 當一個站斷開,我們將看到 SYSTEM_EVENT_AP_DISCONNECTED事件。
我們可以使esp_wifi_get_station_list()函數獲取當前連接的電台,函數返回站的鏈表。 這個列表的存儲被分配給我們,我們應該調用 esp_wifi_free_station_list()釋放它當我們不再存在需要它時 。
從ESP32中,我們可以判斷很多為static項,比如當前連接數通過調用 wifi_softap_get_station_num()。 如果我們想找到那些站的細節,我們可以調用 wifi_softap_get_station_info(),它將返回鏈接列表wifi_sta_list_t,所以 我們必須調用wifi_softap_free_station_info()明確地釋放此調用與分配的存儲。
以下是一個代碼段的示例,其中列出了連接站的詳細信息:
uint8 stationCount = wifi_softap_get_station_num();
os_printf("stationCount = %d\n", stationCount); wifi_sta_list_t *stationInfo = wifi_softap_get_station_info(); if (stationInfo != NULL) { while (stationInfo != NULL) { os_printf("Station IP: %d.%d.%d.%d\n", IP2STR(&(stationInfo->ip))); stationInfo = STAILQ_NEXT(stationInfo, next); } wifi_softap_free_station_info(); }
如果由於某種原因,我們環境中的程序想強制斷開當前的連接的station,我們可以使用 esp_wifi_kick_station()來斷開。
WiFi在啟動時
ESP32可以將WiFi啟動信息存儲在閃存中。 這允許它在啟動時執行其功能,而無需向用戶詢問任何特殊的或附加信息。這種能力由函數esp_wifi_set_auto connect()和esp_wifi_get_auto_connect()完成。它們被用來自動連接的設置值和讀取保存在閃存中的值,設置賦值的函數為esp_wifi_set_config(),存儲方法通過esp_wifi_set_storage()來設置WiFi API配置存儲類型。
首先講解DHCP前需要了解什么是DHCP,DHCP即動態主機配置協議,它的作用是集中分配IP地址給主機,使網絡環境中的主機可以動態的獲得IP地址.如果想詳細了解,可以看如下兩個鏈接
https://baike.baidu.com/item/DHCP/218195?fr=aladdin
http://blog.csdn.net/u012359618/article/details/51872678
本文這里重點講解其在ESP32中的應用和配置。
DHCP客戶端
當ESP32作為站點連接到接入點時,它還運行DHCP客戶端連接到它在接入點的DHCP服務器。 在那里,站點提供其IP地址,網關地址和網絡掩碼, 我們可以這樣做:調用 tcpip_adapter_set_ip_info()在程序編寫時。
函數邏輯如下(詳情請回頭看上篇文章結尾):
tcpip_adapter_init();
tcpip_adapter_dhcpc_stop();
tcpip_adapter_set_ip_info();
esp_wifi_init();
esp_wifi_set_mode();
esp_wifi_set_config();
esp_wifi_start();
esp_wifi_config();
但是當我們想為這些數據設置我們自己的值時。調用的tcpip_adapter_set_ip_info()時需要的參數可以按如下方法設置
tcpip_adapter_ip_info_t ipInfo; IP4_ADDR(&ipInfo.ip, 192,168,1,99); IP4_ADDR(&ipInfo.gw, 192,168,1,1); IP4_ADDR(&ipInfo.netmask, 255,255,255,0); tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA, &ipInfo);
或者用字符串表示
tcpip_adapter_ip_info_t ipInfo; inet_pton(AF_INET,“192.168.1.99”,&ipInfo.ip); inet_pton(AF_INET,“192.168.1.1”,&ipInfo.gw); inet_pton(AF_INET,“255.255.255.0”,&ipInfo.netmask); tcpip_adapter_set_ip_info(TCPIP_ADAPTER_IF_STA,&ipInfo);
DHCP服務器
當ESP32作為接入點時,可能需要它作為DHCP服務器,以便連接站將能夠自然而然的分配IP地址,並獲得他們的子網掩碼和網關。DHCP服務器可以啟動和使用API調用設備中停止wifi_softap_dhcps_start() 和 wifi_softap_dhcps_stop(),當前DHCP服務器的狀態(啟動或停止),可以通過調用
wifi_softap_dhcps_status()查看。
由DHCP服務器提供的IP地址的默認范圍是192.168.4.1向上。第一個地址成為分配給ESP32本身。我們需要注意的是它的地址和我們工作的LAN范圍是不一樣。即他形成了自己的網絡地址空間,它們也許是一相同種類的網絡IP(192.168.XX)出現的。當我們連接到它時,我們可以在PC上PING到它。
當前的IP地址,子網掩碼和網關
當我們需要知道,當前環境中我們的ESP32中的IP地址,子網掩碼和網關時,我們已經知道這些值是由DHCP服務器設置的,我們可以調用tcpip_adapter_get_ip_info()得到這些值,因為,由於ESP32可以有兩個IP接口(一個用於接入點和一個用於站),我們需要通過參數使程序知道我們想要檢索的接口。
WiFi保護設置 - WPS(定義)
該ESP32支持在站模式下的WiFi保護設置,這意味着,如果接入點支持,ESP32可以連接到接入點不呈現出密碼。目前支持的只有“按鈕模式”實現。利用這種機制,一個物理按鈕被按下接入點,並且,對於一個周期的兩分鍾,在范圍內的任何站可以使用加入網絡WPS協議。官方給出了一個實際的應用例子是,當我們按下WPS的按鍵后,ESP32將調用wifi_wps_enable()和wifi_wps_start(),ESP32即可成功的連入計入端。
TCP服務器
到這里,WIFI的連接基本講解完成了,還有ESP32即做AP又做STAION的設置沒講(后面的Smartconfig會講到,就不做詳細講解了),下面即是ESP32連接后的通訊了,因為網絡通訊與一般的串口通訊不同,起需要特定的通訊協議來完成數據間的傳輸,首先,下一篇文章講解的是
TCP服務器
相關知識:wifi相關的API接口