ESP32 開發筆記(三)源碼示例 14_WIFI_Scan 附近WIFI信號掃描示例

開發板購買連接windows

https://item.taobao.com/item.htm?spm=a2oq0.12575281.0.0.50111deb2Ij1As&ft=t&id=626366733674網絡

開發板簡介
開發環境搭建 windows
源碼示例:
    0_Hello Bug (ESP_LOGX與printf)    工程模板/打印調試輸出
    1_LED                                                    LED亮滅控制       
    2_LED_Task                                          使用任務方式控制LED
    3_LEDC_PWM                                      使用LEDC來控制LED實現呼吸燈效果
    4_ADC_LightR                                      使用ADC讀取光敏電阻實現光照傳感
    5_KEY_Short_Long                              按鈕長按短按實現
    6_TouchPad_Interrupt                          電容觸摸中斷實現
    7_WS2812_RMT                                  使用RMT實現RGB_LED彩虹變色示例
    8_DHT11_RMT                                    使用RMT實現讀取DHT11溫溼度傳感器
    9_SPI_SDCard                                    使用SPI總線實現TF卡文件系統示例
    10_IIC_ADXL345                                使用IIC總線實現讀取ADXL345角度加速度傳感器
    11_IIC_AT24C02                                 使用IIC總線實現小容量數據儲存測試
    12_IR_Rev_RMT                                使用RMT實現紅外遙控接收解碼(NEC編碼)
    13_IR_Send_RMT                              使用RMT實現紅外數據發送(NEC編碼)
    14_WIFI_Scan                                    附近WIFI信號掃描示例    
    15_WIFI_AP                                        建立軟AP示例
    16_WIFI_AP_TCP_Server                  在軟AP模式下實現TCP服務端
    17_WIFI_AP_TCP_Client                   在軟AP模式下實現TCP客戶端
    18_WIFI_AP_UDP                              在軟AP模式下實現UDP通信
    19_WIFI_STA                                      建立STA站模
    20_WIFI_STA_TCP_Server                在站模式STA下實現TCP服務端
    21_WIFI_STA_TCP_Client                 在站模式STA下實現TCP客戶端
    22_WIFI_STA_UDP                            在站模式STA下實現UDP通信
    23_LVGL_Test                                     LVGL圖形庫簡單示例app

在ESP32的設計開發中,咱們必然會須要使用到wifi或ble功能,今天就講解下如何將WIFI功能歸入到ESP32中來。函數

 

在 ESP-IDF 中,整個網絡協議棧包含的狀態定義在頭文件 components/esp32/include/esp_event.h中,由枚舉類型 system_event_id_t 定義oop

SYSTEM_EVENT_WIFI_READY = 0,           /*!< ESP32 WiFi ready */
    SYSTEM_EVENT_SCAN_DONE,                /*!< ESP32 finish scanning AP */
    SYSTEM_EVENT_STA_START,                /*!< ESP32 station start */
    SYSTEM_EVENT_STA_STOP,                 /*!< ESP32 station stop */
    SYSTEM_EVENT_STA_CONNECTED,            /*!< ESP32 station connected to AP */
    SYSTEM_EVENT_STA_DISCONNECTED,         /*!< ESP32 station disconnected from AP */
    SYSTEM_EVENT_STA_AUTHMODE_CHANGE,      /*!< the auth mode of AP connected by ESP32 station changed */
    SYSTEM_EVENT_STA_GOT_IP,               /*!< ESP32 station got IP from connected AP */
    SYSTEM_EVENT_STA_LOST_IP,              /*!< ESP32 station lost IP and the IP is reset to 0 */
    SYSTEM_EVENT_STA_WPS_ER_SUCCESS,       /*!< ESP32 station wps succeeds in enrollee mode */
    SYSTEM_EVENT_STA_WPS_ER_FAILED,        /*!< ESP32 station wps fails in enrollee mode */
    SYSTEM_EVENT_STA_WPS_ER_TIMEOUT,       /*!< ESP32 station wps timeout in enrollee mode */
    SYSTEM_EVENT_STA_WPS_ER_PIN,           /*!< ESP32 station wps pin code in enrollee mode */
    SYSTEM_EVENT_STA_WPS_ER_PBC_OVERLAP,   /*!< ESP32 station wps overlap in enrollee mode */
    SYSTEM_EVENT_AP_START,                 /*!< ESP32 soft-AP start */
    SYSTEM_EVENT_AP_STOP,                  /*!< ESP32 soft-AP stop */
    SYSTEM_EVENT_AP_STACONNECTED,          /*!< a station connected to ESP32 soft-AP */
    SYSTEM_EVENT_AP_STADISCONNECTED,       /*!< a station disconnected from ESP32 soft-AP */
    SYSTEM_EVENT_AP_STAIPASSIGNED,         /*!< ESP32 soft-AP assign an IP to a connected station */
    SYSTEM_EVENT_AP_PROBEREQRECVED,        /*!< Receive probe request packet in soft-AP interface */
    SYSTEM_EVENT_GOT_IP6,                  /*!< ESP32 station or ap or ethernet interface v6IP addr is preferred */
    SYSTEM_EVENT_ETH_START,                /*!< ESP32 ethernet start */
    SYSTEM_EVENT_ETH_STOP,                 /*!< ESP32 ethernet stop */
    SYSTEM_EVENT_ETH_CONNECTED,            /*!< ESP32 ethernet phy link up */
    SYSTEM_EVENT_ETH_DISCONNECTED,         /*!< ESP32 ethernet phy link down */
    SYSTEM_EVENT_ETH_GOT_IP,               /*!< ESP32 ethernet got IP from connected AP */

