"); //-->
扫描网络需要数百毫秒才能完成。当我们触发扫描过程,等待完成并提供结果时,可以通过一次运行完成此操作-所有这些都由一个功能完成。另一个选择是将其分为多个步骤,每个步骤由一个单独的功能完成。这样,我们可以在扫描过程中执行其他任务,这称为异步扫描。
相关函数Millis()获取机器运行的时间长度, 单位毫秒. 系统最长的记录时间接近50天, 如果超出时间将从0开始。形式为unsigned long millis (void)返回时间为 unsigned long类型, 如果用 int 保存时间将得到错误结果。
c_str()函数返回一个指向正规C字符串的指针常量, 内容与本string串相同。这是为了与c语言兼容,在c语言中没有string类型,故必须通过string类对象的成员函数c_str()把string 对象转换成c中的字符串样式。
WiFi.disconnect()是关闭与使用先前保存的凭据自动建立的访问点的连接
WiFi.scanNetworks(async, show_hidden)这两个函数参数都是boolean类型。 asysnc-如果设置为true则扫描将在后台开始,并且功能将退出而无需等待结果。要检查结果,请使用scanComplete下面介绍的单独功能。show_hidden-设置true为包含在具有隐藏SSID的扫描结果网络中。返回值为发现的网络数量。
void setup() { Serial.begin(115200); Serial.println(); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); } void loop() { Serial.print("Scan start ... "); int n = WiFi.scanNetworks(); Serial.print(n); Serial.println(" network(s) found"); for (int i = 0; i < n; i++) { Serial.println(WiFi.SSID(i)); } Serial.println(); delay(5000); }WiFi.scanComplete()
扫描完成功能
返回发现的网络数。如果未完成扫描,则返回值<0,扫描仍在进行中:-1 *尚未触发扫描:-2。
WiFi.scanDelete()从内存中删除最后的扫描结果。
WiFi.scanNetworksAsync(onComplete,show_hidden)函数参数: onComplete-扫描完成后执行的事件处理程序show_hidden-可选boolean参数,将其设置 true为扫描隐藏的网络
#include "ESP8266WiFi.h" void prinScanResult(int networksFound){ Serial.printf("%d network(s) found\n", networksFound); for (int i = 0; i < networksFound; i++) { Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i + 1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : ""); } } void setup(){ Serial.begin(115200); Serial.println(); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); WiFi.scanNetworksAsync(prinScanResult); } void loop() {} 结果输出: 5 network(s) found1: Tech_D005107, Ch:6 (-72dBm)2: HP-Print-A2-Photosmart 7520, Ch:6 (-79dBm)3: ESP_0B09E3, Ch:9 (-89dBm) open4: Hack-4-fun-net, Ch:9 (-91dBm)5: UPC Wi-Free, Ch:11 (-79dBm)
显示结果
扫描是以同步还是异步模式完成都没有关系,可以使用相同的API获得扫描结果。通过提供一个“ networkItem”(可识别已发现网络的索引(从零开始))的单个结果即可访问。
SSID返回扫描期间发现的网络的SSID。
WiFi.SSID(networkItem)
返回的SSID是String类型。该networkItem是网络的从零开始的索引扫描时发现的。
encryptionType返回在扫描过程中发现的网络的加密类型。
WiFi.encryptionType(networkItem)
函数返回一个编码加密类型的数字,如下所示:
5:ENC_TYPE_WEP-WEP
2:ENC_TYPE_TKIP-WPA / PSK
4:ENC_TYPE_CCMP-WPA2 / PSK
7:ENC_TYPE_NONE-开放式网络
8:ENC_TYPE_AUTO-WPA / WPA2 / PSK
networkItem是扫描时发现的网络的从零开始的索引。
RSSI返回扫描过程中发现的网络的RSSI(接收信号强度指示)。
WiFi.RSSI(networkItem)
返回的RSSI属于该int32_t类型。networkItem是扫描时发现的网络的从零开始的索引。
BSSID返回BSSID(基本服务集标识),它是扫描期间发现的网络的MAC地址的另一个名称。
WiFi.BSSID(networkItem)
函数返回一个指向存储uint8_tBSSID 的内存位置(一个大小为6个元素的数组)的指针。
如果您不喜欢指针,则此函数的另一个版本将返回String。
WiFi.BSSIDstr(networkItem)
networkItem是扫描时发现的网络的从零开始的索引。
channel返回扫描期间发现的网络的信道。
WiFi.channel(networkItem)
返回的通道属于该int32_t类型。networkItem是扫描时发现的网络的从零开始的索引。
isHidden如果在扫描过程中发现的网络是否隐藏,则返回信息。
WiFi.isHidden(networkItem)
返回值,如果是bolean类型,true则表示网络是隐藏的。networkItem是扫描时发现的网络的从零开始的索引。
getNetworkInfo通过单个函数调用返回上一章中讨论的所有网络信息。
WiFi.getNetworkInfo(networkItem,&ssid,&encryptionType,&RSSI,*&BSSID,&channel,&isHidden)
该networkItem是网络的从零开始的索引扫描时发现的。所有其他输入参数均通过引用传递给函数。因此,将使用为特定的检索到的实际值更新它们networkItem。函数本身返回boolean true或false确认信息检索是否成功。
int n = WiFi.scanNetworks(false, true);
String ssid;
uint8_t encryptionType;
int32_t RSSI;
uint8_t* BSSID;
int32_t channel;
bool isHidden;
for (int i = 0; i < n; i++)
{
WiFi.getNetworkInfo(i, ssid, encryptionType, RSSI, BSSID, channel, isHidden);
Serial.printf("%d: %s, Ch:%d (%ddBm) %s %s\n", i + 1, ssid.c_str(), channel, RSSI, encryptionType == ENC_TYPE_NONE ? "open" : "", isHidden ? "hidden" : "");
}
异步扫描我们想做的是触发网络扫描过程,然后返回执行代码loop()。扫描完成后,我们将在方便的时候检查网络列表。“时间关键过程”将在250ms的时间内通过闪烁的LED进行模拟。我们希望闪烁的图案在任何时候都不会被打扰。
要实现这样的功能,我们应该避免延时函数在loop()中。相反,我们将定义触发特定操作的时间段。然后在内部loop()我们将检查millis()(内部时钟,以毫秒为单位),并在该时间段到期时触发操作。
流程:
首先,我们应该定义扫描周期和内部变量lastScanMillis,这些变量将保留上一次扫描的时间。
#define SCAN_PERIOD 5000long lastScanMillis;
然后在loop()里面,我们将检查是否SCAN_PERIOD时间到,时间周期到后触发下一次扫描:
if (currentMillis - lastScanMillis > SCAN_PERIOD) { WiFi.scanNetworks(true); Serial.print("\nScan start ... "); lastScanMillis = currentMillis; }
请注意,上面的示例没有提供WiFi.scanNetworks(true)额外的参数。这是一条以异步模式进行扫描的指令,即触发扫描过程,不要等待结果(处理将在后台完成)并移至下一行代码。我们需要使用异步模式,否则250ms的LED闪烁模式会被干扰,因为扫描时间超过250ms。
最后,我们应该定期检查扫描是否完成,以便在准备好后打印出结果。为此,我们将使用函数WiFi.scanComplete(),该函数完成后将返回找到的网络数。如果扫描仍在进行,则返回-1。如果尚未触发扫描,它将返回-2。
int n = WiFi.scanComplete();if(n >= 0) { Serial.printf("%d network(s) found\n", n); for (int i = 0; i < n; i++) { Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i+1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : ""); } WiFi.scanDelete(); }
请注意,此功能WiFi.scanDelete()正在从内存中删除扫描结果,因此不会在每次loop()运行时一遍又一遍地打印出来。
完整的示例里面的代码setup()与前面的示例中描述的相同,除了额外pinMode()的配置LED的输出引脚。
#include "ESP8266WiFi.h" #define BLINK_PERIOD 250long lastBlinkMillis; boolean ledState; #define SCAN_PERIOD 5000long lastScanMillis; void setup() { Serial.begin(115200); Serial.println(); pinMode(LED_BUILTIN, OUTPUT); WiFi.mode(WIFI_STA); WiFi.disconnect(); delay(100); } void loop(){ long currentMillis = millis(); // blink LED if (currentMillis - lastBlinkMillis > BLINK_PERIOD) { digitalWrite(LED_BUILTIN, ledState); ledState = !ledState; lastBlinkMillis = currentMillis; } // trigger Wi-Fi network scan if (currentMillis - lastScanMillis > SCAN_PERIOD) { WiFi.scanNetworks(true); Serial.print("\nScan start ... "); lastScanMillis = currentMillis; } // print out Wi-Fi network scan result uppon completion int n = WiFi.scanComplete(); if(n >= 0) { Serial.printf("%d network(s) found\n", n); for (int i = 0; i < n; i++) { Serial.printf("%d: %s, Ch:%d (%ddBm) %s\n", i+1, WiFi.SSID(i).c_str(), WiFi.channel(i), WiFi.RSSI(i), WiFi.encryptionType(i) == ENC_TYPE_NONE ? "open" : ""); } WiFi.scanDelete(); } }结果输出
将以上程序上传到ESP模块并打开一个串行监视器。您应该每隔5秒钟打印一次类似的列表:
Scan start ... 5 network(s) found1: Tech_D005107, Ch:6 (-72dBm)2: HP-Print-A2-Photosmart 7520, Ch:6 (-79dBm)3: ESP_0B09E3, Ch:9 (-89dBm) open4: Hack-4-fun-net, Ch:9 (-91dBm)5: UPC Wi-Free, Ch:11 (-79dBm)
检查LED。每秒应无干扰地闪烁四次。
*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。