ESP32 S3学习记录-wifi模块之SCAN(四)

前言

wifi在日常生活中并不陌生,众所周知,wifi也可以分为不同的模式来使用,比如手机可以直接连接wifi上网,也可以开热点给别人使用,本文主要介绍一下wifi的AP模式和STA模式,以及wifi的扫描功能。

一、ESP32-S3 WIFI简介

ESP32-S3的WiFi库支持配置及监控ESP32-S3的Wi-Fi连网功能。它支持配置基站模式(即
STA 模式或 WiFi 客户端模式),此时 ESP32-S3 连接到接入点(AP)。还支持 AP 模式(即 SoftAP 模式或接入点模式),此时基站连接到 ESP32-S3。同时,支持 AP-STA 共存模式,此时
ESP32-S3 既是接入点,同时又作为 STA。
WiFi 主要有三种模式:
AP 模式:即无线接入点,是我们常说的手机热点,被其他设备连接;
STA 模式:即 Station,是连接热点的设备。
STA 和 AP两种模式共存:就像手机那样可以开热点,也可以连接其他热点。

二、初始化步骤

1、AP模式初始化步骤

在这里插入图片描述

2、STA模式初始化步骤

代码如下(示例):

三、SCAN

1、总流程图

在这里插入图片描述

2、源码

这个初始化代码网上很多,这里不做过多解释,直接贴源码

/**
 * @brief 打印WiFi认证模式
 * 
 * @param authmode 认证模式枚举值
 */
static void print_auth_mode(wifi_auth_mode_t authmode) {
    switch (authmode) {
        case WIFI_AUTH_OPEN:
            ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_OPEN");
            break;
        case WIFI_AUTH_WEP:
            ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WEP");
            break;
        case WIFI_AUTH_WPA_PSK:
            ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_PSK");
            break;
        case WIFI_AUTH_WPA2_PSK:
            ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_PSK");
            break;
        case WIFI_AUTH_WPA_WPA2_PSK:
            ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA_WPA2_PSK");
            break;
        case WIFI_AUTH_WPA3_PSK:
            ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA3_PSK");
            break;
        case WIFI_AUTH_WPA2_WPA3_PSK:
            ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_WPA3_PSK");
            break;
        default:
            ESP_LOGI(TAG, "Authmode \tUnknown");
            break;
    }
}

/**
 * @brief 打印加密类型
 * 
 * @param pairwise_cipher 单播加密类型
 * @param group_cipher 组播加密类型
 */
static void print_cipher_type(wifi_cipher_type_t pairwise_cipher, wifi_cipher_type_t group_cipher) {
    switch (pairwise_cipher) {
        case WIFI_CIPHER_TYPE_NONE:
            ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_NONE");
            break;
        case WIFI_CIPHER_TYPE_WEP40:
            ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP40");
            break;
        case WIFI_CIPHER_TYPE_WEP104:
            ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_WEP104");
            break;
        case WIFI_CIPHER_TYPE_TKIP:
            ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP");
            break;
        case WIFI_CIPHER_TYPE_CCMP:
            ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_CCMP");
            break;
        case WIFI_CIPHER_TYPE_TKIP_CCMP:
            ESP_LOGI(TAG, "Pairwise Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
            break;
        default:
            ESP_LOGI(TAG, "Pairwise Cipher \tUnknown");
            break;
    }
    
    switch (group_cipher) {
        case WIFI_CIPHER_TYPE_NONE:
            ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_NONE");
            break;
        case WIFI_CIPHER_TYPE_WEP40:
            ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP40");
            break;
        case WIFI_CIPHER_TYPE_WEP104:
            ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_WEP104");
            break;
        case WIFI_CIPHER_TYPE_TKIP:
            ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP");
            break;
        case WIFI_CIPHER_TYPE_CCMP:
            ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_CCMP");
            break;
        case WIFI_CIPHER_TYPE_TKIP_CCMP:
            ESP_LOGI(TAG, "Group Cipher \tWIFI_CIPHER_TYPE_TKIP_CCMP");
            break;
        default:
            ESP_LOGI(TAG, "Group Cipher \tUnknown");
            break;
    }
}


void wifi_scan(void)
{
    // 初始化网络接口 - 这是TCP/IP协议栈的基础
    ESP_ERROR_CHECK(esp_netif_init());

    /* 创建默认的事件循环,用于处理WiFi等系统事件 */
    ESP_ERROR_CHECK(esp_event_loop_create_default());

    /* 创建并初始化STA模式的默认网络接口 */
    esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
    assert(sta_netif);  // 确保网络接口创建成功

    /* WiFi初始化配置,使用默认参数 */
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    // 定义扫描参数
    uint16_t number = DEFAULT_SCAN_LIST_SIZE;  // 最大扫描AP数量
    wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];  // 存储AP信息的数组
    uint16_t ap_count = 0;  // 实际扫描到的AP数量

    // 清空AP信息数组,避免脏数据
    memset(ap_info, 0, sizeof(ap_info));

    /* 设置WiFi为STA(工作站)模式 */
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

    /* 启动WiFi功能 */
    ESP_ERROR_CHECK(esp_wifi_start());

    /* 开始扫描附近的WiFi网络
    * 第一个参数:扫描配置(NULL表示使用默认配置)
    * 第二个参数:是否阻塞(true=阻塞式扫描,等待扫描完成)
    */
    esp_wifi_scan_start(NULL, true);

    /* 获取扫描到的AP列表记录 */
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));

    /* 获取扫描到的AP数量 */
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));

    // 打印扫描到的AP总数
    ESP_LOGI(TAG, "Total APs scanned = %u", ap_count);

    /* 遍历并打印每个WiFi网络的详细信息 */
    for (int i = 0; (i < DEFAULT_SCAN_LIST_SIZE) && (i < ap_count); i++) {
        ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);        // 网络名称
        ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);        // 信号强度
        print_auth_mode(ap_info[i].authmode);                 // 认证模式
        
        // 非WEP加密时显示加密类型
        if (ap_info[i].authmode != WIFI_AUTH_WEP) {
            print_cipher_type(ap_info[i].pairwise_cipher, ap_info[i].group_cipher);
        }

        ESP_LOGI(TAG, "Channel \t\t%d\n", ap_info[i].primary);  // 信道
    }
}

3、运行效果

直接调用wifi_scan函数即可打印出扫描到的热点,如下图所示:
在这里插入图片描述

总结

扫描功能一般是配合STA模式使用的,对于此功能不做过多分析。

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