ESP32作為接入點AP


 作為接入點的第一個任務是使用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接口

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM