
Station模式又叫做站點工作模式,類似於無線終端
處於Station模式下的ESP8266,可以連接到AP。通過Station(簡稱為“STA”)模式,ESP8266作為客戶端連接到路由的wifi信號
1. 首先AP發出信標幀(beacon),意思就是我在這里,誰來泡我啊,移動工作站也會發出探(probe)幀,意思是有誰我可以泡啊,每隔一定時間發出一次。(后面會講到Scan功能)。
2. 所以,根據這一點,可以產生很多有價值的應用。比如你的帶WiFi功能的手機,即使在不連接wifi的情況下,只要打開WiFi功能,就可以被路由器截獲這幀信息,路由器收集之后,你的信息就會被一個審計的東西發到服務器上,你手機號xxx上線時間xxx下線時間xxx都瀏覽了哪些網頁,WiFi建立連接過程都一目了然,你的位置也全都暴露了,這就叫WiFi探針。具體流程如下所示:
STA --------> Probe Request ----------> AP
STA <-------- Probe Response <---------- AP,這個是由wifi返回的應答幀; 接下來是身份驗證過程,可以使用諸如WEP、WEP2、WPA等加密方式應用到認證請求上
STA --------> Authentication Request ----------> AP 認證請求中包含認證Auth類型,OpenSystem,sharedKey等信息,路由器返回認證結果
STA <-------- Authentication Response <---------- AP 連接請求
STA --------> Association Request ----------> AP 請求與AP建立關聯,從而可以進行數據交互; 認證通過連接請求OK返回
STA <-------- Association Response <---------- AP
通過這個連接過程分析,也證明了我們經常聽到的一句話,不要輕易連接不明WiFi熱點,各種盜取信息層出不窮。
同時,學過網絡的同學都知道,每台設備都會有個一個IP地址,用來在整個網絡環境下的唯一標識。
而處於Station模式下的ESP8266,可以使用DHCP Client的方式,由上級路由分配的ip,或者設置成靜態ip。
如果是采用DHCP分配的方式,獲取的ip是動態的,在一些需要知道設備ip才能通信的場合下,就需要通過其他手段來獲取ip(一種思路是通過訪問webserver去獲取模塊信息);
如果是采用設置靜態ip的方式,那么就有一個要求前提,要求連接AP設置的網段和靜態的要一致,在不能固定AP網段的情況下,這種方式不可取。
Station模式下的WiFi模塊,有幾個特點,以便用來管理WiFi連接:
1. 當最近使用的可接入點連接斷開,但后面重新可用,那么ESP8266會自動去重新連接它(名詞解析,最近使用的可接入點,就是ESP8266 最后連接的WiFi熱點);
2. 第一點說到的情況,對於ESP8266模塊重新啟動也一樣適用;
3. 這兩點實現的原理就是:ESP8266會把最近使用的可接入點的校驗信息(ssid賬號和psw密碼)會存到flash 存儲中。使用保存在flash中的校驗信息,ESP8266就可以重新連接到最近使用的可接入點,盡管你再次改變代碼燒寫進去,只要你不改變WiFi原來的工作模式和校驗信息(說簡單點就是,如果你燒寫代碼不擦除所有flash空間並且設置了自動連接,那么在仍然是station模式下就會自動連接wifi熱點,不過在這里,博主建議大家在begin之前先調用 WiFi.disconnect(),可以避免一些奇怪的連接問題)
ESP8266WiFiSTA庫
有了前面的理論基礎,那么我們開始詳解一下ESP8266 station模式的專用庫——ESP8266WiFiSTA庫,大家使用的時候不需要 #include <ESP8266WiFiSTA.h>
只需要引入 #include<ESP8266WiFi.h>
首先,對於STA類庫的描述,可以拆分為四個部分:
1. 第一部分方法,和一個接入點(Access Point,wifi熱點)建立連接;
2. 第二部分方法,管理第一部分方法建立的連接;
3. 第三部分方法,提供一些關於這個連接的信息,包括MAC地址、IP地址等;
4. 第四部分方法,提供一些備用方法去連接WiFi-Protected Setup(WPS)以及智能配置方法(SmartConfig)
WiFi.mode(WIFI_STA); //設置模式為STA
第一部分方法——建立連接
語法:
wl_status_t begin(char* ssid, char *password = NULL, int32_t channel = 0, const uint8_t* bssid = NULL,bool connect = true)
//
啟動STA模式,並連接wifi網絡
返回值:wl_status_t wifi狀態
ssid wifi熱點名字
password wifi熱點密碼
channel wifi熱點的通道號,用特定通道通信,可選參數
bssid wifi熱點的mac地址,可選參數
connect bool參數,默認等於true,當設置為false,不會去連接wifi熱點,會建立module保存上面參數
注意點:如果ESP8266模塊之前處於AP模式,那么當你調用begin()有可能進入到STA+softAP模式;當你發現一些操作異常,那么你就檢測一下當前處於什么模式(WiFi.mode());
配置IP地址
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 =(uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000)
local_ip station固定的ip地址
gateway 網關
subnet 子網掩碼
dns1,dns2 可選參數定義域名服務器(dns)的ip地址,這些域名服務器,維護一個域名目錄(如www.google.co.uk),並將它們翻譯成ip地址
返回值: bool值,如果配置成功,返回true;
注意點:有着固定IP配置地址的station,通常會更快連接上網絡,原因是通過DHCP client獲得IP配置這一步被跳過了。如果你把三個參數(local_ip, gateway and subnet)設置為0.0.0.0,那么它會重新啟動DHCP,這時你需要重新連接wifi以拿到最新的IP
第二部分方法——管理連接
bool WiFi.reconnect() 重新連接網絡
返回值:
返回false,意味着ESP8266不處於STA模式或者說Station在此之前沒有連接到一個可接入點
返回true,意味着已經成功重新啟動連接,但是用戶仍應該去檢測網絡連接狀態指導WL_CONNECTED
案例:
WiFi.reconnect();
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
bool disconnect(bool wifioff = false); 斷開網絡連接,設置當前配置SSID和pwd為null
wifioff 可選參數,設置為true,那么就會關閉Station模式
返回值:false or true 返回wl_status_t狀態
注意點:調用該函數將會清掉之前最近一個連接點信息(wifi熱點信息)
對於STA模式下如果出現WiFi賬號密碼正確的前提下仍然連接不上WiFi熱點,可以嘗試在begin方法之前調用該方法。當然,博主建議在begin之前都盡量調用該方法
bool isConnected(); 是否已經連接上網絡
判斷STA模式下是否連接上AP,如果STA連接上AP,那么就返回true
bool setAutoConnect(bool autoConnect); 設置是否自動連接到最近接入點
當電源啟動后,設置ESP8266在STA模式下是否自動連接flash中存儲的AP
autoConnect bool 默認是自動連接
返回值:返回保存狀態 true or false
bool getAutoConnect(); 判斷是否設置了自動連接
返回值:返回自動連接狀態 true or false
bool setAutoReconnect(bool autoReconnect); 設置是否自動重新連接到最近接入點
設置當斷開連接的時候是否自動重連
autoConnect bool
注意點:如果在網絡已經斷開了之后才去設置setAutoReconnect(true),這是無效的
uint8_t waitForConnectResult(); 等待網絡連接結果
等待直到ESP8266連接AP返回結果
返回值:
1.WL_CONNECTED 成功連接
2.WL_NO_SSID_AVAIL 匹配SSID失敗(賬號錯誤)
3.WL_CONNECT_FAILED psw密碼錯誤
4.WL_IDLE_STATUS 當wi-fi正在不同的狀態中變化
5.WL_DISCONNECTED 這個模塊沒有配置STA模式
第三部分方法——連接信息
提供一些關於這個連接的信息,包括MAC地址、IP地址等;
String macAddress(); 獲取本機mac地址
實例:
if (WiFi.status() == WL_CONNECTED)
{
uint8_t macAddr[6];
WiFi.macAddress(macAddr); 獲取本機mac地址
Serial.printf("Connected, mac address: %02x:%02x:%02x:%02x:%02x:%02x\n", macAddr[0], macAddr[1],macAddr[2], macAddr[3], macAddr[4], macAddr[5]);
//Connected, mac address: 5C:CF:7F:08:11:17
}
//實例代碼2 這只是部分代碼 不能直接使用
if (WiFi.status() == WL_CONNECTED)
{
Serial.printf("Connected, mac address: %s\n",
WiFi.macAddress().c_str()); //獲取本機mac地址
//Connected, mac address: 5C:CF:7F:08:11:17
}
IPAddress localIP(); 獲取IP地址
返回ESP8266 STA模式下的IP地址
實例
if (WiFi.status() == WL_CONNECTED)
{
Serial.print("Connected, IP address: ");
Serial.println(WiFi.localIP());
//Connected, IP address: 192.168.1.10
}
IPAddress subnetMask(); 獲取子網掩碼的地址
實例
Serial.print("Subnet mask: ");
Serial.println(WiFi.subnetMask());
//Subnet mask: 255.255.255.0
IPAddress gatewayIP(); 獲取網關地址
實例
Serial.printf("Gataway IP: %s\n", WiFi.gatewayIP().toString().c_str());
//Gataway IP: 192.168.1.9
IPAddress dnsIP(uint8_t dns_no = 0); 獲取dns地址
dns_no dns序列號
實例
Serial.print("DNS #1, #2 IP: ");
WiFi.dnsIP().printTo(Serial);
Serial.print(", ");
WiFi.dnsIP(1).printTo(Serial);
Serial.println();
//DNS #1, #2 IP: 62.179.1.60, 62.179.1.61
String hostname(); 獲取host名字
獲取ESP8266 station DHCP的主機名
設置host名字:
bool hostname(char* aHostname);
bool hostname(const char* aHostname);
bool hostname(String aHostname);
aHostname 最大長度:32
實例
Serial.printf("Default hostname: %s\n", WiFi.hostname().c_str());
WiFi.hostname("Station_Tester_02");
Serial.printf("New hostname: %s\n", WiFi.hostname().c_str());
//Default hostname: ESP_081117
//New hostname: Station_Tester_02
wl_status_t status(); 獲取當前wifi連接狀態
返回wl_status_t中定義的其中一值,wl_status_t在 wl_definitions.h中定義
String SSID() const; 獲取wifi網絡的名字
例子:Serial.printf("SSID: %s\n", WiFi.SSID().c_str());
String psk() 獲取wifi網絡密碼
String BSSIDstr(); 返回當前通信網絡的mac地址--獲取熱點機子的mac地址
實例:
Serial.printf("BSSID: %s\n", WiFi.BSSIDstr().c_str());
//BSSID: 00:1A:70E:C1:68
int32_t RSSI(); 獲取wifi網絡的信號強度,單位是dBm
實例:
Serial.printf("RSSI: %d dBm\n", WiFi.RSSI());
//RSSI: -68 dBm
信號強度說明:
信號強度的值是越大越好,這里說的越大符合數學的邏輯,也就是在負數的情況下,這個數字越小,那么這個值就越大,信號也就越好
dbm含義:dbm是一個純粹的比值,只表示兩個量的相對大小關系。因為Wi-Fi信號的能量通常為mw級,因此業界將Wi-Fi信號大小表示為與1mw的強度比,用dbm來表示
隨着信號的傳播,受到障礙物和距離的影響,能量會逐漸衰弱,因此我們在接收端通常看見的是強度為負的數值,它代表比1mw還弱的能量
#include <ESP8266WiFi.h> //導入庫 #define AP_SSID "jia" //這里改成你的wifi名字 #define AP_PSW "lm654321"//這里改成你的wifi密碼 void setup() { Serial.begin(115200);
WiFi.mode(WIFI_STA); //設置模式為STA delay(2000); Serial.println("setu開始運行"); WiFi.begin(AP_SSID, AP_PSW); //啟動STA模式,並連接wifi網絡 Serial.print(String("連接到:")+AP_SSID); ////判斷網絡狀態是否連接上,沒連接上就延時500ms,並且打出一個點,模擬連接過程 while (WiFi.status() != WL_CONNECTED){ //判斷wifi是否連接成功 delay(500); Serial.print("."); } Serial.println(""); //連接成功后換行 Serial.println("連接的IP地址是:"); Serial.println(WiFi.localIP());//WiFi.localIP() 返回本地的IP地址 Serial.println("setup結束"); } void loop() { }
//statin模式下,配置IP地址,網關地址,子網掩碼,並且打印IP地址 #include <ESP8266WiFi.h> //導入庫 #define AP_SSID "jia" //這里改成你的wifi名字 #define AP_PSW "lm654321"//這里改成你的wifi密碼 IPAddress staticIP(192,168,1,22);//固定IP地址 IPAddress gateway(192,168,1,9);//網關地址 IPAddress subnet(255,255,255,0);//子網掩碼地址 void setup() { Serial.begin(115200); delay(2000); Serial.println("setu開始運行"); WiFi.begin(AP_SSID, AP_PSW); //啟動STA模式,並連接wifi網絡 WiFi.config(staticIP,gateway,subnet);//配置網絡 Serial.print(String("連接到:")+AP_SSID); ////判斷網絡狀態是否連接上,沒連接上就延時500ms,並且打出一個點,模擬連接過程 while (WiFi.status() != WL_CONNECTED){ //判斷wifi是否連接成功 delay(500); Serial.print("."); } Serial.println(""); //連接成功后換行 Serial.println("連接的IP地址是:"); Serial.println(WiFi.localIP());//WiFi.localIP() 返回本地的IP地址 Serial.println("setup結束"); } void loop() { }
//statin模式下,創建一個連接到可接入點(wifi熱點),並且打印station信息 #include <ESP8266WiFi.h> #define AP_SSID "jia" #define AP_PSW "lm654321" void setup() { Serial.begin(115200); delay(2000); Serial.println("setu開始運行"); WiFi.begin(AP_SSID, AP_PSW); WiFi.setAutoConnect(true); //設置是否自動連接到最近接入點 WiFi.setAutoReconnect(true); //設置是否自動重新連接到最近接入點 Serial.print(String("連接到:")+AP_SSID); while (WiFi.status() != WL_CONNECTED){ delay(500); Serial.print("."); } Serial.println(""); Serial.println("網絡信息: "); Serial.println("連接的IP地址是:"); Serial.println(WiFi.localIP()); //獲取本機IP地址 Serial.println(String("mac地址是: ")+WiFi.macAddress().c_str()); // 獲取本機mac地址 //mac地址是: CC:50:E3:60:E3:41 Serial.println(String("子網掩碼地址: ")+WiFi.subnetMask().toString()); //子網掩碼地址: 255.255.255.0 Serial.println(String("網關IP: ")+WiFi.gatewayIP().toString()); //網關IP: 192.168.188.253 Serial.println(String("默認hostname: ")+WiFi.hostname()); WiFi.hostname("host_明哥"); //設置新的hostname Serial.println(String("新的hostname: ")+WiFi.hostname()); //新的hostname: host_明哥 Serial.println(String("WIFI賬號: ")+WiFi.SSID()); //WIFI賬號: jia Serial.println(String("WIFI密碼psk: ")+WiFi.psk()); //WIFI密碼psk: lm654321 Serial.println(String("當前通信網絡的mac地址: ")+WiFi.BSSIDstr());//返回當前通信網絡的mac地址---獲取熱點機子的mac地址 //當前通信網絡的mac地址: 78:D3:8D:CA:6E:28 Serial.println(String("網絡的信號強度: ") + WiFi.RSSI() + " dBm"); //獲取wifi網絡的信號強度,單位是dBm Serial.println("setup結束"); } void loop() { }
天子驕龍
