文档
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表示阻塞等待扫描完成