10.ESP8266WiFiGeneric-基础库

前面介绍到ESP8266WiFi库是包含了很多功能的一个超级库。ESP8266WiFi库不仅仅局限于 ESP8266WiFi.h 和 ESP8266WiFi.cpp 这两个文件,只不过它们是最核心的统一入口。
    而在这些库中,有个8266模块通用库 ESP8266WiFiGeneric库,ESP8266WiFiSTA/ESP8266WiFiAP/ESP8266WiFiScan都会在它的基础上去做一些自己的逻辑(也就是会用到它的一些方法),所以算是比较重要的一个基础库,它包括处理程序来管理wi-fi事件,如连接,断开连接或获得ip,wi-fi模式的变化,管理模块睡眠模式的功能,以ip地址解析的hostName等;
    ESP8266在使用过程中并非会一直如希望般稳定运行的,为了应对这些情况就需要能够了解WiFi状态,并对WiFi突发事件作出响应。

主要包括两类方法:管理wifi事件,与wifi模式相关

管理wifi事件

wifi事件,下面的都是一些wifi事件,当事件发生时如果我们注册了事件的话,就可以获取事件信息

typedef enum WiFiEvent 
{
    WIFI_EVENT_STAMODE_CONNECTED = 0,//STA模式下连接上网络
    WIFI_EVENT_STAMODE_DISCONNECTED,//STA模式下断开网络
    WIFI_EVENT_STAMODE_AUTHMODE_CHANGE,//STA模式下校验模式改变
    WIFI_EVENT_STAMODE_GOT_IP,//STA模式下模块获取到IP地址
    WIFI_EVENT_STAMODE_DHCP_TIMEOUT,//STA模式下DHCP分配IP超时
    WIFI_EVENT_SOFTAPMODE_STACONNECTED,//AP模式下有station连接进来
    WIFI_EVENT_SOFTAPMODE_STADISCONNECTED,//AP模式下有station断开连接
    WIFI_EVENT_SOFTAPMODE_PROBEREQRECVED,//AP模式下收到探针请求
    WIFI_EVENT_MAX,
    WIFI_EVENT_ANY = WIFI_EVENT_MAX,
    WIFI_EVENT_MODE_CHANGE //源码中已经去掉
} WiFiEvent_t;

知道了有哪些事件(WiFiEvent),然后针对性去监听这些事件。当事件发生的时候,我们注册事件处理者(WiFiEventHandler),然后可以获取事件信息。
使用WiFiEventHandler需要先声明,然后注册对应事件并加入事件触发时执行的操作:

//请注意,以下为伪代码,不能运行,注意理解思想即可
//声明事件
WiFiEventHandler event;

//事件触发时处理者
void handler(const WiFiEvent& event)
{
	//TODO 在这里可以获取具体的事件信息
}

//注册事件
event = WiFi.onWiFiEvent(handler);

STA模式下连接上网络

/**
 * 注册事件处理器
 * 事件类型:STA模式下连接上网络
 * @param 事件处理回调函数(函数的入参是 WiFiEventStationModeConnected)
 * @return WiFiEventHandler 
 */
WiFiEventHandler onStationModeConnected(std::function);
//wifi连接的事件信息
// WiFiEventStationModeConnected事件信息
struct WiFiEventStationModeConnected
{
    String ssid;// station的ssid,理解为名字
    uint8 bssid[6];//station的mac地址
    uint8 channel;//station连到的信道
};

STA模式下断开网络

/**
 * 注册事件处理器
 * 事件类型:STA模式下断开网络
 * @param 事件处理回调函数(函数的入参是 WiFiEventStationModeDisconnected)
 * @return WiFiEventHandler 
 */
WiFiEventHandler onStationModeDisconnected(std::function);
// WiFiEventStationModeDisconnected 事件信息
struct WiFiEventStationModeDisconnected
{
    String ssid;// station的ssid,理解为名字
    uint8 bssid[6];//station的mac地址
    WiFiDisconnectReason reason;//断开连接原因
};