認證方式測試

WIFI_AUTH_OPEN = 0,         /**< authenticate mode : open */
    WIFI_AUTH_WEP,              /**< authenticate mode : WEP */
    WIFI_AUTH_WPA_PSK,          /**< authenticate mode : WPA_PSK */
    WIFI_AUTH_WPA2_PSK,         /**< authenticate mode : WPA2_PSK */
    WIFI_AUTH_WPA_WPA2_PSK,     /**< authenticate mode : WPA_WPA2_PSK */
    WIFI_AUTH_WPA2_ENTERPRISE,  /**< authenticate mode : WPA2_ENTERPRISE */
    WIFI_AUTH_WPA3_PSK,         /**< authenticate mode : WPA3_PSK */
    WIFI_AUTH_WPA2_WPA3_PSK,    /**< authenticate mode : WPA2_WPA3_PSK */

事件循環庫是esp提供的一種事件處理方法,而默認事件循環是用於系統事件(例如WiFi事件)的特殊循環類型,這裏建立一個默認事件循環用以處理wifi鏈接事件ui

ESP_ERROR_CHECK(esp_event_loop_create_default()); // 建立默認事件循環

1、編寫代碼

先引用必要頭文件編碼

// WIFI_Scan Example

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

WIFI事件處理函數加密

// wifi 事件
static esp_err_t event_handler(void *ctx, system_event_t *event)
{
	switch (event->event_id)
	{
	case SYSTEM_EVENT_WIFI_READY:			// ESP32 WIFI就緒
		ESP_LOGI(TAG, "event-->ESP32 WiFi ready");
		break;
	case SYSTEM_EVENT_SCAN_DONE:			// 掃描AP完成
		ESP_LOGI(TAG, "event-->ESP32 finish scanning AP");
		break;
	case SYSTEM_EVENT_STA_START:			// 開始STA模式
		ESP_LOGI(TAG, "event-->ESP32 station start");
		break;
	case SYSTEM_EVENT_STA_STOP:				// 中止STA模式
		ESP_LOGI(TAG, "event-->ESP32 station stop");
		break;
	case SYSTEM_EVENT_STA_CONNECTED:		// STA模式鏈接到AP
		ESP_LOGI(TAG, "event-->ESP32 station connected to AP");
		break;
	case SYSTEM_EVENT_STA_DISCONNECTED:		// STA模式斷開與AP的鏈接
		ESP_LOGI(TAG, "event-->ESP32 station disconnected from AP");
		break;
	case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:	// ESP32 Station鏈接的AP的驗證模式已更改
		ESP_LOGI(TAG, "event-->the auth mode of AP connected by ESP32 station changed");
		break;
	case SYSTEM_EVENT_STA_GOT_IP:			// ESP32 Station從鏈接的AP獲取到IP
		ESP_LOGI(TAG, "event-->ESP32 station got IP from connected AP");
		break;		
	case SYSTEM_EVENT_STA_LOST_IP:			// ESP32 Station丟失IP或IP重置
		ESP_LOGI(TAG, "event-->ESP32 station lost IP and the IP is reset to 0");
		break;
	case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:	// ESP32 station wps在註冊模式下成功
		ESP_LOGI(TAG, "event--> ESP32 station wps succeeds in enrollee mode");
		break;
	case SYSTEM_EVENT_STA_WPS_ER_FAILED:	// ESP32 station wps在註冊模式下失敗
		ESP_LOGI(TAG, "event--> ESP32 station wps fails in enrollee mode");
		break;
	case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:	// ESP32 station wps在註冊模式超時
		ESP_LOGI(TAG, "event--> ESP32 station wps timeout in enrollee mode");
		break;
	case SYSTEM_EVENT_STA_WPS_ER_PIN:		// ESP32 Station WPS密碼在登記人模式下
		ESP_LOGI(TAG, "event--> ESP32 station wps pin code in enrollee mode");
		break;
	case SYSTEM_EVENT_STA_WPS_ER_PBC_OVERLAP:// ESP32 station wps在登記人模式下重疊
		ESP_LOGI(TAG, "event--> ESP32 station wps overlap in enrollee mode");
		break;
	case SYSTEM_EVENT_AP_START:				// ESP32 AP模式開始
		ESP_LOGI(TAG, "event--> ESP32 soft-AP start");
		break;
	case SYSTEM_EVENT_AP_STOP:				// ESP32 AP模式中止
		ESP_LOGI(TAG, "event--> ESP32 soft-AP stop");
		break;
	case SYSTEM_EVENT_AP_STACONNECTED:		// ESP32 AP模式下,有站接入此AP
		ESP_LOGI(TAG, "event--> a station connected to ESP32 soft-AP ");
		break;
	case SYSTEM_EVENT_AP_STADISCONNECTED:	// ESP32 AP模式下,有站斷開此AP
		ESP_LOGI(TAG, "event--> a station disconnected from ESP32 soft-AP ");
		break;
	case SYSTEM_EVENT_AP_STAIPASSIGNED:		// ESP32 AP模式下,爲鏈接的站分配IP
		ESP_LOGI(TAG, "event--> ESP32 soft-AP assign an IP to a connected station");
		break;
	case SYSTEM_EVENT_AP_PROBEREQRECVED:	// ESP32 AP模式下,在soft-AP接口中接收探測請求數據包
		ESP_LOGI(TAG, "event--> Receive probe request packet in soft-AP interface");
		break;
	default:
		break;
	}
	return ESP_OK;
}

