新闻  |   论坛  |   博客  |   在线研讨会
Arduino ESP8266 教程五----众里寻他千百度
Linux嵌入式 | 2023-01-03 13:24:39    阅读:690   发布文章

Arduino ESP8266 扫描周围的WiFi无线热点

扫描网络需要数百毫秒才能完成。当我们触发扫描过程,等待完成并提供结果时,可以通过一次运行完成此操作-所有这些都由一个功能完成。另一个选择是将其分为多个步骤,每个步骤由一个单独的功能完成。这样,我们可以在扫描过程中执行其他任务,这称为异步扫描。

相关函数

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。每秒应无干扰地闪烁四次。

*博客内容为网友个人发布,仅代表博主个人观点,如有侵权请联系工作人员删除。

参与讨论
登录后参与讨论
工科男,多年嵌入式工作者,每日分享工作中常遇到的一些“坑”
推荐文章
最近访客