ESP32 连接Wi-Fi

作者:追风剑情 发布于:2026-5-25 18:28 分类:物联网

#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"
#include "lwip/err.h"
#include "lwip/sys.h"

// 定义 Wi-Fi 凭证,请务必替换为你的实际网络信息
#define ESP_WIFI_SSID      "1706"
#define ESP_WIFI_PASS      "1234567890"
#define ESP_MAXIMUM_RETRY  5               // 最大重连次数

// 定义事件标志位
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT      BIT1

static const char *TAG = "wifi station";
static EventGroupHandle_t s_wifi_event_group;
static int s_retry_num = 0;
// 用于存储连接状态
static bool s_is_wifi_connected = false;

// 事件处理函数
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();
        ESP_LOGI(TAG, "正在尝试连接...");
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        s_is_wifi_connected = false;  // 断开时,将状态设为 false
        if (s_retry_num < ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "重连中,第 %d 次尝试...", s_retry_num);
        } else {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
            ESP_LOGI(TAG, "已达最大重试次数,连接失败");
        }
    } 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, "连接成功,获取到 IP:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
        s_is_wifi_connected = true;   // 成功获取 IP 时,将状态设为 true
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

void wifi_init_sta(void)
{
    // 1. 初始化 NVS 存储
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
        ESP_ERROR_CHECK(nvs_flash_erase());
        ret = nvs_flash_init();
    }
    ESP_ERROR_CHECK(ret);

    // 2. 创建事件循环
    ESP_ERROR_CHECK(esp_netif_init());
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    // 3. 创建默认的 Wi-Fi station 接口
    esp_netif_create_default_wifi_sta();

    // 4. 初始化 Wi-Fi 配置
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    // 5. 注册事件处理函数
    s_wifi_event_group = xEventGroupCreate();
    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));

    // 6. 配置 Wi-Fi 为 STA 模式并设置认证信息
    wifi_config_t wifi_config = {
        .sta = {
            .ssid = ESP_WIFI_SSID,
            .password = ESP_WIFI_PASS,
            .threshold.authmode = WIFI_AUTH_WPA2_PSK,  // 选择安全认证方式
            .sae_pwe_h2e = WPA3_SAE_PWE_BOTH,
            .sae_h2e_identifier = "",
        },
    };
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));
    ESP_ERROR_CHECK(esp_wifi_start());

    // 7. 等待连接结果事件
    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            portMAX_DELAY);

    // 8. 根据结果打印日志
    if (bits & WIFI_CONNECTED_BIT) {
        ESP_LOGI(TAG, "成功连接到 AP: %s", ESP_WIFI_SSID);
    } else if (bits & WIFI_FAIL_BIT) {
        ESP_LOGI(TAG, "连接失败");
    } else {
        ESP_LOGE(TAG, "Unexpected event");
    }

    // 9. 注销不需要的事件处理
    ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler));
    ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler));
    vEventGroupDelete(s_wifi_event_group);
}

/* 获取 Wi-Fi 连接状态的函数 */
bool wifi_connect_status(void) {
    return s_is_wifi_connected;
}

void app_main(void)
{
    // 初始化并连接 Wi-Fi
    wifi_init_sta();

    // 主循环
    while (1) {
        if (wifi_connect_status()) {
            // 网络已连接,可以执行需要网络的任务
            // 例如:读取传感器数据并发送
        } else {
            // 网络未连接,可以尝试其他操作或等待
            ESP_LOGI(TAG, "等待网络连接...");
        }
        vTaskDelay(1000 / portTICK_PERIOD_MS);
    }
}

11111.png

标签: IoT

Powered by emlog  蜀ICP备18021003号-1   sitemap

川公网安备 51019002001593号