玩轉ESP32(2):WIFI的代碼實現

來源:互聯網
上載者:User
玩轉ESP32(2):WIFI的代碼實現

ESP32作為一款WIFI+藍芽晶片,WIFI的實現是其最基本的功能,而在ESP32中,利用WIFI可以實現STA、AP、STA+AP這三種方式。 STA代碼實現

首先來看一個最簡單的實現WIFI sta的例子。

#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"#define EXAMPLE_WIFI_SSID "HUAWEI001"#define EXAMPLE_WIFI_PASS "12345678"static const char *TAG = "espressif";/* FreeRTOS event group to signal when we are connected & ready to make a request */static EventGroupHandle_t wifi_event_group;/* The event group allows multiple bits for each event,   but we only care about one event - are we connected   to the AP with an IP? */const int CONNECTED_BIT = BIT0;static esp_err_t event_handler(void *ctx, system_event_t *event){    switch (event->event_id) {    case SYSTEM_EVENT_STA_START:        esp_wifi_connect();        break;    case SYSTEM_EVENT_STA_GOT_IP:        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);        break;    case SYSTEM_EVENT_STA_DISCONNECTED:        /* This is a workaround as ESP32 WiFi libs don't currently           auto-reassociate. */        esp_wifi_connect();        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);        break;    default:        break;    }    return ESP_OK;}static void initialise_wifi(void){    tcpip_adapter_init();    wifi_event_group = xEventGroupCreate();    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );    wifi_config_t wifi_config = {        .sta = {            .ssid = EXAMPLE_WIFI_SSID,            .password = EXAMPLE_WIFI_PASS,        },    };    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );    ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );    ESP_ERROR_CHECK( esp_wifi_start() );}void app_main(){    ESP_ERROR_CHECK(nvs_flash_init());    initialise_wifi();}

上述例子主要實現串連SSID為espressif的路由器,並獲得相應的IP。SSID和PASSWORD可以根據自己的路由資訊變更,在拿到IP之後我們就可以進行相應的網路操作(TCP/UDP)。
其中: STA代碼詳解

現在,開始對上面的代碼進行詳細分析。

#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"

上面是在實現WIFI sta所需要的標頭檔,其中前三個是freertos相關的標頭檔,後面幾個都是espressif所定義的標頭檔,其中esp_system.h是系統相關標頭檔;esp_wifi.h是WIFI相關標頭檔;esp_event_loop.h是事件相關標頭檔。esp_log.h是espressif格式化輸出的標頭檔。

#define EXAMPLE_WIFI_SSID "HUAWEI001"#define EXAMPLE_WIFI_PASS "12345678"static const char *TAG = "espressif";/* FreeRTOS event group to signal when we are connected & ready to make a request */static EventGroupHandle_t wifi_event_group;/* The event group allows multiple bits for each event,   but we only care about one event - are we connected   to the AP with an IP? */const int CONNECTED_BIT = BIT0;

上面是一些參數的定義,前面兩個為ssid和密碼,需要根據自己的路由器和密碼變更。第3個是格式化輸出的首碼,可以自由更改。wifi_event_group是我們定義的事件組,事件組主要是考慮到很多網路操作需要在我們串連到路由器並拿到IP之後才能進行。CONNECTED_BIT是我們定義的事件組Bit位,在此DEMO種只需要WIFI串連這一種事件。
*

Note.
事件組標誌位和WIFI的事件組並不是一個東西,事件組標誌位類似於原子操作,防止因為順序錯亂而導致程式問題。而WIFI事件組只是WIFI在串連過程中的某種狀態。

*

static esp_err_t event_handler(void *ctx, system_event_t *event){    switch (event->event_id) {    case SYSTEM_EVENT_STA_START:        esp_wifi_connect();        break;    case SYSTEM_EVENT_STA_GOT_IP:        xEventGroupSetBits(wifi_event_group, CONNECTED_BIT);        break;    case SYSTEM_EVENT_STA_DISCONNECTED:        /* This is a workaround as ESP32 WiFi libs don't currently           auto-reassociate. */        esp_wifi_connect();        xEventGroupClearBits(wifi_event_group, CONNECTED_BIT);        break;    default:        break;    }    return ESP_OK;}

WIFI在esp32中的串連是通過幾組不同的事件處理來實現的,上述代碼就是在作為STA串連WIFI中需要進行處理的事件。其中SYSTEM_EVENT_STA_START為初始事件狀態,在此事情狀態中,調用esp_wifi_connect()操作會串連到路由器(AP)上,串連成功後,事件狀態位會變為SYSTEM_EVENT_STA_CONNECTED,此時會調用DHCP進行請求IP,在拿到IP之後事件狀態會變更為SYSTEM_EVENT_STA_GOT_IP。在這裡我們使用了xEventGroupSetBits,設定事件組標誌,後續如果有需要在拿到IP後才進行的操作只需要調用xEventGroupWaitBits就可以避免在沒有拿到IP之前進行網路互動操作。
在WIFI因為某些原因斷開後,事件標誌位變為SYSTEM_EVENT_STA_DISCONNECTED,此時需要調用esp_wifi_connect()重新串連,並清除事件組標誌位。

