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

发布于:2025-07-13 ⋅ 阅读:(18) ⋅ 点赞:(0)

包含:

  • 自定义 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);
    }


网站公告

今日签到

点亮在社区的每一天
去签到