ESP-C3入门8. 连接WiFi并打印信息
Posted 编程圈子
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ESP-C3入门8. 连接WiFi并打印信息相关的知识,希望对你有一定的参考价值。
ESP-C3入门8. 连接WiFi并打印信息
本文示例代码主要来自官方开源仓库:
https://gitee.com/EspressifSystems/book-esp32c3-iot-projects
一、ESP32 连接WiFi的基本操作流程
1. 初始化nvs存储
nvs_flash_init();
tcpip_adapter_init();
2. 配置WiFi工作模式
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
esp_wifi_init(&wifi_init_config);
esp_wifi_set_storage(WIFI_STORAGE_RAM);
esp_wifi_set_mode(WIFI_MODE_STA);
3. 设置WiFi登陆信息
wifi_config_t wifi_config =
.sta =
.ssid = "your_SSID",
.password = "your_password",
,
;
esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config);
4. 启动WiFi
esp_wifi_start();
5. 开启连接
esp_wifi_connect();
6. 判断是否成功
wifi_ap_record_t ap_info;
esp_wifi_sta_get_ap_info(&ap_info);
if (ap_info.authmode != WIFI_AUTH_OPEN)
// 连接成功
else
// 连接失败
二、事件处理函数
在 ESP-IDF 中,一些关键的系统任务(比如,Wi-Fi连接、网络传输等)通常都是在事件驱动的模式下实现的,
系统会生成一些事件,然后由事件处理机制来进行处理。事件处理机制是用于接收并处理系统事件的主要机制,通过它,可以实现自定义的动作(比如,记录日志、进行状态更新等)。
在ESP-IDF中使用事件处理函数有以下步骤:
1. 定义事件处理函数
定义一个函数,用于处理特定的事件,如:
void event_handler(void* arg, esp_event_base_t event_base, int32_t event_id, void* event_data)
// your code here
2. 创建事件组
使用 xEventGroupCreate 函数创建事件组。
3. 在事件处理函数中设置事件组位
在事件处理函数内部,使用 xEventGroupSetBits 函数设置事件组位,以标识事件已经发生。
4. 在其他任务中等待事件组位
使用 xEventGroupWaitBits 函数在其他任务中等待事件组位,以确认事件已经发生。
5. 注册事件处理函数
使用函数(如 esp_event_loop_init)注册事件处理函数,使其生效。
esp_event_handler_register(event_base, event_id, event_handler, arg);
其中:
- event_base 是事件的基础,通常是一个枚举,它表示事件类别,比如 WIFI_EVENT。
- event_id 是事件的 ID,通常也是一个枚举,它表示事件类型,比如 WIFI_EVENT_STA_DISCONNECTED。
- event_handler 是事件处理函数,用来处理事件,从中读取事件数据。
- arg 是一个用户指定的参数,在事件处理函数中可以读取。
6. 如果有必要取消注册
esp_event_handler_unregister(event_base, event_id, event_handler);
三、事件组的使用
ESP-IDF中的事件组是一种线程间同步机制,允许多个任务同时等待特定的事件发生。
在ESP-IDF中使用事件组的步骤是:
1. 创建事件组
EventGroupHandle_t s_event_group = xEventGroupCreate();
2. 向事件组中设置事件
xEventGroupSetBits(s_event_group, BIT0);
3. 在其它任务中等待事件
EventBits_t bits = xEventGroupWaitBits(s_event_group, BIT0, pdFALSE, pdFALSE, portMAX_DELAY);
四、实现过程
1. WiFi初始化函数做以下事情
- 创建一个事件组,用来管理Wi-Fi连接事件。
- 实始化协议栈
- 创建默认事件循环
- WiFi设置为sta模式
- 注册事件处理器
static void wifi_initialize(void)
// 创建一个事件组,用于管理Wi-Fi连接事件。
s_wifi_event_group = xEventGroupCreate();
// 初始化 TCP/IP 协议栈。
ESP_ERROR_CHECK(esp_netif_init());
// 创建默认事件循环。
ESP_ERROR_CHECK(esp_event_loop_create_default());
// 创建默认的Wi-Fi网络接口。
esp_netif_create_default_wifi_sta();
// 设置 Wi-Fi 初始化配置为默认配置
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// 注册事件处理器,以处理 Wi-Fi 和 IP 相关事件
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));
其中事件组的定义是:
static EventGroupHandle_t s_wifi_event_group = NULL;
2. WiFi Station模式初始化
- 配置WiFi信息
- WiFi工作模式设置为STA
- 启动WiFi
- 等待事件
static void wifi_station_initialize(void)
// 配置WiFi的配置信息
wifi_config_t wifi_config =
.sta =
.ssid = LIGHT_ESP_WIFI_SSID,
.password = LIGHT_ESP_WIFI_PASS,
// 启用WPA2模式,常用的WiFi连接方式
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg =
.capable = true,
.required = false
,
,
;
// WiFi工作模式设置为STA
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
// 设置WiFi工作模式
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
// 启动WiFi
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_station_initialize finished.");
// 下面的代码不是必须的,但它演示了程序如何阻塞并等待连接成功
/* 等待连接建立(WIFI_CONNECTED_BIT)或连接失败的次数达到最大值(WIFI_FAIL_BIT)。
* 这些位通过 event_handler() 设置(详见上面)*/
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
/* xEventGroupWaitBits() 返回调用前的 bits,因此我们可以测试实际发生了什么事件。 */
if (bits & WIFI_CONNECTED_BIT)
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS);
else if (bits & WIFI_FAIL_BIT)
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS);
else
ESP_LOGE(TAG, "UNEXPECTED EVENT");
xEventGroupWaitBits 函数在这里不是必须的。 它是一个阻塞函数,将等待一个或多个事件位被设置,直到返回时间结束。
本示例中,它等待 WIFI_CONNECTED_BIT 或 WIFI_FAIL_BIT 中的任何一个事件位被设置,并且等待的最长时间是 portMAX_DELAY。
相关参数:
- s_wifi_event_group 是事件组变量,用于存储事件位。
- WIFI_CONNECTED_BIT | WIFI_FAIL_BIT 是要等待的事件位。WIFI_CONNECTED_BIT 表示 Wi-Fi 连接成功的事件,WIFI_FAIL_BIT 表示 Wi-Fi 连接失败的事件。
- pdFALSE 和 pdTRUE 是宏,分别表示布尔值的 false 和 true,此处代表不需要等待所有事件位(pdFALSE)和不清除事件位(pdFALSE)。
- portMAX_DELAY 是一个常量,表示无限等待。
- 返回值(EventBits_t bits)是一个事件位变量,表示返回的事件位。
该代码实现了在等待 Wi-Fi 连接结果的同时不占用 CPU 资源,并在连接成功或失败时记录事件位以作后续处理。
事件组允许每个事件有多个位,前面要定义:
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
这里的BIT0 BIT1由开发者自行定义。
3. 事件回调
// 事件回调
static void event_handler(void *arg, esp_event_base_t event_base,
int32_t event_id, void *event_data)
// 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_START
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)
// 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_DISCONNECTED
/* 如果重试次数小于最大重试次数 */
if (s_retry_num < LIGHT_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事件,并且事件ID是IP事件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));
// 将重试次数重置为 0;
s_retry_num = 0;
// 通过调用 xEventGroupSetBits 函数,将 WIFI_CONNECTED_BIT 设置到事件组中,表示成功连接到 AP
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
五、完整代码
#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"
#define LIGHT_ESP_WIFI_SSID "你的WIFI账号"
#define LIGHT_ESP_WIFI_PASS "你的WiFi密码"
#define LIGHT_ESP_MAXIMUM_RETRY 5
// 事件组允许每个事件有多个位,这里只使用两个事件:
// 已经连接到AP并获得了IP
// 在最大重试次数后仍未连接
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1
static const char *TAG = "wifi connection";
// FreeRTOS事件组,连接成功时发出信号
static EventGroupHandle_t s_wifi_event_group = NULL;
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)
// 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_START
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)
// 如果是Wi-Fi事件,并且事件ID是Wi-Fi事件STA_DISCONNECTED
/* 如果重试次数小于最大重试次数 */
if (s_retry_num < LIGHT_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事件,并且事件ID是IP事件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));
// 将重试次数重置为 0;
s_retry_num = 0;
// 通过调用 xEventGroupSetBits 函数,将 WIFI_CONNECTED_BIT 设置到事件组中,表示成功连接到 AP
xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
static void wifi_initialize(void)
// 创建一个事件组,用于管理Wi-Fi连接事件。
s_wifi_event_group = xEventGroupCreate();
// 初始化 TCP/IP 协议栈。
ESP_ERROR_CHECK(esp_netif_init());
// 创建默认事件循环。
ESP_ERROR_CHECK(esp_event_loop_create_default());
// 创建默认的Wi-Fi网络接口。
esp_netif_create_default_wifi_sta();
// 设置 Wi-Fi 初始化配置为默认配置
wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&cfg));
// 注册事件处理器,以处理 Wi-Fi 和 IP 相关事件
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));
static void wifi_station_initialize(void)
// 配置WiFi的配置信息
wifi_config_t wifi_config =
.sta =
.ssid = LIGHT_ESP_WIFI_SSID,
.password = LIGHT_ESP_WIFI_PASS,
// 启用WPA2模式,常用的WiFi连接方式
.threshold.authmode = WIFI_AUTH_WPA2_PSK,
.pmf_cfg =
.capable = true,
.required = false
,
,
;
// WiFi工作模式设置为STA
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
// 设置WiFi工作模式
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
// 启动WiFi
ESP_ERROR_CHECK(esp_wifi_start());
ESP_LOGI(TAG, "wifi_station_initialize finished.");
/* 等待连接建立(WIFI_CONNECTED_BIT)或连接失败的次数达到最大值(WIFI_FAIL_BIT)。
* 这些位通过 event_handler() 设置(详见上面)*/
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, portMAX_DELAY);
/* xEventGroupWaitBits() 返回调用前的 bits,因此我们可以测试实际发生了什么事件。 */
if (bits & WIFI_CONNECTED_BIT)
ESP_LOGI(TAG, "connected to ap SSID:%s password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS);
else if (bits & WIFI_FAIL_BIT)
ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s", LIGHT_ESP_WIFI_SSID, LIGHT_ESP_WIFI_PASS);
else
ESP_LOGE(TAG, "UNEXPECTED EVENT");
void app_main()
int i = 0;
ESP_LOGE(TAG, "app_main");
// 初始化NVS存储区
ESP_ERROR_CHECK(nvs_flash_init());
// Wi-Fi初始化
ESP_LOGI(TAG, "Wi-Fi initialization");
wifi_initialize();
// Wi-Fi Station初始化
wifi_station_initialize();
while (1)
ESP_LOGI(TAG, "[%02d] Hello world!", i++);
vTaskDelay(pdMS_TO_TICKS(5000));
运行结果:
以上是关于ESP-C3入门8. 连接WiFi并打印信息的主要内容,如果未能解决你的问题,请参考以下文章