1. 设定STA模式,连接到AP
处于STA模式下的ESP32-C3,可以作为STA连接到AP,在此模式下设备可以通过AP分配的IP地址直接访问外网和内网。可以通过menuconfig->Example_Configuration中配置Wi-Fi的SSID以及Password。
2. 如何使用ESP-IDF的组件控制设备连接到路由器
使用ESP-IDF的组件控制设备连接到路由器的流程如图所示。
(1)初始化阶段:
- 初始化LwIP。创建LwIP核心任务并初始化与LwIP相关的工作。
ESP_ERROR_CHECK(esp_netif_init());
- 初始化事件。Wi-Fi事件处理基于esp-event组件,Wi-Fi驱动程序会将事件发送到默认事件循环。应用程序可以在esp_event_handler_register()中的回调函数中处理这些事件。esp_netif组件还会处理Wi-Fi事件,以提供一组默认行为。 例如,当ESP32-C3连接到AP时,esp_netif将自动启动DHCP客户端(默认情况下)。初始化事件的代码如下:
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
//...
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));
- 初始化Wi-Fi。创建Wi-Fi驱动程序任务,并初始化Wi-Fi驱动程序。 初始化Wi-Fi的代码如下:
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
(2)配置阶段
Wi-Fi驱动程序初始化成功后,进入配置阶段。在该阶段中,Wi-Fi驱动程序处于STA模式,调用esp_wifi_set_mode(WIFI_MODE_STA)函数将ESP32-C3模式配置为STA模式。
wifi_config_t wifi_config = {
.sta = {
.ssid = EXAMPLE_ESP_WIFI_SSID,
.password = EXAMPLE_ESP_WIFI_PASS,
},
};
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
(3)启动阶段
调用esp_wifi_start()函数启动Wi-Fi驱动程序,Wi-FI驱动程序将WIFI_EVENT_STA_START发布到事件任务,事件任务将执行一些常规操作,并将调用应用程序事件回调函数。应用程序事件回调函数将WIFI_EVENT_STA_START中继到应用程序任务,此时调用函数esp_wifi_connect()。
ESP_ERROR_CHECK(esp_wifi_start());
(4)连接阶段
一旦esp_wifi_connect()函数被调用,Wi-Fi驱动程序将开始内部扫描/连接过程。如果内部扫描/连接过程成功,则生成WIFI_EVENT_STA_CONNECTED。在事件任务中,将启动DHCP客户端,该客户端最终将触发DHCP进程。(底层实现)
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);
}
}
(5)获取IP阶段
初始化DHCP客户端后,将进入获取IP地址阶段,如果从DHCP服务器成功接收到IP地址,则将触发IP_EVENT_STA_GOT_IP事件,并在事件任务中进行常规处理。在应用程序事件回调函数中,IP_EVENT_STA_GOT_IP被传递到应用程序任务。对于基于LwIP的应用程序已准备就绪,可以开始其他任务。但在接收IP之前,请勿进行与套接字相关的工作。
(6)断开阶段
由于主动断开连接、密码错误、找不到AP等原因,Wi-FI连接可能会失败。在这种情况下,会触发WIFI_EVENT_STA_DISCONNECTED事件并提供失败的原因,如调用esp_wifi_disconnect()函数以主动断开连接。
ESP_ERROR_CHECK(esp_wifi_disconnect());
(7)IP更改阶段
如果IP地址发生变化,将触发IP_EVENT_STA_GOT_IP事件,在该事件中将ip_change设置为true。
(8)清理阶段
包括断开Wi-Fi连接、终止Wi-Fi驱动程序、清理Wi-Fi驱动程序等。
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));
ESP_ERROR_CHECK(esp_wifi_stop());
ESP_ERROR_CHECK(esp_wifi_deinit());
ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(station_netif));
esp_netif_destroy(station_netif);