目录
一、ESP32的WiFi特点
二、ESP32的WIFI状态机总结
状态机解析
WiFi初始化API介绍
WiFi初始化编写
作为AP的回调函数解析
三、STA代码实现
四、遇到的问题和解决方法
五、总结
一、ESP32的WiFi特点
WiFi可以分为AP、STA、AP+STA三种工作模式模式,这期我们主要介绍AP模式。
作为AP时,理论上可以被4个STA连接。这里有人就回问了,什么是AP和STA
AP 是 (Wireless) AccessPoint 的缩写,即 (无线) 访问接入点。简单来讲就像是无线路由器一样,设备打开后进入 AP 模式,在手机的网络列表里面,可以搜索到类似 TPLINK_XXX 的名字(SSID)
STA是每一个连接到无线网络中的终端(如笔记本电脑、手机、PAD及其它可以联网的用户设备)都可称为一个站点,STA本身并不接受无线的接入,可以连接到AP。
二、ESP32的WIFI状态机总结
初始化wifi配置后,程序会根据WIFI的实时状态,在回调函数中给出状态返回,所以只需要在回调中进行相关操作,但是其中的状态解析很重要。
状态机解析
回调原型 | static esp_err_t event_handler ( void *ctx, system_event_t *event ) |
函数功能 | WIFI状态机回调函数 |
参数 | [in] event: typedef struct { system_event_id_t event_id; /*事件ID*/ system_event_info_t event_info; /*事件信息*/ } system_event_t; //事件ID取值 typedef enum { SYSTEM_EVENT_WIFI_READY = 0, /*WiFi准备好*/ SYSTEM_EVENT_SCAN_DONE, /*扫描AP完成*/ SYSTEM_EVENT_STA_START, /*作为STA开始工作*/ SYSTEM_EVENT_STA_STOP, /*作为STA结束工作*/ SYSTEM_EVENT_STA_CONNECTED, /*作为STA连接上AP*/ SYSTEM_EVENT_STA_DISCONNECTED, /*作为STA断开AP*/ SYSTEM_EVENT_STA_AUTHMODE_CHANGE, /*作为STA连接的AP改变了*/ SYSTEM_EVENT_STA_GOT_IP, /*作为STA从AP获取了IP*/ SYSTEM_EVENT_STA_LOST_IP, /*作为STA丢掉了IP,也就是错了*/ SYSTEM_EVENT_STA_WPS_ER_SUCCESS, /*wps succeeds in enrollee mode */ SYSTEM_EVENT_STA_WPS_ER_FAILED, /* wps fails in enrollee mode */ SYSTEM_EVENT_STA_WPS_ER_TIMEOUT, /* wps timeout in enrollee mode */ SYSTEM_EVENT_STA_WPS_ER_PIN, /*wps pin code in enrollee mode */ SYSTEM_EVENT_AP_START, /*AP开始*/ SYSTEM_EVENT_AP_STOP, /*AP结束*/ SYSTEM_EVENT_AP_STACONNECTED, /*有STA连上SP32的AP*/ SYSTEM_EVENT_AP_STADISCONNECTED, /*有STA断开ESP32的AP*/ SYSTEM_EVENT_AP_PROBEREQRECVED, /*从AP中接收包*/ SYSTEM_EVENT_GOT_IP6, /*获取IPv6*/ SYSTEM_EVENT_ETH_START, /*有线开始*/ SYSTEM_EVENT_ETH_STOP, /*有线停止*/ SYSTEM_EVENT_ETH_CONNECTED, /*有线上线*/ SYSTEM_EVENT_ETH_DISCONNECTED, /*有线掉线*/ SYSTEM_EVENT_ETH_GOT_IP, /*有线获取了IP*/ SYSTEM_EVENT_MAX } system_event_id_t;
|
返回值 | ESP_OK:成功 ESP_ERR_INVALID_ARG : 参数错误 |
WiFi初始化API介绍
设置WiFi回调函数esp_event_loop_init();
回调原型 | esp_err_t esp_event_loop_init (
) |
函数功能 | 设置WiFi回调函数 |
参数 | [in] cb:回调函数指针 [in] ctx:保留 |
返回值 | ESP_OK:成功 other: 失败 |
初始化WiFi设置函数WIFI_INIT_CONFIG_DEFAULT();
设置WiFi工作模式函数esp_err_t esp_wifi_set_mode();
回调原型 | esp_err_t esp_wifi_set_mode ( wifi_mode_t mode ) |
函数功能 | 设置WiFi工作模式函数 |
参数 | [in] mode:wifi工作模式
|
返回值 | ESP_OK:成功 other: 失败 |
启动WiFi函数:esp_err_t esp_wifi_start(void);
更多更详细接口请参考官方指南。
WiFi初始化编写
void app_main()
{
ESP_ERROR_CHECK( nvs_flash_init() );
tcpip_adapter_init();
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));
wifi_config_t wifi_config = {
.ap = {
.ssid = "Helon_test",
.ssid_len = 0,
/* 最多只能被4个station同时连接,这里设置为只能被一个station连接 */
.max_connection = 1,
.password = "20180604",
.authmode = WIFI_AUTH_WPA_WPA2_PSK,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_AP));
ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_AP, &wifi_config));
ESP_ERROR_CHECK(esp_wifi_start());
}
作为AP的回调函数解析
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
switch (event->event_id)
{
case SYSTEM_EVENT_AP_START:
printf("\nwifi_softap_start\n");
break;
case SYSTEM_EVENT_AP_STACONNECTED:
printf("\nwifi_softap_connectted\n");
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
printf("\nwifi_softap_disconnectted\n");
break;
default:
break;
}
return ESP_OK;
}
三、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 "guanzhengfei"
#define EXAMPLE_WIFI_PASS "668668"
static const char *TAG = "espressif";
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:
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();
}
#define EXAMPLE_WIFI_SSID "guanzhengfei"
#define EXAMPLE_WIFI_PASS "668668"
这一步设置自己家里的WIFI名称密码。
四、遇到的问题和解决方法
发现esp32时钟连接不上wifi
主体代码如下:
while(WiFi.status()!=WL_CONNECTED){
delay(300);
Serial.println("正在连接至wifi...");
WiFi.begin(id,psw);
}
Serial.println("已连接.");
检查过wifi账号密码,语句逻辑无误之后
最后发现是
delay(300);
这个延时函数的问题,延时太短了
问题原因猜想:
我猜测
(1)esp32是多线程运行的(存疑)
(2)在上一个wifi.begin()未执行完时,
程序就进入了下一个循环
然后又调用了wifi.begin()
留给连接wifi的时间太短,导致一直连接不上。
解决办法:
延时函数写大
delay(3000);
结果
五、总结
连接到Wi-Fi网络的设备称为站点(STA)。而接入点(AP)提供与Wi-Fi的连接,该接入点可以充当一个或多个站点的连接坞,接入点的另一端一般会连接到有线网络。接入点通常与路由器集成在一起,以提供从Wi-Fi网络到互联网的访问。AP会通过SSID(Service Set IDentifier) 来识别接入的STA设备该名称实际上是将设备(站点)连接到Wi-Fi时选择的网络名称。
ESP32模组可以既作为station(STA)运作,因此我们可以将它连接到Wi-Fi网络。它还可以用作软接入点(AP),以建立自己的Wi-Fi网络。当ESP32模块用作软接入点时,我们可以将其他站连接到ESP模块。