//断开连接原因
enum WiFiDisconnectReason 
{
    WIFI_DISCONNECT_REASON_UNSPECIFIED              = 1,
    WIFI_DISCONNECT_REASON_AUTH_EXPIRE              = 2,
    WIFI_DISCONNECT_REASON_AUTH_LEAVE               = 3,
    WIFI_DISCONNECT_REASON_ASSOC_EXPIRE             = 4,
    WIFI_DISCONNECT_REASON_ASSOC_TOOMANY            = 5,
    WIFI_DISCONNECT_REASON_NOT_AUTHED               = 6,
    WIFI_DISCONNECT_REASON_NOT_ASSOCED              = 7,
    WIFI_DISCONNECT_REASON_ASSOC_LEAVE              = 8,
    WIFI_DISCONNECT_REASON_ASSOC_NOT_AUTHED         = 9,
    WIFI_DISCONNECT_REASON_DISASSOC_PWRCAP_BAD      = 10,  /* 11h */
    WIFI_DISCONNECT_REASON_DISASSOC_SUPCHAN_BAD     = 11,  /* 11h */
    WIFI_DISCONNECT_REASON_IE_INVALID               = 13,  /* 11i */
    WIFI_DISCONNECT_REASON_MIC_FAILURE              = 14,  /* 11i */
    WIFI_DISCONNECT_REASON_4WAY_HANDSHAKE_TIMEOUT   = 15,  /* 11i */
    WIFI_DISCONNECT_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16,  /* 11i */
    WIFI_DISCONNECT_REASON_IE_IN_4WAY_DIFFERS       = 17,  /* 11i */
    WIFI_DISCONNECT_REASON_GROUP_CIPHER_INVALID     = 18,  /* 11i */
    WIFI_DISCONNECT_REASON_PAIRWISE_CIPHER_INVALID  = 19,  /* 11i */
    WIFI_DISCONNECT_REASON_AKMP_INVALID             = 20,  /* 11i */
    WIFI_DISCONNECT_REASON_UNSUPP_RSN_IE_VERSION    = 21,  /* 11i */
    WIFI_DISCONNECT_REASON_INVALID_RSN_IE_CAP       = 22,  /* 11i */
    WIFI_DISCONNECT_REASON_802_1X_AUTH_FAILED       = 23,  /* 11i */
    WIFI_DISCONNECT_REASON_CIPHER_SUITE_REJECTED    = 24,  /* 11i */

    WIFI_DISCONNECT_REASON_BEACON_TIMEOUT           = 200,
    WIFI_DISCONNECT_REASON_NO_AP_FOUND              = 201,
    WIFI_DISCONNECT_REASON_AUTH_FAIL                = 202,
    WIFI_DISCONNECT_REASON_ASSOC_FAIL               = 203,
    WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT        = 204,
};

知道了有哪些事件(WiFiEvent),然后针对性去监听这些事件。当事件发生的时候,我们注册事件处理者(WiFiEventHandler),然后可以获取事件信息。
使用WiFiEventHandler需要先声明,然后注册对应事件并加入事件触发时执行的操作:

//请注意,以下为伪代码,不能运行,注意理解思想即可
//声明事件
WiFiEventHandler event;

//事件触发时处理者
void handler(const WiFiEvent& event)
{
	//TODO 在这里可以获取具体的事件信息
}

//注册事件
event = WiFi.onWiFiEvent(handler);

STA模式下校验模式改变

/**
 * 注册事件处理器
 * 事件类型:STA模式下校验模式改变
 * @param 事件处理回调函数(函数的入参是 WiFiEventStationModeAuthModeChanged)
 * @return WiFiEventHandler 
 */
WiFiEventHandler onStationModeAuthModeChanged(std::function); 
//事件信息
// WiFiEventStationModeAuthModeChanged 事件信息
struct WiFiEventStationModeAuthModeChanged
{
    uint8 oldMode;
    uint8 newMode;
};
//验证模式
typedef enum _auth_mode {
    AUTH_OPEN           = 0,
    AUTH_WEP,
    AUTH_WPA_PSK,
    AUTH_WPA2_PSK,
    AUTH_WPA_WPA2_PSK,
    AUTH_MAX
} AUTH_MODE;

STA模式下模块获取到IP地址

/**
 * 注册事件处理器
 * 事件类型:STA模式下模块获取到IP地址
 * @param 事件处理回调函数(函数的入参是 WiFiEventStationModeGotIP)
 * @return WiFiEventHandler 
 */
WiFiEventHandler onStationModeGotIP(std::function);
// WiFiEventStationModeGotIP 事件信息
struct WiFiEventStationModeGotIP
{
    IPAddress ip;//IP地址
    IPAddress mask;//子网掩码
    IPAddress gw;//网关
};