static void initialise_wifi(void){    tcpip_adapter_init();    wifi_event_group = xEventGroupCreate();    ESP_ERROR_CHECK( esp_event_loop_init(event_handler, NULL) );    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );    wifi_config_t wifi_config = {        .sta = {            .ssid = EXAMPLE_WIFI_SSID,            .password = EXAMPLE_WIFI_PASS,        },    };    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.sta.ssid);    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_STA) );    ESP_ERROR_CHECK( esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );    ESP_ERROR_CHECK( esp_wifi_start() );}

上述代碼是實現初始化WIFI的核心代碼,其中tcpip_adapter_init()用來初始化TCP/IP協議棧,xEventGroupCreate()用來建立事件組標誌。esp_event_loop_init(event_handler, NULL)用來初始化事件event_handler,回調event_handler即我們剛剛處理的各種WIFI事件。ESP_ERROR_CHECK用來檢查傳回值是否為ESP_OK。WIFI_INIT_CONFIG_DEFAULT()指定需要初始化底層的參數資訊,esp_wifi_init用上述資訊來初始化WIFI硬體。esp_wifi_set_storage設定串連的WIFI資訊(SSID和PASSWORD)儲存在哪裡,可選的有RAM和FLASH。wifi_config是WIFI串連時的配置資訊,作為STA時只需要考慮sta的參數資訊,上述代碼只是制定了最基本的ssid和password資訊,除此之外,還可以指定bssid和channel等相關資訊。ESP_LOGI是espressif的格式化輸出資訊,其他還包括ESP_LOGE(錯誤資訊)、ESP_LOGD(調試資訊)。esp_wifi_set_mode設定WIFI模式,除了WIFI_MODE_STA以外還包括WIFI_MODE_AP,WIFI_MODE_APSTA。esp_wifi_set_config設定STA模式的配置資訊。esp_wifi_start()根據當前配置資訊開啟WIFI。

void app_main(){    ESP_ERROR_CHECK(nvs_flash_init());    initialise_wifi();}

void app_main()是espressif工程的入口,類似與C語言中的main,nvs_flash_init是初始化NVS儲存,initialise_wifi即初始化WIFI。在程式的後面,當需要實現其他功能時,使用vTaskCreate來建立即可。
至此,WIFI的整個串連過程結束,
AP實現

AP的實現與STA的實現很類似,只需要更改一些配置資訊即可。

#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"const static char *TAG = "espressif";static void initialise_wifi(void){    tcpip_adapter_init();    ESP_ERROR_CHECK( esp_event_loop_init(NULL, NULL) );    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();    ESP_ERROR_CHECK( esp_wifi_init(&cfg) );    ESP_ERROR_CHECK( esp_wifi_set_storage(WIFI_STORAGE_RAM) );    wifi_config_t wifi_config = {        .ap = {            .ssid = "TestAp",            .authmode = WIFI_AUTH_OPEN,            .max_connection = 3,        .channel = 12,        },    };    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.ap.ssid);    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_AP, &wifi_config) );    ESP_ERROR_CHECK( esp_wifi_start() );}void app_main(void){    ESP_ERROR_CHECK(nvs_flash_init());    initialise_wifi();}

在設定AP時,相對STA,大體相似,只有一小部分需要更改為AP資訊。

    ESP_ERROR_CHECK( esp_event_loop_init(NULL, NULL) );

在AP模式下,可以不需要回呼函數,當然也可以寫回調來擷取更多資訊,可以參考esp_event.h中的定義。

    wifi_config_t wifi_config = {        .ap = {            .ssid = "TestAp",            .authmode = WIFI_AUTH_OPEN,            .max_connection = 3,        .channel = 12,        },    };

在此DEMO中,我設定的SSID為TestAp,authmode是open,即不加密,如果設定成加密,還需要添加.password。max_connection為支援的最大串連數。channel即通道為12。其他參數可以參考esp_wifi_types.h中的wifi_ap_config_t定義。

    ESP_LOGI(TAG, "Setting WiFi configuration SSID %s...", wifi_config.ap.ssid);    ESP_ERROR_CHECK( esp_wifi_set_mode(WIFI_MODE_AP) );    ESP_ERROR_CHECK( esp_wifi_set_config(WIFI_IF_AP, &wifi_config) );

wifi_config.ap.ssid列印當前配置的AP的SSID資訊, esp_wifi_set_mode(WIFI_MODE_AP)設定為AP模式,esp_wifi_set_config(WIFI_IF_AP, &wifi_config)按照當前的配置資訊來設定AP。
運行之後,用手機串連測試SSID:TestAp,會出現如下介面:

AP模式也設定成功。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.