ESP32 Wi-Fi讲解,station连接热点案例
零. 聲明
本專欄文章我們會(huì)以連載的方式持續(xù)更新,本專欄計(jì)劃更新內(nèi)容如下:
第一篇:ESP-IDF基本介紹,主要會(huì)涉及模組,芯片,開發(fā)板的介紹,環(huán)境搭建,程序編譯下載,啟動(dòng)流程等一些基本的操作,讓你對(duì)ESP-IDF開發(fā)有一個(gè)總體的認(rèn)識(shí),比我們后續(xù)學(xué)習(xí)打下基礎(chǔ)!
第二篇:ESP32-IDF外設(shè)驅(qū)動(dòng)介紹,主要會(huì)根據(jù)esp-idf現(xiàn)有的driver,提供各個(gè)外設(shè)的驅(qū)動(dòng),比如LED,OLED,SPI LCD,TOUCH,紅外,Codec ic等等,在這一篇中,我們不僅僅來(lái)做外設(shè)驅(qū)動(dòng),還會(huì)對(duì)常用的外設(shè)總線做一個(gè)介紹,讓大家知其然又知其所以然!
第三篇:目前比較火熱的GUI LVGL介紹,主要會(huì)設(shè)計(jì)LVGL7.1,LVGL8的移植介紹,并且也會(huì)介紹各個(gè)組件,知道原理后,最后,我們會(huì)推出一款組態(tài)軟件來(lái)構(gòu)建我們的GUI,來(lái)提升我們的效率!
第四篇:ESP32-藍(lán)牙,熟悉我的,應(yīng)該都知道,我即使從事藍(lán)牙協(xié)議棧的開發(fā)的,所以這個(gè)是我們獨(dú)有的優(yōu)勢(shì),在這一篇章,我們會(huì)提供不僅僅是藍(lán)牙應(yīng)用方法的知識(shí),也會(huì)應(yīng)用結(jié)合藍(lán)牙底層協(xié)議棧的理論,讓你徹底從上到下打通藍(lán)牙任督二脈!
第五篇:Wi-Fi介紹,熟悉我的,應(yīng)該也知道,我們也做過(guò)一款sdio wifi的驅(qū)動(dòng)教程板子,所以在wifi這方面我們也是有獨(dú)有的優(yōu)勢(shì),在這一篇章,我們同樣不僅僅提供Wi-Fi應(yīng)用方面的知識(shí),也會(huì)結(jié)合底層理論,讓你對(duì)Wi-Fi有一個(gè)清晰的認(rèn)知!
第六篇:FreeRTOS介紹,主要介紹下FreeRTOS各個(gè)功能(任務(wù)管理/消息隊(duì)列/信號(hào)量/互斥量/事件/軟件定時(shí)器/任務(wù)通知/內(nèi)存管理/中斷管理等)的使用以及運(yùn)作機(jī)制。
第七篇:Arduino介紹,主要介紹ESP32 Arduino的基本操作(環(huán)境搭建,燒錄,下載等開發(fā)流程),以及介紹下基于Arduino的外設(shè),藍(lán)牙,wifi的使用。
第八篇:Demo,此篇章是融會(huì)貫通以上章節(jié),做一些綜合性的demo,讓你鞏固以上篇章的同時(shí),還能學(xué)到實(shí)際項(xiàng)目!!
另外,我們的教程包括但是不局限于以上篇章,為了給你一個(gè)更好的導(dǎo)航,以下信息尤其重要,請(qǐng)?jiān)敿?xì)查看!!
------------------------------------------------------------------------------------------------------------------------------------------
購(gòu)買開發(fā)板(點(diǎn)擊我)
文檔目錄(點(diǎn)擊我)
Github代碼倉(cāng)庫(kù)(點(diǎn)擊我)
藍(lán)牙交流扣扣群:539357317
微信公眾號(hào)↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓↓
------------------------------------------------------------------------------------------------------------------------------------------
一.Wi-Fi station的使用步驟
下圖為 station 模式下的宏觀場(chǎng)景,其中包含不同階段的具體描述:
1.Wi-Fi/LwIP 初始化階段
- s1.1:主任務(wù)通過(guò)調(diào)用函數(shù) esp_netif_init() 創(chuàng)建一個(gè) LwIP 核心任務(wù),并初始化 LwIP 相關(guān)工作。
- s1.2:主任務(wù)通過(guò)調(diào)用函數(shù) esp_event_loop_create() 創(chuàng)建一個(gè)系統(tǒng)事件任務(wù),并初始化應(yīng)用程序事件的回調(diào)函數(shù)。在此情況下,該回調(diào)函數(shù)唯一的動(dòng)作就是將事件中繼到應(yīng)用程序任務(wù)中。
- s1.3:主任務(wù)通過(guò)調(diào)用函數(shù) esp_netif_create_default_wifi_sta() 創(chuàng)建有 TCP/IP 堆棧的默認(rèn)網(wǎng)絡(luò)接口實(shí)例綁定 station 或 AP。
- s1.4:主任務(wù)通過(guò)調(diào)用函數(shù) esp_wifi_init() 創(chuàng)建 Wi-Fi 驅(qū)動(dòng)程序任務(wù),并初始化 Wi-Fi 驅(qū)動(dòng)程序。
- s1.5:主任務(wù)通過(guò)調(diào)用 OS API 創(chuàng)建應(yīng)用程序任務(wù)。
推薦按照 s1.1 ~ s1.5 的步驟順序針對(duì)基于 Wi-Fi/LwIP 的應(yīng)用程序進(jìn)行初始化。但這一順序 并非 強(qiáng)制,您可以在第 s1.1 步創(chuàng)建應(yīng)用程序任務(wù),然后在該應(yīng)用程序任務(wù)中進(jìn)行所有其它初始化操作。不過(guò),如果您的應(yīng)用程序任務(wù)依賴套接字,那么在初始化階段創(chuàng)建應(yīng)用程序任務(wù)可能并不適用。此時(shí),您可以在接收到 IP 后再進(jìn)行任務(wù)創(chuàng)建。
ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default()); esp_netif_create_default_wifi_sta();wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg));2.Wi-Fi配置階段
Wi-Fi 驅(qū)動(dòng)程序初始化成功后,可以進(jìn)入到配置階段。該場(chǎng)景下,Wi-Fi 驅(qū)動(dòng)程序處于 station 模式。因此,首先您需調(diào)用函數(shù) esp_wifi_set_mode() (WIFI_MODE_STA) 將 Wi-Fi 模式配置為 station 模式。可通過(guò)調(diào)用其它 esp_wifi_set_xxx API 進(jìn)行更多設(shè)置,例如:協(xié)議模式、國(guó)家代碼、帶寬等。請(qǐng)參閱 ESP32 Wi-Fi 配置。
一般情況下,我們會(huì)在建立 Wi-Fi 連接之前配置 Wi-Fi 驅(qū)動(dòng)程序,但這 并非 強(qiáng)制要求。也就是說(shuō),只要 Wi-Fi 驅(qū)動(dòng)程序已成功初始化,您可以在任意階段進(jìn)行配置。但是,如果您的 Wi-Fi 在建立連接后不需要更改配置,則應(yīng)先在此階段完成配置。因?yàn)檎{(diào)用配置 API(例如 esp_wifi_set_protocol())將會(huì)導(dǎo)致 Wi-Fi 連接斷開,為您的操作帶來(lái)不便。
如果 menuconfig 已使能 Wi-Fi NVS flash,則不論當(dāng)前階段還是后續(xù)的 Wi-Fi 配置信息都將被存儲(chǔ)至該 flash 中。那么,當(dāng)主板上電/重新啟動(dòng)時(shí),就不需從頭開始配置 Wi-Fi 驅(qū)動(dòng)程序。您只需調(diào)用函數(shù) esp_wifi_get_xxx API 獲取之前存儲(chǔ)的配置信息。當(dāng)然,如果不想使用之前的配置,您依然可以重新配置 Wi-Fi 驅(qū)動(dòng)程序。
#define EXAMPLE_ESP_WIFI_SSID "wireless link" #define EXAMPLE_ESP_WIFI_PASS "12345678" #define EXAMPLE_ESP_MAXIMUM_RETRY 5wifi_config_t wifi_config = {.sta = {.ssid = EXAMPLE_ESP_WIFI_SSID,.password = EXAMPLE_ESP_WIFI_PASS,/* Setting a password implies station will connect to all security modes including WEP/WPA.* However these modes are deprecated and not advisable to be used. Incase your Access point* doesn't support WPA2, these mode can be enabled by commenting below line */.threshold.authmode = WIFI_AUTH_WPA2_PSK,.pmf_cfg = {.capable = true,.required = false},},};ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );3.Wi-Fi啟動(dòng)階段
- s3.1:調(diào)用函數(shù) esp_wifi_start() 啟動(dòng) Wi-Fi 驅(qū)動(dòng)程序。
- s3.2:Wi-Fi 驅(qū)動(dòng)程序?qū)⑹录?WIFI_EVENT_STA_START 發(fā)布到事件任務(wù)中,然后,事件任務(wù)將執(zhí)行一些正常操作并調(diào)用應(yīng)用程序的事件回調(diào)函數(shù)。
- s3.3:應(yīng)用程序的事件回調(diào)函數(shù)將事件 WIFI_EVENT_STA_START 中繼到應(yīng)用程序任務(wù)中。推薦您此時(shí)調(diào)用函數(shù) esp_wifi_connect() 進(jìn)行 Wi-Fi 連接。當(dāng)然,您也可以等待在 WIFI_EVENT_STA_START 事件發(fā)生后的其它階段再調(diào)用此函數(shù)。
4.Wi-Fi 連接階段
- s4.1:調(diào)用函數(shù) esp_wifi_connect() 后,Wi-Fi 驅(qū)動(dòng)程序?qū)?dòng)內(nèi)部掃描/連接過(guò)程。
- s4.2:如果內(nèi)部掃描/連接過(guò)程成功,將產(chǎn)生 WIFI_EVENT_STA_CONNECTED 事件。然后,事件任務(wù)將啟動(dòng) DHCP 客戶端服務(wù),最終觸發(fā) DHCP 程序。
- s4.3:在此情況下,應(yīng)用程序的事件回調(diào)函數(shù)會(huì)將 WIFI_EVENT_STA_CONNECTED 事件中繼到應(yīng)用程序任務(wù)中。通常,應(yīng)用程序不需進(jìn)行操作,而您可以執(zhí)行任何動(dòng)作,例如:打印日志等。
步驟 s4.2 中 Wi-Fi 連接可能會(huì)由于某些原因而失敗,例如:密碼錯(cuò)誤、未找到 AP 等。這種情況下,將引發(fā) WIFI_EVENT_STA_DISCONNECTED 事件并提示連接錯(cuò)誤原因。
if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {esp_wifi_connect(); }5.Wi-Fi 獲取 IP 階段
- s5.1:一旦步驟 4.2 中的 DHCP 客戶端初始化完成,Wi-Fi 驅(qū)動(dòng)程序?qū)⑦M(jìn)入 獲取 IP 階段。
- s5.2:如果 Wi-Fi 成功從 DHCP 服務(wù)器接收到 IP 地址,則將引發(fā) IP_EVENT_STA_GOT_IP事件,事件任務(wù)將執(zhí)行正常處理。
- s5.3:應(yīng)用程序的事件回調(diào)函數(shù)將事件 IP_EVENT_STA_GOT_IP 中繼到應(yīng)用程序任務(wù)中。對(duì)于那些基于 LwIP 構(gòu)建的應(yīng)用程序,此事件較為特殊,因?yàn)樗馕吨鴳?yīng)用程序已準(zhǔn)備就緒,可以開始任務(wù),例如:創(chuàng)建 TCP/UDP 套接字等。此時(shí)較為容易犯的一個(gè)錯(cuò)誤就是在接收到 IP_EVENT_STA_GOT_IP 事件之前就初始化套接字。切忌在接收到 IP 之前啟動(dòng)任何套接字相關(guān)操作。
6.Wi-Fi 斷開階段
- s6.1:當(dāng) Wi-Fi 因?yàn)槟承┰?#xff08;例如:AP 掉電、RSSI 較弱等)連接中斷時(shí),將產(chǎn)生 WIFI_EVENT_STA_DISCONNECTED 事件。此事件也可能在上文階段 3 中發(fā)生。在這里,事件任務(wù)將通知 LwIP 任務(wù)清除/移除所有 UDP/TCP 連接。然后,所有應(yīng)用程序套接字都將處于錯(cuò)誤狀態(tài)。也就是說(shuō),WIFI_EVENT_STA_DISCONNECTED 事件發(fā)生時(shí),任何套接字都無(wú)法正常工作。
- s6.2:上述情況下,應(yīng)用程序的事件回調(diào)函數(shù)會(huì)將 WIFI_EVENT_STA_DISCONNECTED 事件中繼到應(yīng)用程序任務(wù)中。推薦您調(diào)用函數(shù) esp_wifi_connect() 重新連接 Wi-Fi,關(guān)閉所有套接字,并在必要時(shí)重新創(chuàng)建套接字。
7.Wi-Fi IP 更改階段
- s7.1:如果 IP 地址發(fā)生更改,將引發(fā) IP_EVENT_STA_GOT_IP 事件,其中 “ip_change” 被置為 “true”。
- s7.2:此事件對(duì)應(yīng)用程序至關(guān)重要。這一事件發(fā)生時(shí),適合關(guān)閉所有已創(chuàng)建的套接字并進(jìn)行重新創(chuàng)建。
8.Wi-Fi 清理階段
- s8.1:調(diào)用函數(shù) esp_wifi_disconnect() 斷開 Wi-Fi 連接。
- s8.2:調(diào)用函數(shù) esp_wifi_stop() 終止 Wi-Fi 驅(qū)動(dòng)程序。
- s8.3:調(diào)用函數(shù) esp_wifi_deinit() 清理 Wi-Fi 驅(qū)動(dòng)程序。
二.代碼
/* WiFi station ExampleThis example code is in the Public Domain (or CC0 licensed, at your option.)Unless required by applicable law or agreed to in writing, thissoftware is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES ORCONDITIONS OF ANY KIND, either express or implied. */ #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.h" #include "esp_log.h" #include "nvs_flash.h"#include "lwip/err.h" #include "lwip/sys.h"/* The examples use WiFi configuration that you can set via project configuration menuIf you'd rather not, just change the below entries to strings withthe config you want - ie #define EXAMPLE_WIFI_SSID "mywifissid" */ #define EXAMPLE_ESP_WIFI_SSID "wireless link" #define EXAMPLE_ESP_WIFI_PASS "12345678" #define EXAMPLE_ESP_MAXIMUM_RETRY 5/* FreeRTOS event group to signal when we are connected*/ static EventGroupHandle_t s_wifi_event_group;/* The event group allows multiple bits for each event, but we only care about two events:* - we are connected to the AP with an IP* - we failed to connect after the maximum amount of retries */ #define WIFI_CONNECTED_BIT BIT0 #define WIFI_FAIL_BIT BIT1static const char *TAG = "wifi station";static int s_retry_num = 0;static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data) {if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {esp_wifi_connect();} else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {esp_wifi_connect();s_retry_num++;ESP_LOGI(TAG, "retry to connect to the AP");} else {xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);}ESP_LOGI(TAG,"connect to the AP fail");} else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;ESP_LOGI(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));s_retry_num = 0;xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);} }void wifi_init_sta(void) {s_wifi_event_group = xEventGroupCreate();ESP_ERROR_CHECK(esp_netif_init());ESP_ERROR_CHECK(esp_event_loop_create_default());esp_netif_create_default_wifi_sta();wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();ESP_ERROR_CHECK(esp_wifi_init(&cfg));esp_event_handler_instance_t instance_any_id;esp_event_handler_instance_t instance_got_ip;ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&event_handler,NULL,&instance_any_id));ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT,IP_EVENT_STA_GOT_IP,&event_handler,NULL,&instance_got_ip));wifi_config_t wifi_config = {.sta = {.ssid = EXAMPLE_ESP_WIFI_SSID,.password = EXAMPLE_ESP_WIFI_PASS,/* Setting a password implies station will connect to all security modes including WEP/WPA.* However these modes are deprecated and not advisable to be used. Incase your Access point* doesn't support WPA2, these mode can be enabled by commenting below line */.threshold.authmode = WIFI_AUTH_WPA2_PSK,.pmf_cfg = {.capable = true,.required = false},},};ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) );ESP_ERROR_CHECK(esp_wifi_start() );ESP_LOGI(TAG, "wifi_init_sta finished.");/* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum* number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,pdFALSE,pdFALSE,portMAX_DELAY);/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually* happened. */if (bits & WIFI_CONNECTED_BIT) {ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);} else if (bits & WIFI_FAIL_BIT) {ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);} else {ESP_LOGE(TAG, "UNEXPECTED EVENT");}/* The event will not be processed after unregister */ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));vEventGroupDelete(s_wifi_event_group); }void app_main(void) {//Initialize NVSesp_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);ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");wifi_init_sta(); }整份代碼就是我們第一小節(jié)的內(nèi)容,所以大致自己看下就可以了
三.效果演示
log如下:
我們可以看到已經(jīng)連接成功,并且分配的IP地址是:192.168.61.27
此時(shí)我們看熱點(diǎn)的連接設(shè)備列表,可以看到有設(shè)備連接進(jìn)來(lái),如下圖:
此時(shí)我們用另外一臺(tái)STA,也就是我們的PC去ping一下esp32的板子,發(fā)現(xiàn)能ping通
PC(sta) <-------> AP熱點(diǎn) <-------> ESP32開發(fā)板
總結(jié)
以上是生活随笔為你收集整理的ESP32 Wi-Fi讲解,station连接热点案例的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 小兔子和大兔子
- 下一篇: navicat新建数据库