AP模式下有station连接进来

/**
 * 注册事件处理器
 * 事件类型:AP模式下有station连接进来
 * @param 事件处理回调函数(函数的入参是 WiFiEventSoftAPModeStationConnected)
 * @return WiFiEventHandler 
 */
WiFiEventHandler onSoftAPModeStationConnected(std::function);
// WiFiEventSoftAPModeStationConnected 事件信息
struct WiFiEventSoftAPModeStationConnected
{
    uint8 mac[6];//station mac地址
    uint8 aid;// station 名字 
};

AP模式下有station连接断开

/**
 * 注册事件处理器
 * 事件类型:AP模式下有station断开连接
 * @param 事件处理回调函数(函数的入参是 WiFiEventSoftAPModeStationDisconnected)
 * @return WiFiEventHandler 
 */
WiFiEventHandler onSoftAPModeStationDisconnected(std::function);
// WiFiEventSoftAPModeStationDisconnected 事件信息
struct WiFiEventSoftAPModeStationDisconnected
{
    uint8 mac[6];//station mac地址
    uint8 aid;// station 名字 
};

AP模式下收到探针请求

/**
 * 注册事件处理器
 * 事件类型:AP模式下收到探针请求
 * @param 事件处理回调函数(函数的入参是 WiFiEventSoftAPModeProbeRequestReceived)
 * @return WiFiEventHandler 
 */
WiFiEventHandler onSoftAPModeProbeRequestReceived(std::function);

// WiFiEventSoftAPModeStationDisconnected 事件信息
struct WiFiEventSoftAPModeProbeRequestReceived
{
    int rssi;//信号强度
    uint8 mac[6];//mac地址
};

wifi配置模式

是否保存wifi设置到flash中

/**
 * 是否保存wifi设置到flash中
 * @param persistent 该参数设置是否将WiFi参数保存于Flash中,默认为true
 */
void persistent(bool persistent);
/*注意:
    1.该方法设置是否将WiFi参数保存于Flash中,默认为true,即在每次调用 WiFi.begin()、WiFi.softAP()、WiFi.disconnect、WiFi.softAPdisconnect 方法时都会将相关数据写入到Flash中;
    2.如果使用该方法设置为false时,以上动作将不会把数据写入Flash中,仅仅改变内存中的WiFi设置;
*/

设置wifi工作模式

/**
 * 设置wifi工作模式
 * @param WiFiMode_t wifi工作模式
 * @return bool 是否设置成功
 */
bool mode(WiFiMode_t);
//wifi工作模式
typedef enum WiFiMode 
{
    WIFI_OFF = 0, WIFI_STA = 1, WIFI_AP = 2, WIFI_AP_STA = 3
} WiFiMode_t;

获取当前wifi工作模式

/**
 * 获取当前wifi工作模式
 * @return WiFiMode_t 当前wifi工作模式
 */
WiFiMode_t getMode();

设置STA模式

/**
 * 设置为STA模式
 * @param enable true表示使能STA工作模式
 * @return bool 是否设置成功
 */
bool enableSTA(bool enable);

设置为AP模式

/**
 * 设置为AP模式
 * @param enable true表示使能AP工作模式
 * @return bool 是否设置成功
 */
bool enableAP(bool enable);

设置为睡眠模式

/**
 * 设置睡眠模式
 * @param WiFiSleepType_t 睡眠模式
 * @return bool 是否设置成功
 */
bool setSleepMode(WiFiSleepType_t type);
WiFiSleepType_t 睡眠模式:
typedef enum WiFiSleepType
{
    WIFI_NONE_SLEEP = 0,//非睡眠模式 WIFI_LIGHT_SLEEP = 1,//轻度睡眠 
    WIFI_MODEM_SLEEP = 2//深度睡眠
} WiFiSleepType_t;

实例操作

官方实示例

/*
    This sketch shows how to use WiFi event handlers.

    In this example, ESP8266 works in AP mode.
    Three event handlers are demonstrated:
    - station connects to the ESP8266 AP
    - station disconnects from the ESP8266 AP
    - ESP8266 AP receives a probe request from a station
*/

#include <ESP8266WiFi.h>
#include <stdio.h>

const char* ssid     = "ap-ssid";
const char* password = "ap-password";

