ESP-IDF库开发教程之(5)--WiFi Scanner

esp32芯片的主要特点与其前身esp8266相同,确保能够连接到wifi网络。我已经在之前的文章中讨论过该芯片支持的不同标准(802.11 b / g / n)和安全方法(WEP,WPA-PSK等);今天我要解释如何开发一个程序来扫描可用的wifi网络。

完整的程序在我的Github仓库中可用;让我们评论一下源代码。

正如我们所知道的,每个使用esp-idf框架的程序都是从app_main()方法开始执行的。此方法开始初始化tcpip堆栈和wifi事件处理程序:

tcpip_adapter_init();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));();
ESP_ERROR_CHECK(esp_event_loop_init(event_handler, NULL));

ESP_ERROR_CHECK是一个方便的宏,在esp_err.h中定义,用于检查不同框架方法的结果。如果一个调用返回常量ESP_OK,程序的执行可以继续;如果不是,则程序停止并且串行输出中显示错误行。

esp-idf wifi堆栈需要一个方法(=事件处理程序),每次触发与wifi接口相关的事件(例如连接到新网络......)时都会调用该方法。我们将在以后的关于事件处理的教程中讨论,现在定义一个空的处理程序方法就足够了:

static esp_err_t event_handler(void *ctx, system_event_t *event)
{
  return ESP_OK;
} esp_err_t event_handler(void *ctx, system_event_t *event)
{
  return ESP_OK;
}

该程序继续配置,初始化和启动wifi堆栈:

wifi_init_config_t wifi_config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_config));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());= WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_config));
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_start());

您可以使用WIFI_INIT_CONFIG_DEFAULT()宏创建一个默认配置,并使用固定的WIFI_MODE_STA以站模式启动wifi接口。站模式是当接口充当“客户端”时,连接到接入点。

现在您可以配置并启动扫描过程:

wifi_scan_config_t scan_config = {
	.ssid = 0,
	.bssid = 0,
	.channel = 0,
        .show_hidden = true
};
ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, true));= {
	.ssid = 0,
	.bssid = 0,
	.channel = 0,
        .show_hidden = true
};
ESP_ERROR_CHECK(esp_wifi_scan_start(&scan_config, true));

使用scan_config变量,您可以配置扫描进程将使用的某些过滤器(例如,只扫描给定通道),并要求显示或不显示具有隐藏SSID的接入点。每个字段的零值表示ALL(=无过滤器)。

扫描过程可以在阻塞(真)或非阻塞(假)模式下执行,更改函数esp_wifi_scan_start的第二个参数。在这个例子中,我使用了阻塞模式:程序执行停止,直到扫描完成。

扫描完成后,您可以获取检测到的网络列表:

uint16_t ap_num = MAX_APs;
wifi_ap_record_t ap_records[MAX_APs];
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_num, ap_records)); ap_num = MAX_APs;
wifi_ap_record_t ap_records[MAX_APs];
ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&ap_num, ap_records));

esp_wifi_scan_get_ap_records方法返回一个包含wifi_ap_record_t元素的数组。您必须保留一些内存空间来存储该数组,定义要检索的元素的最大数量。在我的程序中,我定义了MAX_APs常量:

#define MAX_APs 20

通过引用esp_wifi_scan_get_ap_records方法传递ap_num变量可能听起来很奇怪。原因是该方法以两种方式(inout)使用变量:作为输入来查找作为第二个参数传递的数组的最大容量,并将其作为输出返回在数组中找到并存储的有效网络数。
您现在可以在串行连接上打印找到的网络的详细信息:

您现在可以在串行连接上打印找到的网络的详细信息:

printf("Found %d access points:\n", ap_num);
for(int i = 0; i < ap_num; i++)
	printf("%32s | %7d | %4d | %12s\n", 
	(char *)ap_records[i].ssid, ap_records[i].primary, ap_records[i].rssi,
	getAuthModeName(ap_records[i].authmode));("Found %d access points:\n", ap_num);
for(int i = 0; i < ap_num; i++)
	printf("%32s | %7d | %4d | %12s\n", 
	(char *)ap_records[i].ssid, ap_records[i].primary, ap_records[i].rssi,
	getAuthModeName(ap_records[i].authmode));

最后,创建一个空的任务来避免芯片的连续重置:

xTaskCreate(&loop_task, "loop_task", 2048, NULL, 5, NULL);
[...]
void loop_task(void *pvParameter) {
    while(1) { 
        vTaskDelay(1000 / portTICK_RATE_MS);		
    }
}(&loop_task, "loop_task", 2048, NULL, 5, NULL);
[...]
void loop_task(void *pvParameter) {
    while(1) { 
        vTaskDelay(1000 / portTICK_RATE_MS);		
    }
}

在程序编译过程中,请记得在menuconfig(组件配置 - ESP32特定配置)中激活wifi模块:

ESP-IDF库开发教程之(5)--WiFi Scanner_第1张图片

Here’s the output of the program:

ESP-IDF库开发教程之(5)--WiFi Scanner_第2张图片

 

你可能感兴趣的:(ESP32,ESP32开发之旅,ESP-IDF,ESP32)