Hello World:WiFi 扫描仪

知识库
知识库文档
/tech-stacks/esp-idf/examples/Hello World:WiFi 扫描仪.md

文档

ESP-IDF Hello World:WiFi 扫描仪

目标

在 ESP32 上运行 ESP-IDF FreeRTOS 任务,扫描周围 WiFi 网络并输出信号强度。

完整代码

/* main.c — ESP32 WiFi Scanner
 * 硬件:任意 ESP32/ESP32-S3 开发板
 * 依赖:ESP-IDF v5.x
 */

#include <stdio.h>
#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_wifi.h"
#include "esp_log.h"
#include "nvs_flash.h"

static const char *TAG = "wifi_scan";

/* WiFi 扫描任务 */
void wifi_scan_task(void *pvParameters) {
    // 初始化 WiFi(STA 模式)
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());

    while (1) {
        // 触发扫描
        ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, true));
        ESP_LOGI(TAG, "=== WiFi 扫描完成 ===");

        // 获取扫描结果
        uint16_t ap_count = 0;
        ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));
        ESP_LOGI(TAG, "发现 %d 个 WiFi 网络", ap_count);

        if (ap_count > 0) {
            wifi_ap_record_t *ap_records = calloc(ap_count, sizeof(wifi_ap_record_t));
            ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_count, ap_records));

            // 打印前 10 个最强信号
            int show = ap_count > 10 ? 10 : ap_count;
            for (int i = 0; i < show; i++) {
                ESP_LOGI(TAG,
                    "SSID: %-20s | RSSI: %4d dBm | CH: %2d | %s",
                    ap_records[i].ssid,
                    ap_records[i].rssi,
                    ap_records[i].primary,
                    ap_records[i].authmode == WIFI_AUTH_OPEN ? "开放" : "加密");
            }
            free(ap_records);
        }

        // 清理扫描结果
        esp_wifi_clear_ap_list();

        ESP_LOGI(TAG, "5 秒后重新扫描...\n");
        vTaskDelay(pdMS_TO_TICKS(5000));
    }
}

void app_main(void) {
    // 初始化 NVS(WiFi 库需要)
    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);

    ESP_LOGI(TAG, "ESP32 WiFi 扫描仪启动");

    // 创建扫描任务
    xTaskCreate(wifi_scan_task, "wifi_scan", 4096, NULL, 5, NULL);
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.16)
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
project(wifi_scanner)

运行步骤

# 1. 激活 ESP-IDF 环境
. ~/esp/esp-idf/export.sh

# 2. 设置目标芯片
idf.py set-target esp32

# 3. 配置(可选 — 修改分区表等)
idf.py menuconfig

# 4. 编译 & 烧录 & 监控
idf.py build flash monitor
# 退出监控:Ctrl+]

预期输出

I (456) wifi_scan: ESP32 WiFi 扫描仪启动
I (1234) wifi_scan: === WiFi 扫描完成 ===
I (1235) wifi_scan: 发现 12 个 WiFi 网络
I (1236) wifi_scan: SSID: MyHome-5G           | RSSI:  -42 dBm | CH: 11 | 加密
I (1237) wifi_scan: SSID: Starbucks WiFi       | RSSI:  -58 dBm | CH:  6 | 开放
...
I (1238) wifi_scan: 5 秒后重新扫描...

关键点

  • app_main 是 ESP-IDF 的入口函数(类似 main
  • 必须先初始化 NVS,WiFi 库依赖它存储配置
  • FreeRTOS 任务栈大小 4096 是典型值,复杂任务需增大
  • esp_wifi_scan_start(NULL, true)true 表示阻塞等待扫描完成

信息

路径
/tech-stacks/esp-idf/examples/Hello World:WiFi 扫描仪.md
更新时间
2026/5/31