ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用
1. 前言
现在,通常,为了让手机连上一个WiFi热点,基本上都是打开手机设置里面的WiFi设置功能,然后会看到里面有个WiFi热点列表,然后选择你要的连接上。 基本上你只要打开手机连接WiFi功能,都会发现附近有超级多的各种来路不明的WiFi热点(连接有风险需谨慎),那么手机是怎么知道附近的WiFi的呢?
通常,无线网络提供的WiFi热点,大部分都开放了SSID广播(记得之前博主讲过WiFi热点也可以隐藏的),Scan WiFi的功能就是扫描出所有附近的WiFi热点的SSID信息,这样一来,客户端就可以根据需要选择不同的SSID连入对应的无线网络中。
2. scan WiFi功能
一般扫描网络需要几百毫秒才能完成。
而扫描WiFi过程包括:
- 触发扫描过程
- 等待完成
- 提供结果
那么Scan WiFi库提供了两种方式实现上面的扫描过程:
- 同步扫描:通过单个函数在一次运行中完成,需要等待完成所有操作才能继续运行下面的操作。
- 异步扫描:把上面的过程分成几个步骤,每个步骤由一个单独函数完成,我们可以在扫描过程中执行其他任务。
一般来说,学过多线程的读者应该都知道同步和异步的区别,这里就不细说,非本篇的重点内容。
3. ESP8266WiFiScan库
有了前面的理论基础,那么我们开始详解一下ESP8266 scan wifi功能专用库——ESP8266WiFiScan库,大家使用的时候不需要
#include <ESP8266WiFiSTA.h>
只需要引入
#include<ESP8266WiFi.h>
至于原因,敬请回顾 ESP8266开发之旅 网络篇② ESP8266 工作模式与ESP8266WiFi库。 首先,对于Scan类库的描述,可以拆分为两个部分:
- 第一部分方法,扫描操作;
- 第二部分方法,获取扫描结果;
讲解之前,先浏览一下博主整理的百度脑图,以便有个整体认识:
3.1 扫描操作方法
3.1.1 scanNetworks —— 同步扫描周边有效wifi网络
函数说明:
/**
* Start scan WiFi networks available
* @param async run in async mode(是否启动异步扫描)
* @param show_hidden show hidden networks(是否扫描隐藏网络)
* @param channel scan only this channel (0 for all channels)(是否扫描特定通道)
* @param ssid* scan for only this ssid (NULL for all ssid's)(是否扫描特定的SSID)
* @return Number of discovered networks
*/
int8_t scanNetworks(bool async = false, bool show_hidden = false, uint8 channel = 0, uint8* ssid = NULL);
应用实例:
//实例代码 这只是部分代码 不能直接使用
//同步扫描
int n = WiFi.scanNetworks();//不需要填任何参数
Serial.println("scan done");
if (n == 0) {
Serial.println("no networks found");
} else {
Serial.println(" networks found");
}
3.1.2 scanNetworks(async ) —— 异步扫描周边有效wifi网络
函数说明:
/**
* Start scan WiFi networks available
* @param async run in async mode(是否启动异步扫描)
* @param show_hidden show hidden networks(是否扫描隐藏网络)
* @param channel scan only this channel (0 for all channels)(是否扫描特定通道)
* @param ssid* scan for only this ssid (NULL for all ssid's)(是否扫描特定的SSID)
* @return Number of discovered networks
*/
int8_t scanNetworks(bool async = false, bool show_hidden = false, uint8 channel = 0, uint8* ssid = NULL);
应用实例:
//实例代码 这只是部分代码 不能直接使用
//异步扫描
WiFi.scanNetworks(true);
// 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();
}
3.1.3 scanNetworksAsync —— 异步扫描周边wifi网络,并回调结果
函数说明:
/**
* Starts scanning WiFi networks available in async mode
* @param onComplete the event handler executed when the scan is done
* @param show_hidden show hidden networks
*/
void scanNetworksAsync(std::function<void(int)> onComplete, bool show_hidden = false);
应用实例:
//实例代码
#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) found
//1: Tech_D005107, Ch:6 (-72dBm)
//2: HP-Print-A2-Photosmart 7520, Ch:6 (-79dBm)
//3: ESP_0B09E3, Ch:9 (-89dBm) open
//4: Hack-4-fun-net, Ch:9 (-91dBm)
//5: UPC Wi-Free, Ch:11 (-79dBm)
3.1.4 scanComplete —— 检测异步扫描的结果
函数说明:
/**
* called to get the scan state in Async mode(异步扫描的结果函数)
* @return scan result or status
* -1 if scan not find
* -2 if scan not triggered
*/
int8_t scanComplete();
3.1.5 scanDelete —— 从内存中删掉最近扫描结果
函数说明:
/**
* delete last scan result from RAM(从内存中删除最近的扫描结果)
*/
void scanDelete();
注意点:
- 如果不删除,将会叠加上次扫描的结果;
3.2 扫描结果方法
3.2.1 SSID —— 获取wifi网络名字
函数说明:
/**
* Return the SSID discovered during the network scan.
* @param i specify from which network item want to get the information
* @return ssid string of the specified item on the networks scanned list
*/
String SSID(uint8_t networkItem);
3.2.2 RSSI —— 获取wifi网络信号强度
函数说明:
/**
* Return the RSSI of the networks discovered during the scanNetworks(信号强度)
* @param i specify from which network item want to get the information
* @return signed value of RSSI of the specified item on the networks scanned list
*/
int32_t RSSI(uint8_t networkItem);
3.2.3 encryptionType —— 获取wifi网络加密方式
函数说明:
/**
* Return the encryption type of the networks discovered during the scanNetworks(加密方式)
* @param i specify from which network item want to get the information
* @return encryption type (enum wl_enc_type) of the specified item on the networks scanned list
* ............ Values map to 802.11 encryption suites.....................
* AUTH_OPEN ----> ENC_TYPE_WEP = 5,
* AUTH_WEP ----> ENC_TYPE_TKIP = 2,
* AUTH_WPA_PSK ----> ENC_TYPE_CCMP = 4,
* ........... except these two, 7 and 8 are reserved in 802.11-2007.......
* AUTH_WPA2_PSK ----> ENC_TYPE_NONE = 7,
* AUTH_WPA_WPA2_PSK ----> ENC_TYPE_AUTO = 8
*/
uint8_t encryptionType(uint8_t networkItem);
3.2.4 BSSID —— 获取wifi网络mac地址
函数说明:
/**
* return MAC / BSSID of scanned wifi (物理地址)
* @param i specify from which network item want to get the information
* @return uint8_t * MAC / BSSID of scanned wifi
*/
uint8_t * BSSID(uint8_t networkItem);
/**
* return MAC / BSSID of scanned wifi (物理地址)
* @param i specify from which network item want to get the information
* @return uint8_t * MAC / BSSID of scanned wifi
*/
String BSSIDstr(uint8_t networkItem);
3.2.5 getNetworkInfo —— 获取整体网络信息,名字,信号强度等
函数说明:
/**
* loads all infos from a scanned wifi in to the ptr parameters
* @param networkItem uint8_t
* @param ssid const char**
* @param encryptionType uint8_t *
* @param RSSI int32_t *
* @param BSSID uint8_t **
* @param channel int32_t *
* @param isHidden bool *
* @return (true if ok)
*/
bool getNetworkInfo(uint8_t networkItem, String &ssid, uint8_t &encryptionType, int32_t &RSSI, uint8_t* &BSSID, int32_t &channel, bool &isHidden);
注意点:
- 入参前面多数加了&,意味着调完函数后外面获取到详细信息;
3.2.6 channel —— 获取wifi网络通道号
函数说明:
/**
* return channel of scanned wifi(通道号)
*/
int32_t channel(uint8_t networkItem);
3.2.7 isHidden —— 判断wifi网络是否是隐藏网络
函数说明:
/**
* return if the scanned wifi is Hidden (no SSID)(判断扫描到的wifi是否是隐藏wifi)
* @param networkItem specify from which network item want to get the information
* @return bool (true == hidden)
*/
bool isHidden(uint8_t networkItem);
4. 实例操作
上面博主讲了一堆方法理论的知识,下面我们开始讲解操作实例,博主尽量都在代码中注释,直接看代码就好。
4.1 操作实例1:同步扫描
实例代码:
/**
* Demo:
* STA模式下,演示同步扫描Scan wifi功能
* @author 单片机菜鸟
* @date 2019/09/03
*/
#include <ESP8266WiFi.h>
//以下三个定义为调试定义
#define DebugBegin(baud_rate) Serial.begin(baud_rate)
#define DebugPrintln(message) Serial.println(message)
#define DebugPrint(message) Serial.print(message)
void setup() {
//设置串口波特率,以便打印信息
DebugBegin(115200);
//延时5s 为了演示效果
delay(5000);
// 我不想别人连接我,只想做个站点
WiFi.mode(WIFI_STA);
//断开连接
WiFi.disconnect();
delay(100);
DebugPrintln("Setup done");
}
void loop() {
DebugPrintln("scan start");
// 同步扫描,等待返回结果
int n = WiFi.scanNetworks();
DebugPrintln("scan done");
if (n == 0){
DebugPrintln("no networks found");
}else{
DebugPrint(n);
DebugPrintln(" networks found");
for (int i = 0; i < n; ++i){
DebugPrint(i + 1);
DebugPrint(": ");
//打印wifi账号
DebugPrint(WiFi.SSID(i));
DebugPrint(",");
DebugPrint(String("Ch:")+WiFi.channel(i));
DebugPrint(",");
DebugPrint(WiFi.isHidden(i)?"hide":"show");
DebugPrint(" (");
//打印wifi信号强度
DebugPrint(WiFi.RSSI(i));
DebugPrint("dBm");
DebugPrint(")");
//打印wifi加密方式
DebugPrintln((WiFi.encryptionType(i) == ENC_TYPE_NONE)?"open":"*");
delay(10);
}
}
DebugPrintln("");
// 延时5s之后再次扫描
delay(5000);
}
测试结果(博主附近潜在的WiFi热点):
4.2 操作实例2: 异步扫描方式1
实例代码:
/**
* Demo:
* STA模式下,演示异步扫描Scan wifi功能
* @author 单片机菜鸟
* @date 2019/09/03
*/
#include <ESP8266WiFi.h>
//以下三个定义为调试定义
#define DebugBegin(baud_rate) Serial.begin(baud_rate)
#define DebugPrintln(message) Serial.println(message)
#define DebugPrint(message) Serial.print(message)
//定义一个扫描时间间隔
#define SCAN_PERIOD 5000
long lastScanMillis;
void setup() {
//设置串口波特率,以便打印信息
DebugBegin(115200);
//延时5s 为了演示效果
delay(5000);
// 我不想别人连接我,只想做个站点
WiFi.mode(WIFI_STA);
//断开连接
WiFi.disconnect();
delay(100);
DebugPrintln("Setup done");
}
void loop() {
long currentMillis = millis();
//触发扫描
if (currentMillis - lastScanMillis > SCAN_PERIOD){
WiFi.scanNetworks(true);
Serial.print("\nScan start ... ");
lastScanMillis = currentMillis;
}
// 判断是否有扫描结果
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();
}
}
测试结果:
4.3 操作实例3:异步扫描方式2
实例代码:
/**
* Demo:
* STA模式下,演示异步扫描Scan wifi功能
* @author 单片机菜鸟
* @date 2019/09/03
*/
#include <ESP8266WiFi.h>
//以下三个定义为调试定义
#define DebugBegin(baud_rate) Serial.begin(baud_rate)
#define DebugPrintln(message) Serial.println(message)
#define DebugPrint(message) Serial.print(message)
/**
* 打印扫描结果
* @param networksFound 结果个数
*/
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() {
//设置串口波特率,以便打印信息
DebugBegin(115200);
//延时5s 为了演示效果
delay(5000);
// 我不想别人连接我,只想做个站点
WiFi.mode(WIFI_STA);
//断开连接
WiFi.disconnect();
delay(100);
DebugPrintln("Setup done");
Serial.print("\nScan start ... ");
WiFi.scanNetworksAsync(prinScanResult);
}
void loop() {
}
测试结果:
5. 总结
扫描并不是多复杂的功能,分为同步扫描和异步扫描,一般楼主建议用异步扫描方式,不影响代码运行。
ESP8266开发之旅 网络篇⑤ Scan WiFi——ESP8266WiFiScan库的使用的更多相关文章
- ESP8266开发之旅 网络篇⑯ 无线更新——OTA固件更新
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 网络篇⑦ TCP Server & TCP Client
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 网络篇⑧ SmartConfig——一键配网
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 网络篇⑨ HttpClient——ESP8266HTTPClient库的使用
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 网络篇⑩ UDP服务
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 网络篇⑪ WebServer——ESP8266WebServer库的使用
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 网络篇⑬ SPIFFS——ESP8266 SPIFFS文件系统
授人以鱼不如授人以渔,目的不是为了教会你具体项目开发,而是学会学习的能力.希望大家分享给你周边需要的朋友或者同学,说不定大神成长之路有博哥的奠基石... QQ技术互动交流群:ESP8266&3 ...
- ESP8266开发之旅 网络篇④ Station——ESP8266WiFiSTA库的使用
1. 前言 在前面的篇章中,博主给大家讲解了ESP8266的软硬件配置以及基本功能使用,目的就是想让大家有个初步认识.并且,博主一直重点强调 ESP8266 WiFi模块有三种工作模式: St ...
- ESP8266开发之旅 网络篇③ Soft-AP——ESP8266WiFiAP库的使用
1. 前言 在前面的篇章中,博主给大家讲解了ESP8266的软硬件配置以及基本功能使用,目的就是想让大家有个初步认识.并且,博主一直重点强调 ESP8266 WiFi模块有三种工作模式: St ...
随机推荐
- 豆瓣电影TOP250和书籍TOP250爬虫
豆瓣电影 TOP250 和书籍 TOP250 爬虫 最近开始玩 Python , 学习爬虫相关知识的时候,心血来潮,爬取了豆瓣电影TOP250 和书籍TOP250, 这里记录一下自己玩的过程. 电影 ...
- Linux入门基础之 下
八.Linux 管道.重定向及文本处理 8.1.Linux 多命令协作:管道及重定向 8.1.1 开源文化 开源文化的核心理念之一就是不要重复发明轮子,很多的开源软件都是现有软件.代码.功能的重新组合 ...
- JQuery对于动态生成的标签绑定事件失效
JQuery对整个html文档进行dom操作后,我们要想动态绑定事件,有两种方法 1.在进行dom操作时,在标签中写上onclick="afun()" 2.利用document的操 ...
- 5分钟了解Prometheus
Prometheus(译:普罗米修斯)用领先的开源监控解决方案为你的指标和警报提供动力(赋能). 1. 概述 1.1. Prometheus是什么? Prometheus是一个开源的系统监控和警报 ...
- APP自動化測試腳本1
package com.lemon.day01; import java.net.MalformedURLException; import java.net.URL; import java.uti ...
- 基于RDD实现简单的WordCount程序
写在前面 因为觉得自己的代码量实在是太少了,所以,想着,每周至少写5个小的demo程序.现在的想法是,写一些Spark,Storm,MapReduce,Flume,kafka等等单独或组合使用的一些小 ...
- SpringBoot集成Spring Security入门体验
一.前言 Spring Security 和 Apache Shiro 都是安全框架,为Java应用程序提供身份认证和授权. 二者区别 Spring Security:重量级安全框架 Apache S ...
- Gradle 梳理:安装、入门使用方法
Gradle 教程:第一部分,安装[翻译] 原文地址:http://rominirani.com/2014/07/28/gradle-tutorial-part-1-installation-se ...
- Pots POJ 3414
/* *POJ 3414 *简单模板bfs *编程应该为了方便理解,尽量提供接口 */ #include<cstdio> #include<algorithm> #includ ...
- GitHub项目徽标
前言 GitHub徽标,GitHub Badge,你也可以叫它徽章.就是在项目README中经常看到的那些表明构建状态或者版本等信息的小图标.就像这样: 这些好看的小图标不仅简洁美观,而且包含了清晰易 ...