一. WiFi的STA和AP模式指什么?
ESP8266有三種工作模式,分別為:AP,STA,AP混合STA
1. AP
AP,也就是無線接入點,是一個無線網絡的創建者,是網絡的中心節點。一般家庭或辦公室使用的無線路由器就一個AP。
2. STA
STA是Station的簡稱,類似于無線終端,STA本身并不接受無線的接入,它可以連接到AP,簡單來說就是和手機連接WIFI熱點的工作狀態相同,可以連接其它的熱點。
3. AP混合STA
了解了前兩個概念,AP混合STA模式就不難理解了,就是既可以連接到其它的WIFI熱點,也可以讓別的無線終端連接,這兩個過程能同時進行。
二. 切換模式相關API
1. 設置WIFI模式
WiFi.mode(WIFI_MODE_AP);
模式定義如下:
typedef enum {
WIFI_MODE_NULL = 0, /**< null mode */
WIFI_MODE_STA, /**< WiFi station mode */
WIFI_MODE_AP, /**< WiFi soft-AP mode */
WIFI_MODE_APSTA, /**< WiFi station + soft-AP mode */
WIFI_MODE_MAX
} wifi_mode_t;
2. 獲取WIFI工作模式
WiFi.getMode();
3. 使能/使能STA模式
WiFi.enableSTA(true);
4. 使能/使能AP模式
WiFi.enableAP(true);
5. 使能/使能Wifi休眠
WiFi.setSleep(true);
僅限STA模式, 默認開啟休眠, 如果對實時性要求高,應關閉休眠
三. AP熱點
1. WIFI AP熱點建立 WiFisoftAP()
bool WiFiAPClass::softAP(const char *ssid, const char *passphrase = (const char *)__null, int channel = 1, int ssid_hidden = 0, int max_connection = 4)
功能:建立AP熱點
參數:
ssid – WIFI名稱SSID (max 63 char).
passphrase – WIFI密碼(for WPA2 min 8 char, for open use NULL)
channel – WiFi 信道, 1 - 13.(默認1)
ssid_hidden – 是否隱藏WIFI名 (0 = broadcast SSID, 1 = hide SSID) 默認0,不隱藏
max_connection – 最大可連接數, 1 - 4. 默認4
2. 配置AP 熱點 WiFi.softAPConfig();
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
功能: 配置AP 熱點
參數:
local_ip – 本地IP 192.168.4.1
gateway – 網關IP 192.168.4.1
subnet – 子網掩碼 255.255.255.0
3. 斷開wifi WiFi.disconnect();
bool WiFiSTAClass::disconnect(bool wifioff = false, bool eraseap = false)
功能: 斷開AP熱點
參數:
wifioff : 為true則還將關閉網絡功能, 默認false
eraseap : 為true則清空AP熱點配置信息, 默認false
返回:
返回wlan狀態碼
4. 一些獲取AP熱點信息的API
#include <Arduino.h>
#include "WiFi.h"
void setup()
{
Serial.begin(115200);
WiFi.softAP("ESP_AP", "12345678");
}
void loop()
{
Serial.print("主機名:");
Serial.println(WiFi.softAPgetHostname());
Serial.print("主機IP:");
Serial.println(WiFi.softAPIP());
Serial.print("主機IPV6:");
Serial.println(WiFi.softAPIPv6());
Serial.print("主機SSID:");
Serial.println(WiFi.SSID());
Serial.print("主機廣播IP:");
Serial.println(WiFi.softAPBroadcastIP());
Serial.print("主機mac地址:");
Serial.println(WiFi.softAPmacAddress());
Serial.print("主機連接個數:");
Serial.println(WiFi.softAPgetStationNum());
Serial.print("主機網絡ID:");
Serial.println(WiFi.softAPNetworkID());
Serial.print("主機狀態:");
Serial.println(WiFi.status());
delay(1000);
}
5. 設置主機名稱 WiFi.softAPsetHostname("ESP_xiongba");
bool WiFiAPClass::softAPsetHostname(const char *hostname)
Set the softAP interface Host name.
參數:
hostname – pointer to const string
返回:
true on success
四. STA模式
1. 開始wifi連接 WiFi.begin()
wl_status_t WiFiSTAClass::begin(const char *ssid, const char *passphrase = (const char *)__null, int32_t channel = 0, const uint8_t *bssid = (const uint8_t *)__null, bool connect = true)
還有 2 個重載
啟動Wifi連接如果設置了密碼短語,將自動選擇最安全的支持模式
參數:
ssid – WIFI名, const char* Pointer to the SSID string.
passphrase – 密碼, const char * Optional. Passphrase. Valid characters in a passphrase must be between ASCII 32-126 (decimal).
channel – (AP的通道, 可選參數)Optional. Channel of AP
bssid – BSSID是指站點的MAC地址(可選參數) uint8_t[6] Optional. BSSID / MAC of AP
connect – (是否連接此WIFI, 可選參數)Optional. call connect
WiFi.begin("anny", "20141208");
while (!WiFi.isConnected())
{
delay(500);
Serial.print(".");
}
Serial.println("WIFI連接成功!");
2. wifi配置
bool WiFiSTAClass::config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0, IPAddress dns2 = (uint32_t)0)
Change IP configuration settings disabling the dhcp client
參數:
local_ip – 當地IP, Static ip configuration
gateway – 網關, Static gateway configuration
subnet – 子網掩碼, Static Subnet mask
dns1 – DNS服務器1, Static DNS server 1
dns2 – DNS服務器2, Static DNS server 2
3. 關閉wifi連接
用法和AP的disconnect一樣
bool WiFiSTAClass::disconnect(bool wifioff = false, bool eraseap = false)
Disconnect from the network
參數:
wifioff
返回:
one value of wl_status_t enum
4. 其他一些獲取WIFI信息的API
#include <Arduino.h>
#include "WiFi.h"
void setup()
{
Serial.begin(115200);
// WiFi.softAP("ESP_AP", "12345678");
// WiFi.softAPsetHostname("ESP_xiongba");
WiFi.begin("anny", "20141208");
WiFi.setAutoReconnect(true);
}
void loop()
{
Serial.print("是否連接:");
Serial.println(WiFi.isConnected());
Serial.print("本地IP:");
Serial.println(WiFi.localIP());
Serial.print("本地IPv6:");
Serial.println(WiFi.localIPv6());
Serial.print("mac地址:");
Serial.println(WiFi.macAddress());
Serial.print("網絡ID:");
Serial.println(WiFi.networkID());
Serial.print("休息:");
Serial.println(WiFi.getSleep());
Serial.print("獲取狀態嗎:");
Serial.println(WiFi.getStatusBits());
Serial.print("getTxPower:");
Serial.println(WiFi.getTxPower());
Serial.print("是否自動連接:");
Serial.println(WiFi.getAutoConnect());
Serial.print("是否自動重連:");
Serial.println(WiFi.getAutoReconnect());
Serial.print("獲取模式:");
Serial.println(WiFi.getMode());
Serial.print("獲取主機名:");
Serial.println(WiFi.getHostname());
Serial.print("獲取網關IP:");
Serial.println(WiFi.gatewayIP());
Serial.print("dnsIP:");
Serial.println(WiFi.dnsIP());
Serial.print("狀態:");
Serial.println(WiFi.status());
delay(1000);
}
關于狀態碼, 請看下面解釋:
5. 設置自動連接
bool WiFiSTAClass::setAutoReCoennect(bool autoConnect)
Setting the ESP32 station to connect to the AP (which is recorded)automatically or not when powered on. Enable auto-connect by default.
參數:
autoConnect – bool
返回:
if saved
6. 設置自動重連
設置WIFI斷開后是否自動嘗試重連
bool WiFiSTAClass::setAutoReconnect(bool autoReconnect)
五. 掃描WIFI
1. 掃描WIFI,返回掃描數量
這個功能默認在阻塞模式下運行,程序會掃描WIFI,期間什么事情都做不了, 可以通過參數設置改為異步模式.
int16_t WiFiScanClass::scanNetworks(bool async = false, bool show_hidden = false, bool passive = false, uint32_t max_ms_per_chan = 300U)
Start scan WiFi networks available
參數:
async – run in async mode
show_hidden – show hidden networks
返回:
Number of discovered networks
只返回了掃描到的WIFI的數量, 那結果怎么得到? 原來他已經將掃描到的WIFI存入了WIFI單例對應的數組中.
比如 SSID,都存入了 WiFi.SSID中,可以通過索引值遍歷獲取. 其他屬性亦然.
2. 掃描連接WIFI(同步方式)
#include <Arduino.h>
#include "WiFi.h"
String ssid;
String password;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_MODE_STA);
WiFi.disconnect(); //斷開可能的連接
delay(100);
Serial.println("開始掃描WIFI:");
int n = WiFi.scanNetworks();
if (n)
{
Serial.print("掃描到");
Serial.print(n);
Serial.println("個WIFI");
for (size_t i = 0; i < n; i++)
{
Serial.print("WiFi的名稱(SSID):");
Serial.println(WiFi.SSID(i));
Serial.print("WiFi的信號強度(RSSI):");
Serial.println(WiFi.RSSI(i));
Serial.print("WiFi加密與否:");
Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? "未加密" : "加密");
if (WiFi.SSID(i) == "anny")
{
ssid = WiFi.SSID(i);
password = "20141208";
}
}
}
else
{
Serial.println("沒掃描到WIFI");
}
WiFi.begin(ssid.c_str(), password.c_str());
while (!WiFi.isConnected())
{
Serial.print(".");
}
Serial.println("連接成功");
}
void loop()
{
}
3. 異步模式時,獲取掃描完成信息 WiFi.scanComplete();
int16_t WiFiScanClass::scanComplete()
called to get the scan state in Async mode
返回:
scan result or status -1 if scan not fin -2 if scan not triggered
如果沒用掃描完成, 則返回-1 , 如果根本沒在掃描,返回-2
如果完成了掃描,返回掃描結果
4. 清除現有的掃描結果
WiFi.scanDelete();
5. 掃描連接WIFI(異步)
采用異步掃描方式, 每隔0.5秒詢問一下WiFi.scanComplete();判斷是否掃描完畢.
如果掃描完畢,置標志位,停定時器.
觸發連接程序, 連接完成后
#include <Arduino.h>
#include "WiFi.h"
#include "Ticker.h"
String ssid = "";
String password = "";
Ticker t1;
void aysncScanHandler()
{
if (!WiFi.isConnected())
{
int wifiScanStatus = WiFi.scanComplete();
switch (wifiScanStatus)
{
case -1:
Serial.println("掃描中...");
break;
case -2:
Serial.println("未進行掃描...");
break;
default:
Serial.println("掃描完成");
for (size_t i = 0; i < wifiScanStatus; i++)
{
Serial.print("WiFi的名稱(SSID):");
Serial.println(WiFi.SSID(i));
Serial.print("WiFi的信號強度(RSSI):");
Serial.println(WiFi.RSSI(i));
Serial.print("WiFi加密與否:");
Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? "未加密" : "加密");
if (WiFi.SSID(i) == "anny")
{
ssid = WiFi.SSID(i);
password = "20141208";
};
}
WiFi.scanDelete();
t1.detach();
break;
}
}
}
void connectAnny()
{
WiFi.begin();
while (!WiFi.isConnected())
{
Serial.print(".");
}
Serial.println("連接成功");
}
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_MODE_STA);
WiFi.disconnect(); //斷開可能的連接
delay(100);
Serial.println("開始掃描WIFI:");
WiFi.scanNetworks(true);
t1.attach(0.5, aysncScanHandler);
}
void loop()
{
if (!WiFi.isConnected())
{
if (ssid == "anny")
{
Serial.println(ssid);
connectAnny();
}
}
}
六. 智能配網
1. 什么是智能配網
智能配網這種快速連接方式,相對于 AP 模式連接簡化操作,更加貼近于市場
1、手機連上 WiFi,打開智能硬件指定 APP 軟件,進入配置界面,輸入手機所在 WiFi 密碼,請求配網 TOKEN
2、智能硬件開啟混雜模式監聽所有網絡數據包
3、手機通過廣播、組播循環發送 ssid/password/token
4、硬件設備通過 UDP 包(長度)獲取配置信息捕捉到 ssid/password/token,報文后解碼,得到正確的 SSID 和密碼,然后主動連接指定 SSID 的路由完成連接。
2. 智能配網過程
進入智能配網模式后, 用手機微信掃描安信可官方二維碼
輸入WIFI密碼
微信會廣播這些信息,
ESP32獲取后得知 WIFI名, 密碼. 自動存儲好. 自動連接WIFI
3. 示例, 智能配網過程
思路: 先自動聯網20秒, 如果失敗了進入智能配網階段, 智能配網過程如上??
#include <Arduino.h>
#include "WiFi.h"
void mySmartWifiConfig()
{
WiFi.mode(WIFI_MODE_STA);
Serial.println("開啟智能配網:");
WiFi.beginSmartConfig();
while (1)
{
Serial.print(".");
delay(500);
if (WiFi.smartConfigDone())
{
Serial.println("配網成功");
Serial.printf("SSID:%s", WiFi.SSID().c_str());
Serial.printf("PSW:%s", WiFi.psk().c_str());
break;
}
}
}
bool autoConfig()
{
WiFi.disconnect(true,true);
WiFi.begin();
for (size_t i = 0; i < 20; i++)
{
int wifiStatus = WiFi.status();
if (wifiStatus == WL_CONNECTED)
{
Serial.println("自動連接成功!");
return 1;
}
else
{
delay(1000);
Serial.println("等待自動配網中...");
}
}
Serial.println("無法自動配網!");
return 0;
}
void setup()
{
Serial.begin(115200);
delay(5000);
if (!autoConfig())
{
mySmartWifiConfig();
}
}
void loop()
{
if (WiFi.isConnected())
{
Serial.println("網絡已連接");
delay(1000);
}
}
第一次連接時:
手機端也會同步顯示:
第二次連接時: