前言

本节我们学习使用WeMos D1的WIFI Scan功能,并编写两个实例分别实现同步扫描和异步扫描,所谓同步扫描是指调用扫描函数后,程序会阻塞,直到扫描结束,直接调用WiFi.scanComplete()即可查看扫描结果;而异步操作是指,调用扫描函数后,程序会继续往下执行,不过需要等到扫描完成才能获取到有效的结果。

一、基础知识

1.WIFI Scan简介

通常要加入一个无线网络,我们需要找到它的网络名称,即SSID,使用WIFI Scan功能便可以获得周围无线网络的SSID。

扫描附近热点在产品产测过程中也经常用到,因为工厂工序比较多,不可能每个工序都测试测试所有功能,通过测试扫描热点的强度可以判断模块WIFI性能是否OK。

2.ESP8266WiFi库

wemos D1 arduino物联网开发板应用笔记5-扫描热点_第1张图片

从上图中可以看出ESP8266WiFi库主要包含Station、Soft AP、config、WiFiClient、WiFiServer、scan、hostname,本节主要介绍scan相关的函数使用。

wemos D1 arduino物联网开发板应用笔记5-扫描热点_第2张图片

二、实例

1 同步扫描

1.1程序

#include "ESP8266WiFi.h"

void setup() {
  Serial.begin(115200);

  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);

  Serial.println("Setup done");
}

void loop() {
  Serial.println("scan start");

  // WiFi.scanNetworks will return the number of networks found
  int n = WiFi.scanNetworks();
  Serial.println("scan done");
  if (n == 0)
    Serial.println("no networks found");
  else
  {
    Serial.print(n);
    Serial.println(" networks found");
    for (int i = 0; i < n; ++i)
    {
      // Print SSID and RSSI for each network found
      Serial.print(i + 1);
      Serial.print(": ");
      Serial.print(WiFi.SSID(i));
      Serial.print(" (");
      Serial.print(WiFi.RSSI(i));
      Serial.print(")");
      Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
      delay(10);
    }
  }
  Serial.println("");

  // Wait a bit before scanning again
  delay(5000);
}

首先设置模块为WIFI_STA模式,就是作为客户端可以连接无线网络的模式,之后程序调用WiFi.scanNetworks()开始扫描,然后紧接着调用WiFi.SSID()获取无线网络名称,WiFi.RSSI()获取无线网络的信号强度,WiFi.encryptionType(i)获取加密方式,最后逐一打印出来。

1.2编译运行

wemos D1 arduino物联网开发板应用笔记5-扫描热点_第3张图片

2 异步扫描

2.1程序

#include "ESP8266WiFi.h"
#include 

Ticker tk;

int timer_flag = 0;
int scan_res = 0;

void time_coming_cicyle_cb(void)
{
  timer_flag = 1;
}

void setup() {
  Serial.begin(115200);

  // Set WiFi to station mode and disconnect from an AP if it was previously connected
  WiFi.mode(WIFI_STA);
  WiFi.disconnect();
  delay(100);
  tk.attach(5, time_coming_cicyle_cb);
  Serial.println("Setup done");
}

void loop() {

  if (1 == timer_flag)
  {
    Serial.println("scan start");
    timer_flag = 0;
    WiFi.scanNetworks(true);
  }

  scan_res = WiFi.scanComplete();
  if (-1 == scan_res)
  {
  Serial.println("scan not finish");
  }
  else if(-2 == scan_res)
  {
    Serial.println("scan not triggered");
  }
  else if(scan_res >= 0)
  {
    Serial.println("scan done");
    if (scan_res == 0)
      Serial.println("no networks found");
    else
    {
      Serial.print(scan_res);
      Serial.println(" networks found");
      for (int i = 0; i < scan_res; ++i)
      {
        // Print SSID and RSSI for each network found
        Serial.print(i + 1);
        Serial.print(": ");
        Serial.print(WiFi.SSID(i));
        Serial.print(" (");
        Serial.print(WiFi.RSSI(i));
        Serial.print(")");
        Serial.println((WiFi.encryptionType(i) == ENC_TYPE_NONE)?" ":"*");
        delay(10);
      }
    }
    Serial.println("");
  }

  // Wait a bit before scanning again
  delay(500);
}

程序首先设置一个5秒的周期定时器,定时时间到了设置timer_flag标志位为1,loop()函数循环执行,检测到timer_flag为1,调用一次异步扫描函数,然后清楚标志位,loop()函数中同时调用WiFi.scanComplete()获取扫描结果。

2.2编译运行

wemos D1 arduino物联网开发板应用笔记5-扫描热点_第4张图片

由于setup()中设置5秒的定时器,所以程序执行的5秒内没有触发扫描,因此WiFi.scanComplete()返回-2,打印scan not triggered,扫描后不能立刻获取结果,此时因此WiFi.scanComplete()返回-1,打印scan not finish,接下里获取并打印扫描到的结果。

三、结语

1.总结:

本节完,实际操作过程中需要注意的地方有如下几点:

(1) 用异步扫描还是同步扫描?

一般来说,使用异步扫描即可,如此一来,程序可以往下继续执行,不受扫描影响,对于特定场景,同步扫描也是可以的。

2.后记:

如您在使用过程中有任何问题,请加QQ群进一步交流,也可以github提Issue。

QQ交流群:906015840 (备注:物联网项目交流)

获取源码:关注公众号,回复wemos即可

一叶孤沙出品:一沙一世界,一叶一菩提

wemos D1 arduino物联网开发板应用笔记5-扫描热点_第5张图片