打印WIFI的認證方式.net

static void print_auth_mode(int 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_WPA2_ENTERPRISE:
		ESP_LOGI(TAG, "Authmode \tWIFI_AUTH_WPA2_ENTERPRISE");
		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 \tWIFI_AUTH_UNKNOWN");
		break;
	}
}

打印WIFI的加密方式

static void print_cipher_type(int pairwise_cipher, int 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 \tWIFI_CIPHER_TYPE_UNKNOWN");
		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 \tWIFI_CIPHER_TYPE_UNKNOWN");
		break;
	}
}

初始化WIFI 配置掃描模式 開始掃描 打印掃描到的AP信息

// 初始化WIFI 配置掃描模式 開始掃描 打印掃描到的AP信息
static void wifi_scan(void)
{
	ESP_ERROR_CHECK(esp_netif_init());					// 初始化底層TCP/IP堆棧。在應用程序啓動時,應該調用此函數一次
	ESP_ERROR_CHECK(esp_event_loop_create_default());	// 建立默認事件循環
	esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();// 建立一個默認的WIFI-STA網絡接口,
	assert(sta_netif);									// 若是初始化錯誤,此API將停止
	wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
	ESP_ERROR_CHECK(esp_wifi_init(&cfg));				// 使用默認wifi初始化配置

	uint16_t number = DEFAULT_SCAN_LIST_SIZE;			// 默認掃描列表大小
	wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];	// AP信息結構體大小
	uint16_t ap_count = 0;								// 初始化AP數量0
	memset(ap_info, 0, sizeof(ap_info));				// 初始化AP信息結構體

	ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));	// 設置WiFi的工做模式爲 STA
	ESP_ERROR_CHECK(esp_wifi_start());					// 啓動WiFi鏈接
	ESP_ERROR_CHECK(esp_wifi_scan_start(NULL, true));	// 開始掃描WIFI(默認配置,阻塞方式)
	ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));// 獲取搜索的具體AP信息
	ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));		//接入點的數量
	ESP_LOGI(TAG, "Total APs scanned = %u", ap_count);
	for (int i = 0; (i < DEFAULT_SCAN_LIST_SIZE) && (i < ap_count); i++) {
		ESP_LOGI(TAG, "SSID \t\t%s", ap_info[i].ssid);		// 打印WIFI名稱
		ESP_LOGI(TAG, "RSSI \t\t%d", ap_info[i].rssi);		// 打印信號強度	
		print_auth_mode(ap_info[i].authmode);				// 打印認證方式
		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);
	}
}

主函數

// 主函數
void app_main(void)
{
	ESP_LOGI(TAG, "APP Start......");
	// Initialize NVS
	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 );
	wifi_scan();
}

2、下載測試

打開ESP-IDF Command Prompt

cd命令進入此工程目錄

cd F:\ESP32_DevBoard_File\14_WIFI_Scan

查看電腦設備管理器中開發板的串口號

執行idf.py -p COM9 flash monitor從串口9下載並運行打開口顯示設備調試信息   Ctrl+c退出運行