Wi-Fi库
要使用 ESP32 Wi-Fi 功能,您需要做的第一件事就是包括WiFi.h代码中的库,如下所示:
#include <WiFi.h>ESP32 Wi-Fi 模式
ESP32板可以充当Wi-Fi站、接入点或两者兼而有之。要设置 Wi-Fi 模式,请使用WiFi.mode()并将所需模式设置为参数:
| 模式 | 说明 |
|---|---|
WiFi.mode(WIFI_STA) | 站点模式:ESP32连接到接入点 |
WiFi.mode(WIFI_AP) | 接入点模式:站点可以连接到ESP32 |
WiFi.mode(WIFI_AP_STA) | 接入点和连接到另一个接入点的站点 |
Wi-Fi站
当ESP32设置为Wi-Fi站时,它可以连接到其他网络(例如您的路由器)。在这种情况下,路由器会为您的 ESP 板分配一个唯一的 IP 地址。您可以通过参考ESP唯一IP地址,使用同样连接到同一网络的其他设备(站点)与ESP通信。
路由器已经连接到网络,因为我们可以使用ESP32板从网络上请求信息,例如API(天气数据)的资料,将数据发布到在线平台,使用来自互联网的图标和图像或包含 JavaScript 库来构建 Web 服务器页面。
将ESP32设置为站点并连接到Wi-Fi网络
在某些情况下,这可能不是最好的配置——当你附近没有网络,并且仍然想连接到ESP来控制它时。在此情景中,您必须将 ESP 板设置为接入点。
接入点
当您将ESP32板设置为接入点时,您可以使用任何具有Wi-Fi功能的设备进行连接,而无需连接到路由器。当您将ESP32设置为接入点时,您将创建自己的Wi-Fi网络,附近的Wi-Fi设备(站)可以连接到它,例如您的智能手机或电脑。所以,你不需要连接到路由器来控制它。
如果您想让几个ESP32设备在不需要路由器的情况下相互通信,这也很有用。
因为ESP32不会像您的路由器那样进一步连接到有线网络,所以它被称为soft-AP(软接入点)。这意味着,如果您尝试从互联网上加载库或使用固件,它将无法工作。如果您向互联网上的服务发出HTTP请求,将传感器读数发布到云端或使用互联网上的服务(例如发送电子邮件),它也不起作用。
将ESP32设置为接入点
要将ESP32设置为接入点,请将Wi-Fi模式设置为接入点:
WiFi.mode(WIFI_AP)然后,使用softAP()方法如下:
WiFi.softAP(ssid, password);ssid是您想给ESP32接入点起的名字,以及password是接入点的密码。如果您不想设置密码,请将其设置为NULL。
还有其他可选参数,你可以传递给softAP()方法。以下是所有参数:
WiFi.softAP(const char* ssid, const char* password, int channel, int ssid_hidden, int max_connection)- ssid:接入点的名称——最多63个字符;
- password:最少8个字符;如果您希望接入点打开则设置为
NULL; - channel:Wi-Fi频道编号(1-13);
- ssid_hidden:(0=广播SSID,1=隐藏SSID);
- max_connection:最大同时连接的客户端(1-4);
Wi-Fi站+接入点
ESP32可以同时设置为Wi-Fi站和接入点。将其模式设置为WIFI_AP_STA
WiFi.mode(WIFI_AP_STA);以上是关于ESP32中关于WiFi模式说明。
扫描Wi-Fi网络
ESP32可以在其Wi-Fi范围内扫描附近的Wi-Fi网络。在您的Arduino IDE中,转到文件>示例>WiFi>WiFiScan。这将用一个图来展示ESP32板扫描范围内的Wi-Fi网络。
这对于检查您尝试连接的Wi-Fi网络是否在您的主板或其他应用程序的范围内很有用。您的Wi-Fi项目可能不经常工作,因为由于Wi-Fi强度不足,它可能无法连接到您的路由器。
下面是一个示例:
#include <Arduino.h>
// 引入WiFi库
#include <WiFi.h>
// 获取WiFi加密类型
const char* getEncryptionType(wifi_auth_mode_t authMode) {
switch (authMode) {
case WIFI_AUTH_OPEN:
return "OPEN";
case WIFI_AUTH_WEP:
return "WEP";
case WIFI_AUTH_WPA_PSK:
return "WPA_PSK";
case WIFI_AUTH_WPA2_PSK:
return "WPA2_PSK";
case WIFI_AUTH_WPA_WPA2_PSK:
return "WPA_WPA2_PSK";
case WIFI_AUTH_WPA2_ENTERPRISE:
return "WPA2_ENTERPRISE";
case WIFI_AUTH_WPA3_PSK:
return "WPA3_PSK";
case WIFI_AUTH_WPA2_WPA3_PSK:
return "WPA2_WPA3_PSK";
default:
return "UNKNOWN";
}
}
// 阻塞扫描WiFi网络
void wifiScan() {
Serial.println("开始扫描WiFi网络");
// WiFi.scanNetworks()返回发现的WiFi网络数量
int numSsid = WiFi.scanNetworks();
if(numSsid == 0) {
Serial.println("没有发现WiFi网络");
} else {
Serial.printf("发现%d个WiFi网络\n", numSsid);
// 打印扫描结果
for (int i = 0; i < numSsid; i++) {
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" RSSI: (");
Serial.print(WiFi.RSSI(i));
Serial.print("dBm)");
Serial.print(" Ch:");
Serial.print(WiFi.channel(i));
Serial.print(" ");
Serial.println(getEncryptionType(WiFi.encryptionType(i)));
delay(10);
}
}
//... 扫描循环结束后 ...
// 删除扫描结果以释放内存
WiFi.scanDelete();
Serial.println("扫描完成");
}
// 异步扫描WiFi网络
void wifiScanSync() {
WiFi.scanNetworks(true); // 传递true参数以启用异步扫描
Serial.println("开始扫描WiFi网络");
}
void setup() {
Serial.begin(115200);
// 设置WiFi模式为STA(Station)模式
// 将WiFi设置为站模式,如果AP之前已连接,则断开与AP的连接
WiFi.mode(WIFI_STA);
// 断开WiFi连接
WiFi.disconnect();
Serial.println("WiFi已设置为STA模式并断开连接");
// 阻塞扫描 wifi网络
// wifiScan();
// 异步扫描 wifi网络
wifiScanSync();
}
void loop() {
int scanResult = WiFi.scanComplete();
if (scanResult >= 0) {
Serial.println("扫描已完成,处理结果");
Serial.printf("发现%d个WiFi网络\n", scanResult);
for (int i = 0; i < scanResult; ++i) {
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" RSSI: (");
Serial.print(WiFi.RSSI(i));
Serial.print("dBm)");
Serial.print(" Ch:");
Serial.print(WiFi.channel(i));
Serial.print(" ");
Serial.println(getEncryptionType(WiFi.encryptionType(i)));
}
//... 扫描循环结束后 ...
// 删除扫描结果以释放内存
WiFi.scanDelete();
}
delay(5000);
}我们可以将上面的代码编译后上传到ESP开发板中,并检查可用的网络以及RSSI(接收信号强度指示器)
运行后找到了6个
示例代码说明
WiFi.scanNetworks()返回找到的网络数量
int n = WiFi.scanNetworks();扫描后,您可以访问每个网络的参数WiFi.SSID()打印特定网络的SSID:
Serial.print(WiFi.SSID(i));WiFi.RSSI()返回该网络的RSSI。RSSI代表接收信号强度指示器。它是射频客户端设备从接入点或路由器接收的功率水平的估计度量。
Serial.print(WiFi.RSSI(i));WiFi.encryptionType()返回网络加密类型。这个具体的例子在开放网络的情况下放了一个*。然而,该函数可以返回以下选项之一(而不仅仅是开放网络):
- WIFI_AUTH_OPEN
- WIFI_AUTH_WEP
- WIFI_AUTH_WPA_PSK
- WIFI_AUTH_WPA2_PSK
- WIFI_AUTH_WPA_WPA2_PSK
- WIFI_AUTH_WPA2_ENTERPRISE
扫描Wi-Fi网络的阻塞与非阻塞
在代码里面有两种扫描Wi-Fi网络的方式:阻塞和非阻塞。WiFi.scanNetworks() 默认是阻塞式调用,这意味着在扫描过程中,你的程序会暂停执行其他任务。对于简单的程序这没问题,但对于需要同时处理其他任务(如响应按钮、处理传感器数据等)的复杂应用,这会是个问题。
所以我在代码里面也同样实现了非阻塞的扫描:
- 调用
WiFi.scanNetworks(true)启动非阻塞扫描 - 在
loop()中定期检查WiFi.scanComplete()的返回值,当返回值大于或等于 0 时,表示扫描完成 - 处理完结果后,可以调用
WiFi.scanDelete()
删除扫描结果以释放内存
WiFi.scanNetworks() 会在内部分配内存来存储扫描结果。如果你的程序会多次调用 wifiScan(),最好在处理完结果后调用 WiFi.scanDelete() 来释放这部分内存,防止内存泄漏。对于长时间运行的应用尤其重要。
//... 扫描循环结束后 ...
// 删除扫描结果以释放内存
WiFi.scanDelete();
Serial.println("扫描完成");
评论