现在一个测试环境中,有多个ssid名字一样,请帮我写一个算法,要esp32-c3连接信号强度最强的ssid,用esp-idf,针对esp32-c3

下面给出一份基于 ESP32‑C3 + ESP‑IDF 的示例代码,演示如何在存在多个同名 SSID 的环境中,选取信号最强的那个 AP(通过 BSSID 做唯一标识)并连接。

思路:

  1. 发起一次扫描,扫描所有信道;

  2. 在扫描结果中筛选出与目标 SSID 名称相同的条目,比较它们的 RSSI,选出最强信号对应的 BSSID;

  3. 使用 wifi_config_t.sta.bssid_set = true + 填入选中的 BSSID,再调用 esp_wifi_connect()


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

static const char *TAG = "c3_best_ap";
static const char *TARGET_SSID = "YOUR_SSID";  // ← 替换为你要连接的 SSID 名称

// 事件组,用于等待扫描完成和连接成功
static EventGroupHandle_t s_wifi_event_group;
#define SCAN_DONE_BIT    BIT0
#define CONNECTED_BIT    BIT1

// 最佳 AP 信息
static wifi_ap_record_t best_ap;

// 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 && event_id == WIFI_EVENT_SCAN_DONE) {
        ESP_LOGI(TAG, "Scan done, selecting strongest AP...");
        uint16_t ap_count = 0;
        esp_wifi_scan_get_ap_num(&ap_count);
        wifi_ap_record_t *ap_list = 
            calloc(ap_count, sizeof(wifi_ap_record_t));
        esp_wifi_scan_get_ap_records(&ap_count, ap_list);

        bool found = false;
        for (int i = 0; i < ap_count; i++) {
            if (strcmp((char*)ap_list[i].ssid, TARGET_SSID) == 0) {
                ESP_LOGD(TAG, "Found SSID %s, BSSID " MACSTR ", RSSI %d",
                         ap_list[i].ssid,
                         MAC2STR(ap_list[i].bssid),
                         ap_list[i].rssi);
                if (!found || ap_list[i].rssi > best_ap.rssi) {
                    best_ap = ap_list[i];
                    found = true;
                }
            }
        }
        free(ap_list);

        if (found) {
            ESP_LOGI(TAG,
                "Will connect to BSSID " MACSTR " with RSSI %d",
                MAC2STR(best_ap.bssid), best_ap.rssi);
            xEventGroupSetBits(s_wifi_event_group, SCAN_DONE_BIT);
        } else {
            ESP_LOGW(TAG, "No AP with SSID \"%s\" found!", TARGET_SSID);
            // 也可以重试 scan:esp_wifi_scan_start(...)
        }
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        ESP_LOGI(TAG, "WiFi inited, start scan");
        esp_wifi_scan_start(NULL, false);
    }
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_CONNECTED) {
        ESP_LOGI(TAG, "Connected to AP");
        xEventGroupSetBits(s_wifi_event_group, CONNECTED_BIT);
    }
    else if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
        ip_event_got_ip_t* evt = (ip_event_got_ip_t*)event_data;
        ESP_LOGI(TAG, "Got IP:" IPSTR, IP2STR(&evt->ip_info.ip));
    }
}

// 初始化 Wi‑Fi 并启动 STA
static void wifi_init_and_start(void)
{
    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();
    }

    s_wifi_event_group = xEventGroupCreate();
    esp_netif_init();
    esp_event_loop_create_default();
    esp_netif_create_default_wifi_sta();

    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();
}

void app_main(void)
{
    // 1. 初始化并启动 Wi‑Fi
    wifi_init_and_start();

    // 2. 等待扫描完成
    EventBits_t bits = xEventGroupWaitBits(
        s_wifi_event_group,
        SCAN_DONE_BIT,
        pdFALSE, pdFALSE,
        portMAX_DELAY);

    if (bits & SCAN_DONE_BIT) {
        // 3. 根据 best_ap 填写连接配置
        wifi_config_t sta_cfg = { 0 };
        strcpy((char*)sta_cfg.sta.ssid, TARGET_SSID);
        // 如果是开放网络,此处 pwd 可以留空
        strcpy((char*)sta_cfg.sta.password, "YOUR_PASSWORD");
        sta_cfg.sta.bssid_set = true;
        memcpy(sta_cfg.sta.bssid, best_ap.bssid, 6);
        sta_cfg.sta.channel = best_ap.primary;  // 可选:绑定信道加速连接

        ESP_LOGI(TAG, "Connecting to selected AP ...");
        esp_wifi_set_config(WIFI_IF_STA, &sta_cfg);
        esp_wifi_connect();

        // 4. 等待连接结果
        bits = xEventGroupWaitBits(
            s_wifi_event_group,
            CONNECTED_BIT,
            pdFALSE, pdFALSE,
            pdMS_TO_TICKS(10000));
        if (bits & CONNECTED_BIT) {
            ESP_LOGI(TAG, "Successfully connected to best AP");
        } else {
            ESP_LOGE(TAG, "Failed to connect to best AP");
        }
    }
}

关键说明

  1. 扫描:调用 esp_wifi_scan_start(NULL, false) 扫描所有信道

  2. 筛选同名 SSID:遍历 wifi_ap_record_t 数组,比较 rssi,记录最强信号对应的 bssid

  3. 强制 BSSID 连接:在 wifi_config_t.sta 中设置 .bssid_set = true 且填入 bssid[6],还可指定 channel 加速连接

  4. 事件同步:使用 FreeRTOS 事件组等待扫描完成及连接成功

这样就能确保 ESP32‑C3 始终连接到信号最强的同名 AP。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值