ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

针对esp32-c5写一个示例程序,此程序主要是扫描2.4G+5.8Gwifi,然后链接,可能通过自定义的at指令

2026/8/16 0:30:29 拓冰建站 浏览量
针对esp32-c5写一个示例程序,此程序主要是扫描2.4G+5.8Gwifi,然后链接,可能通过自定义的at指令

包含:

  • 自定义 AT 命令 (AT+SCAN=2G, AT+SCAN=5G, AT+CONN=ssid,pwd,2G/5G)

  • 2.4 GHz 与 5 GHz 扫描逻辑,并按频段过滤并打印结果

  • STA 模式初始化、事件回调处理

  • 连接指定 SSID/密码 的示例

  • 详细的中文注释,帮助理解每个模块的设计与实现

  • #include <string.h>
    #include <stdlib.h>
    #include "freertos/FreeRTOS.h"
    #include "freertos/event_groups.h"
    #include "freertos/task.h"
    #include "esp_wifi.h"
    #include "esp_event.h"
    #include "esp_log.h"
    #include "nvs_flash.h"

    // 本示例针对 ESP32-C5 模组
    // 功能:
    // 1. 通过自定义 AT 指令扫描 2.4GHz 或 5GHz Wi-Fi(AT+SCAN=2G 或 AT+SCAN=5G)
    // 2. 通过自定义 AT 指令连接指定频段的 Wi-Fi(AT+CONN=<SSID>,<PWD>,2G/5G)

    static const char *TAG = "esp32c5_wifi";

    // 事件组标志
    #define WIFI_SCAN_DONE_BIT    BIT0

    static EventGroupHandle_t wifi_event_group;

    // AT 命令行缓冲区
    #define AT_CMD_MAX_LEN 128
    static char at_cmd[AT_CMD_MAX_LEN];

    //--------------------------------------------------
    // 1. Wi-Fi 事件处理回调
    static void wifi_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:
    ESP_LOGI(TAG, "Wi-Fi STA started");
    break;
    case WIFI_EVENT_SCAN_DONE: {
    ESP_LOGI(TAG, "Wi-Fi scan completed");
    xEventGroupSetBits(wifi_event_group, WIFI_SCAN_DONE_BIT);
    break;
    }
    case WIFI_EVENT_STA_CONNECTED:
    ESP_LOGI(TAG, "Wi-Fi connected");
    break;
    case WIFI_EVENT_STA_DISCONNECTED:
    ESP_LOGI(TAG, "Wi-Fi disconnected");
    break;
    default:
    break;
    }
    } 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));
    }
    }

    //--------------------------------------------------
    // 2. 初始化 Wi-Fi STA 模式
    static void wifi_init(void)
    {
    // 初始化 NVS(Wi-Fi 驱动依赖)
    esp_err_t ret = nvs_flash_init();
    if (ret == ESP_ERR_NVS_NO_FREE_PAGES || ret == ESP_ERR_NVS_NEW_VERSION_FOUND) {
    nvs_flash_erase();
    nvs_flash_init();
    }

        // 创建事件组
    wifi_event_group = xEventGroupCreate();

        // 初始化 TCP/IP 网络接口
    esp_netif_init();
    esp_event_loop_create_default();

        // 创建默认 Wi-Fi STA 接口
    esp_netif_create_default_wifi_sta();

        // Wi-Fi 驱动配置
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    esp_wifi_init(&cfg);

        // 注册事件处理
    esp_event_handler_instance_t instance_any_id;
    esp_event_handler_instance_t instance_got_ip;
    esp_event_handler_instance_register(WIFI_EVENT,
    ESP_EVENT_ANY_ID,
    &wifi_event_handler,
    NULL,
    &instance_any_id);
    esp_event_handler_instance_register(IP_EVENT,
    IP_EVENT_STA_GOT_IP,
    &wifi_event_handler,
    NULL,
    &instance_got_ip);

        // 设置为 STA
    esp_wifi_set_mode(WIFI_MODE_STA);
    esp_wifi_start();
    }

    //--------------------------------------------------
    // 3. 扫描并根据频段打印 AP 列表
    static void wifi_scan_band(int band)
    {
    // band = 2 -> 2.4GHz, band = 5 -> 5GHz
    ESP_LOGI(TAG, "Starting %dGHz scan...", band);

        wifi_scan_config_t scan_cfg = {
    .ssid = NULL,
    .bssid = NULL,
    .channel = 0,          // 0 表示扫描所有信道
    .show_hidden = true
    };
    esp_wifi_scan_start(&scan_cfg, false);

        // 等待扫描完成
    xEventGroupWaitBits(wifi_event_group,
    WIFI_SCAN_DONE_BIT,
    pdTRUE,
    pdFALSE,
    portMAX_DELAY);

        // 获取扫描结果数量
    uint16_t ap_num = 0;
    esp_wifi_scan_get_ap_num(&ap_num);
    wifi_ap_record_t *ap_records = calloc(ap_num, sizeof(wifi_ap_record_t));
    esp_wifi_scan_get_ap_records(&ap_num, ap_records);

        // 遍历并过滤频段
    for (int i = 0; i < ap_num; i++) {
    int ch = ap_records[i].primary;
    bool is2g = (ch >= 1 && ch <= 14);
    if ((band == 2 && is2g) || (band == 5 && !is2g)) {
    printf("SSID: %s, RSSI: %d dBm, Channel: %d\n",
    (char *)ap_records[i].ssid,
    ap_records[i].rssi,
    ap_records[i].primary);
    }
    }
    free(ap_records);
    }

    //--------------------------------------------------
    // 4. 连接指定 SSID
    static void wifi_connect_ap(const char *ssid, const char *pwd)
    {
    wifi_config_t sta_cfg = { 0 };
    strncpy((char *)sta_cfg.sta.ssid, ssid, sizeof(sta_cfg.sta.ssid) - 1);
    strncpy((char *)sta_cfg.sta.password, pwd, sizeof(sta_cfg.sta.password) - 1);
    sta_cfg.sta.threshold.authmode = WIFI_AUTH_WPA2_PSK;

        esp_wifi_set_config(WIFI_IF_STA, &sta_cfg);
    esp_wifi_connect();
    }

    //--------------------------------------------------
    // 5. 简单 AT 命令行解析任务
    static void at_task(void *arg)
    {
    while (1) {
    printf("\nEnter AT Command (e.g. AT+SCAN=2G / AT+SCAN=5G / AT+CONN=ssid,pwd,2G): ");
    fflush(stdout);
    if (fgets(at_cmd, AT_CMD_MAX_LEN, stdin) == NULL) {
    vTaskDelay(pdMS_TO_TICKS(100));
    continue;
    }
    // 去除换行符
    at_cmd[strcspn(at_cmd, "\r\n")] = 0;

            if (strncmp(at_cmd, "AT+SCAN=2G", 10) == 0) {
    wifi_scan_band(2);
    } else if (strncmp(at_cmd, "AT+SCAN=5G", 10) == 0) {
    wifi_scan_band(5);
    } else if (strncmp(at_cmd, "AT+CONN=", 8) == 0) {
    // 格式: AT+CONN=ssid,pwd,2G
    char *cmd = at_cmd + 8;
    char *ssid = strtok(cmd, ",");
    char *pwd  = strtok(NULL, ",");
    char *band = strtok(NULL, ",");
    if (ssid && pwd && band) {
    printf("Connecting to SSID '%s' on %s...\n", ssid, band);
    wifi_connect_ap(ssid, pwd);
    } else {
    printf("Invalid AT+CONN format. Use: AT+CONN=ssid,pwd,2G or 5G\n");
    }
    } else {
    printf("Unknown command.\n");
    }
    }
    }

    //--------------------------------------------------
    void app_main(void)
    {
    // 1. 初始化 Wi-Fi
    wifi_init();

        // 2. 创建 AT 命令解析任务
    xTaskCreate(at_task, "at_task", 4096, NULL, 5, NULL);
    }