WiFi连接STA模式
一、ESP32的WiFi功能介绍
前面章节内容,基本上都是描述了ESP32强大的MCU能力,这些MCU能力使得ESP32可以替换许多类型的单片机工作,而自己承担这部分功能;当然ESP32的IOT能力才是它的主业,从硬件配置来看,ESP32支持2.4GHz频段WiFi+BT(LE)4.2,而esp-idf对WiFi的驱动支持可谓是十分完善,我们不需要花费太多的精力研究底层实现,更多的将精力放在自己的应用设计上。
对于ESP32的WIFI,有三种工作模式:
STA模式,这种模式是ESP32最常用的模式,ESP32可以连接到任何已经存在的WiFi网络,从而允许ESP32与网络上的其他设备进行通信,类似于一台普通的WiFi客户端设备。 AP模式,这种模式下ESP32创建自己的WiFi网络,成为一个小型WiFi路由器,接受其它WiFi终端设备连接,这种模式多用于设备配网。STA+AP模式,在这种模式下,ESP32 同时工作在STA和AP两种模式下,既可以连接到已有的WiFi网络,也可以提供WiFi热点,这种高级功能使ESP32能够连接到现有的WiFi网络,同时创建自己的网络,充当桥接器或中继器,通俗的讲就是连接到一个热点后,ESP32自己又创建了一个网络,允许其它设备接入,这些设备以ESP32为中继节点,可以访问互联网。二、STA模式代码
STA模式代码位于esp32-board/wifi,因为esp-idf的WiFi驱动已经十分的完善,所以我们不需要很多代码就能完成WiFi连接,看到esp32-board/wifi/main/simple_wifi_sta.c文件,
#define DEFAULT_WIFI_SSID "wifitest"#define DEFAULT_WIFI_PASSWORD "12345678"static const char *TAG = "wifi";/** 事件回调函数 * @param arg 用户传递的参数 * @param event_base 事件类别 * @param event_id 事件ID * @param event_data 事件携带的数据 * @return 无*/static void 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: //WIFI以STA模式启动后触发此事件 esp_wifi_connect(); //启动WIFI连接 break; case WIFI_EVENT_STA_CONNECTED: //WIFI连上路由器后,触发此事件 ESP_LOGI(TAG, "connected to AP"); break; case WIFI_EVENT_STA_DISCONNECTED: //WIFI从路由器断开连接后触发此事件 esp_wifi_connect(); //继续重连 ESP_LOGI(TAG,"connect to the AP fail,retry now"); break; default: break; } } if(event_base == IP_EVENT) //IP相关事件 { switch(event_id) { case IP_EVENT_STA_GOT_IP: //只有获取到路由器分配的IP,才认为是连上了路由器 ESP_LOGI(TAG,"get ip address"); break; } }}//WIFI STA初始化esp_err_t wifi_sta_init(void){ ESP_ERROR_CHECK(esp_netif_init()); //用于初始化tcpip协议栈 ESP_ERROR_CHECK(esp_event_loop_create_default()); //创建一个默认系统事件调度循环,之后可以注册回调函数来处理系统的一些事件 esp_netif_create_default_wifi_sta(); //使用默认配置创建STA对象 //初始化WIFI wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg)); //注册事件 ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT,ESP_EVENT_ANY_ID,&event_handler,NULL)); ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT,IP_EVENT_STA_GOT_IP,&event_handler,NULL)); //WIFI配置 wifi_config_t wifi_config = { .sta = { .ssid = DEFAULT_WIFI_SSID, //WIFI的SSID .password = DEFAULT_WIFI_PASSWORD, //WIFI密码 .threshold.authmode = WIFI_AUTH_WPA2_PSK, //加密方式 .pmf_cfg = { .capable = true, .required = false }, }, }; //启动WIFI ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); //设置工作模式为STA ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config) ); //设置wifi配置 ESP_ERROR_CHECK(esp_wifi_start() ); //启动WIFI ESP_LOGI(TAG, "wifi_init_sta finished."); return ESP_OK;}此文件只有两个函数,一个是WiFi连接事件回调函数,一个是初始化函数,先解析初始化内容。ESP_ERROR_CHECK(esp_netif_init()); //用于初始化tcpip协议栈 ESP_ERROR_CHECK(esp_event_loop_create_default()); //创建一个默认系统事件调度循环,之后可以注册回调函数来处理系统的一些事件 esp_netif_create_default_wifi_sta(); //使用默认配置创建STA对象 //初始化WIFI wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT(); ESP_ERROR_CHECK(esp_wifi_init(&cfg));
上述这部分是标准的WiFi底层初始化代码,包含网卡初始化、创建事件循环系统、STA默认配置、WIFI默认配置,这部分代码不用去动它,这些代码涉及到底层的初始化,感兴趣的同学可以看看WIFI_INIT_CONFIG_DEFAULT()这个默认配置到底配置了什么。
然后调用esp_event_handler_register函数,注册回调函数处理各种WIFI事件(WIFI_EVENT)的以及IP事件(IP_EVENT)。ESP_EVENT_ANY_ID参数表示任何的WIFI事件都执行回调函数,IP_EVENT_STA_GOT_IP表示获取到IP地址才会执行回调函数。
wifi_config_t wifi_config定义了WiFi连接配置,这个配置里面我们填入了要连接的SSID和密码,还有加密方式,目前大部分路由器都支持WPA2-PSK方式,pmf_cfg这个成员表示对WiFi保护管理帧的配置,.capable成员不推荐使用,设置为true即可,表示ESP32一直使用保护管理帧(pmf)方式连接,.required表示是否只与支持保护管理帧(pmf)的设备进行连接。如果大家不知道这里是什么意思,按我这里设定就行,esp-idf官方例程也是如此。
esp_wifi_set_mode(WIFI_MODE_STA)表示WiFi工作在STA模式
esp_wifi_set_config(WIFI_IF_STA, &wifi_config)表示将设置WiFi连接配置
esp_wifi_start()表示启动wifi
在启动WiFi后,WiFi驱动程序就会用配置的SSID和密码去尝试连接路由器,如果连接成功会触发WiFi事件WIFI_EVENT_STA_CONNECTED,我们在回调函数中可以将这个事件打印出来,但这个事件不代表可以连接网络,仅仅表示已经连接了AP热点,只有我们获取到了IP事件IP_EVENT_STA_GOT_IP,这个事件是路由器给ESP32分配了地址,到这才认为是已经连接到了网络,当然这个也是要求你的路由器能连接互联网。
主函数实现如下:
void app_main(void){ //NVS初始化(WIFI底层驱动有用到NVS,所以这里要初始化) nvs_flash_init(); //wifi STA工作模式初始化 wifi_sta_init(); while(1) { vTaskDelay(pdMS_TO_TICKS(500)); }}
由于WiFi底层驱动使用了nvs来一份默认可连接的SSID和密码,因此我们需要先初始化nvs。
最后附上相关资料:
ESP32教程资料链接:
https://pan.baidu.com/s/1kCjD8yktZECSGmHomx_veg?pwd=q8er
提取码:q8er
配套源码下载地址:
esp32-board: esp32开发板配套的经典例程
鉴于实验需要开发板的支持,我也设计了一款ESP32开发板,包含部分传感器模块,1.69寸LCD高亮屏,Type-C一键下载,方便大家学习和做各种实验。开发板链接如下:
https://item.taobao.com/item.htm?ft=t&id=802401650392&spm=a21dvs.23580594.0.0.4fee645eXpkfcp&skuId=5635015963649
请大家多多支持。