ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

简单实现WIFI链接

简单实现WIFI链接 WIFI功能介绍之前的课程我们大致学习了一些esp-idf方面的基础知识但WIFI才是ESP32S3的最强大功能使得我们通过简单代码就可以接入到物联网中。一般来说wifi有两种工作模式第一种STA模式这个是最常见最常用的模式大部分设备都工作于此模式STA模式下ESP32S3作为一个终端设备接入到一个无线接入点比如说路由器第二种是AP模式AP模式就是把ESP32S3作为一个无线接入点让其他设备连接进来还有一种是APSTA模式也就是两种模式同时工作注意ESP32S3只支持2.4G 频段的WIFIesp-idf的wifi代码功能针对ESP32S3的STA模式其代码比较简单初始化步骤如下图1是初始化底层包括一些协议栈以及STA2然后是创建事件循环系统和注册回调函数在WiFi的连接或工作过程中有很多不同的事件比如说连上了断连了或者启动成功等等这些都是事件我们创建的这个事件循环系统就是为了捕获各种这样的事件然后通过事件回调函数来通知我们。3接下来是配置STA参数比如WIFI的SSID和密码。4启动STA工作STA代码实现打开vscode新建一个项目项目名称是wifi新建项目的步骤参考第二章。然后我们们新建两个文件分别是wifi_manager.h和wifi_manager.c工程目录如下其中wifi_manager.c包含wifi的主要功能代码实现的头文件如下#ifndef _WIFI_MANAGER_H_ #define _WIFI_MANAGER_H_ #include esp_err.h #include esp_wifi.h typedef enum { WIFI_STATE_CONNECTED, WIFI_STATE_DISCONNECTED, }WIFI_STATE; //wifi状态变化回调函数 typedef void(*p_wifi_state_callback)(WIFI_STATE state); /** 初始化wifi默认进入STA模式 * param f wifi状态变化回调函数 * return 无 */ void wifi_manager_init(p_wifi_state_callback f); /** 发起wifi链接 * param ssid * param password * return 成功/失败 */ esp_err_t wifi_manager_connect(const char* ssid,const char* password); #endif代码解析功能很简单目前只有两个函数1wifi_manager_init这个是STA的初始化函数里面有一个参数是回调函数我们希望wifi成功连接或者断开连接的时候通过这个回调函数通知我们好让我们的其他应用做相应的动作这个回调函数有一个参数是一个枚举值分别是WIFI_STATE_CONNECTED连接成功以及WIFI_STATE_DISCONNECTED断连。2wifi_manager_connect是使用指定的ssid和密码进行连接。wifi_manager.c代码如下#include wifi_manager.h #include stdio.h #include esp_log.h #include string.h #include esp_netif.h #include esp_wifi.h #include esp_event.h #define TAG wifi_manager //重连次数 #define MAX_CONNECT_RETRY 6 static int sta_connect_count 0; //回调函数 static p_wifi_state_callback wifi_state_cb NULL; //当前sta连接状态 static bool is_sta_connected false; /** 事件回调函数 * 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模式启动后触发此事件 { wifi_mode_t mode; esp_wifi_get_mode(mode); if(mode WIFI_MODE_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从路由器断开连接后触发此事件 if(is_sta_connected) //这里增加这个判断是为了防止重复通知WIFI_STATE_DISCONNECTED这个事件 { if(wifi_state_cb) wifi_state_cb(WIFI_STATE_DISCONNECTED); is_sta_connected false; } if(sta_connect_count MAX_CONNECT_RETRY) { wifi_mode_t mode; esp_wifi_get_mode(mode); if(mode WIFI_MODE_STA) esp_wifi_connect(); //继续重连 sta_connect_count; } 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); is_sta_connected true; if(wifi_state_cb) wifi_state_cb(WIFI_STATE_CONNECTED); break; default:break; } } } /** 初始化wifi默认进入STA模式 * param 无 * return 无 */ void wifi_manager_init(p_wifi_state_callback f) { 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_state_cb f; //启动WIFI ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) ); //设置工作模式为STA ESP_ERROR_CHECK(esp_wifi_start() ); //启动WIFI ESP_LOGI(TAG, wifi_init finished.); } /** 连接wifi * param ssid * param password * return 成功/失败 */ esp_err_t wifi_manager_connect(const char* ssid,const char* password) { sta_connect_count 0; wifi_config_t wifi_config { .sta { .threshold.authmode WIFI_AUTH_WPA2_PSK, //加密方式 }, }; snprintf((char*)wifi_config.sta.ssid,31,%s,ssid); snprintf((char*)wifi_config.sta.password,63,%s,password); ESP_ERROR_CHECK(esp_wifi_disconnect()); wifi_mode_t mode; esp_wifi_get_mode(mode); if(mode ! WIFI_MODE_STA) { ESP_ERROR_CHECK(esp_wifi_stop()); ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA)); ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, wifi_config)); esp_wifi_start(); } else { ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, wifi_config)); esp_wifi_connect(); } return ESP_OK; }代码解析1、wifi_manager_init初始化函数里面完成了STA功能的初始化其顺序与上回介绍的WIIF代码框图流程一致具体每一行的代码作用可以看一下注释这里注意如果我们没有配置指定的SSID和密码则当调用esp_wifi_start这句函数之后esp-idf就会用上次成功连接的SSID和密码去发起连接上次连接成功的SSID和密码会自动的保存到NVS中掉电不失。2、wifi_manager_connect函数里面主要对wifi_config_t这个结构体里面的成员进行填充填充内容包括.sta.threshold.authmode //加密方式这里设置的加密方式是可接受的最低安全模式一般填 WIFI_AUTH_WPA2_PSK.sta.ssid //ssid.sta.password //密码esp_wifi_get_mode这句函数是获取当前的工作模式如果当前不是STA模式则需要停止WIFI工作调用esp_wifi_set_mode将模式设置到STA模式然后调用esp_wifi_set_config设置sta的配置后再启动wifi的工作。3、static void event_handler(void* arg, esp_event_base_t event_base,int32_t event_id, void* event_data)这个函数是WIFI相关的事件响应回调函数目前注册了两大类事件分别是WIFI事件和IP事件WIFI事件我们比较关注WIFI_EVENT_STA_START(STA模式启动)、WIFI_EVENT_STA_CONNECTED连上AP热点、WIFI_EVENT_STA_DISCONNECTED断开与AP的热点IP事件我们只关注一个获取到AP热点分配的IP地址这时候我们才认为是真正的连上了路由器这时候可以调用init的时候传进来的那个回调函数通知我们的应用了。if(event_base IP_EVENT) //IP相关事件 { switch(event_id) { case IP_EVENT_STA_GOT_IP: //只有获取到路由器分配的IP才认为是连上了路由器 ESP_LOGI(TAG,Get ip address); is_sta_connected true; if(wifi_state_cb) //调用回调函数通知主任务 wifi_state_cb(WIFI_STATE_CONNECTED); break; default:break; } }测试程序在main.c中我们输入如下代码进行测试#include stdio.h #include freertos/FreeRTOS.h #include freertos/task.h #include wifi_manager.h #include nvs_flash.h #include nvs.h #include esp_log.h #define TAG MAIN #define DEFAULT_WIFI_SSID testwifi #define DEFAULT_WIFI_PASSWORD 12345678 //WIFI状态通知回调函数 void wifi_state_handler(WIFI_STATE state) { if(state WIFI_STATE_CONNECTED) { ESP_LOGI(TAG,Wifi connect success!); } else { ESP_LOGI(TAG,Wifi disconnect! ); } } void app_main(void) { //NVS初始化WIFI底层驱动有用到NVS所以这里要初始化 nvs_flash_init(); //wifi STA工作模式初始化 wifi_manager_init(wifi_state_handler); //使用指定的SSID和密码进行连接 wifi_manager_connect(DEFAULT_WIFI_SSID,DEFAULT_WIFI_PASSWORD); while(1) { vTaskDelay(pdMS_TO_TICKS(500)); } }我们的main里面代码很简单首先是要初始化nvs不然wifi工作会报错然后我们用指定的DEFAULT_WIFI_SSID和DEFAULT_WIFI_PASSWORD发起连接成功后会调用wifi_state_handler回调函数通知我们这里简单打印一句即可。最后不要忘记在main/CMakeLists.txt中加入wifi_manager.c不然编译会报错配套的参考例程esp32s3-board/wifi
返回列表