WiFiEventHandler stationConnectedHandler;
WiFiEventHandler stationDisconnectedHandler;
WiFiEventHandler probeRequestPrintHandler;
WiFiEventHandler probeRequestBlinkHandler;

bool blinkFlag;

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);

  // 不保存任何wifi配置到flash
  WiFi.persistent(false);

  // 建立一个AP
  WiFi.mode(WIFI_AP);
  WiFi.softAP(ssid, password);

  // 注册事件处理器
  // 回调函数会在事件发生时被调用
  // onStationConnected函数会在每一次有station连接时调用
  stationConnectedHandler = WiFi.onSoftAPModeStationConnected(&onStationConnected);
  // onStationDisconnected函数会在每一次有station断开时调用
  stationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(&onStationDisconnected);
  // onProbeRequestPrint和onProbeRequestBlink函数会在每一次收到探针请求时调用
  // onProbeRequestPrint会打印station的mac地址和信号强度到串口监视器
  // onProbeRequestBlink会闪烁LED
  probeRequestPrintHandler = WiFi.onSoftAPModeProbeRequestReceived(&onProbeRequestPrint);
  probeRequestBlinkHandler = WiFi.onSoftAPModeProbeRequestReceived(&onProbeRequestBlink);
}

void onStationConnected(const WiFiEventSoftAPModeStationConnected& evt) {
  Serial.print("Station connected: ");
  Serial.println(macToString(evt.mac));
}

void onStationDisconnected(const WiFiEventSoftAPModeStationDisconnected& evt) {
  Serial.print("Station disconnected: ");
  Serial.println(macToString(evt.mac));
}

void onProbeRequestPrint(const WiFiEventSoftAPModeProbeRequestReceived& evt) {
  Serial.print("Probe request from: ");
  Serial.print(macToString(evt.mac));
  Serial.print(" RSSI: ");
  Serial.println(evt.rssi);
}

void onProbeRequestBlink(const WiFiEventSoftAPModeProbeRequestReceived&) {
  // 我们不能在事件处理函数中调用延时函数或者其他阻塞函数
  // 因此这里设置一个标志位
  blinkFlag = true;
}

void loop() {
  if (millis() > 10000 && probeRequestPrintHandler) {
    // 10s之后,禁止 onProbeRequestPrint
    Serial.println("Not printing probe requests any more (LED should still blink)");
    probeRequestPrintHandler = WiFiEventHandler();
  }
  if (blinkFlag) {
    blinkFlag = false;
    digitalWrite(LED_BUILTIN, LOW);
    delay(100);
    digitalWrite(LED_BUILTIN, HIGH);
  }
  delay(10);
}

String macToString(const unsigned char* mac) {
  char buf[20];
  snprintf(buf, sizeof(buf), "%02x:%02x:%02x:%02x:%02x:%02x",
           mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
  return String(buf);
}

station事件

/**
 * 设置为AP模式
 * @param enable true表示使能AP工作模式
 * @return bool 是否设置成功
 */
bool enableAP(bool enable);

设置为睡眠模式

#include 

const char *ssid = "********";
const char *password = "********";

WiFiEventHandler STAConnected;
WiFiEventHandler STADisconnected;
WiFiEventHandler STAGotIP;

void ConnectedHandler(const WiFiEventStationModeConnected &event)
{
    Serial.println(WiFi.status());
    Serial.println("模块连接到网络");
}

void DisconnectedHandler(const WiFiEventStationModeDisconnected &event)
{
    Serial.println(WiFi.status());
    Serial.println("模块从网络断开");
}

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

    STAConnected = WiFi.onStationModeConnected(ConnectedHandler);
    STADisconnected = WiFi.onStationModeDisconnected(DisconnectedHandler);
    STAGotIP = WiFi.onStationModeGotIP([](const WiFiEventStationModeGotIP &event) {
        Serial.println(WiFi.status());
        Serial.println("模块获得IP");
    });

    WiFi.mode(WIFI_STA);
    WiFi.begin(ssid, password);
    Serial.println(WiFi.status());
}

void loop()
{
    delay(5000); //等待5秒
    WiFi.disconnect(); //断开当前网络连接
}

笔记参考博哥博客,如果对你有帮助,可以给我赞赏哦!

点赞

发表评论

昵称和uid可以选填一个,填邮箱必填(留言回复后将会发邮件给你)
tips:输入uid可以快速获得你的昵称和头像

Title - Artist
0:00