文章目录- 目的
- 建立网络(AP)
- 连接网络(STA)
- 扫描网络
- 通用WiFi方法
- WiFi事件
- 总结
目的
使用ESP32一般是为了它的WiFi功能,使用这块功能最基本的就是建立/连接网络这些基本操作,其它面向用户的网络应用都是建立在这基础上的。
建立网络(AP)
基础使用
建立网络只需两步:
- 引用WiFi库
#include <WiFi.h> ;
- 启动AP网络
WiFi.softAP(ssid) ;
将下面代码上传到模块中:
#include <WiFi.h>
void setup()
{
WiFi.softAP("ESP32_AP_TEST");
}
void loop()
{
}
代码运行后可以搜索到一个名称为ESP32_AP_TEST 的无密码的网络;
默认情况下ESP32建立AP时,模块自身地址为192.168.4.1 ,可以连接到该网络后进行测试;

常用方法说明
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4)
该方法用来启动AP,在成功启动后返回true,各项参数如下:
ssid 所建立AP网络的名称,至少需一个字节,最大一般不超过32字节;
passphrase 所建立AP网络的密码,可以为NULL(无密码)或不小于8字节且不大于63字节的密码;
channel WiFi网络信道,可选值1~13;
ssid_hidden 是否对外隐藏SSID,0-不隐藏,1-隐藏;
max_connection 最大可接入数,可选值1~4;
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)
设置本地地址、网关地址和子网掩码,默认分别为192.168.4.1 192.168.4.1 255.255.255.0 ;
bool softAPdisconnect(bool wifioff = false)
关闭当前AP,若wifioff 为true则还将关闭网络功能;
uint8_t softAPgetStationNum()
返回连接到AP的客户端数量;
IPAddress softAPIP()
返回当前模块IP
const char * softAPgetHostname()
返回主机名字
bool softAPsetHostname(const char * hostname)
设置主机名字
uint8_t* softAPmacAddress(uint8_t* mac)
String softAPmacAddress(void)
返回mac地址
使用示例
使用下面代码进行测试:
#include <WiFi.h>
IPAddress local_IP(192,168,4,22);
IPAddress gateway(192,168,4,22);
IPAddress subnet(255,255,255,0);
const char *ssid = "ESP32_AP_TEST";
const char *password = "12345678";
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.mode(WIFI_AP); //设置工作在AP模式
WiFi.softAPConfig(local_IP, gateway, subnet); //设置AP地址
while(!WiFi.softAP(ssid, password)){}; //启动AP
Serial.println("AP启动成功");
Serial.print("IP address: ");
Serial.println(WiFi.softAPIP()); // 打印IP地址
WiFi.softAPsetHostname("myHostName"); //设置主机名
Serial.print("HostName: ");
Serial.println(WiFi.softAPgetHostname()); //打印主机名
Serial.print("mac Address: ");
Serial.println(WiFi.softAPmacAddress()); //打印mac地址
}
void loop()
{
delay(1000);
Serial.println(WiFi.softAPgetStationNum()); //打印客户端连接数
}

上面测试时用电脑连接了一次该AP网络,然后断开,图中能看得到接入客户端数量的变化;
连接网络(STA)
基础使用
连接到网络也只需要两步:
- 引用WiFi库
#include <WiFi.h> ;
- 连接到网络
WiFi.begin(ssid, password); ;
将下面代码上传到模块中:
#include <WiFi.h>
const char *ssid = "********"; //你的网络名称
const char *password = "********"; //你的网络密码
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.begin(ssid, password); //连接网络
while (WiFi.status() != WL_CONNECTED) //等待网络连接成功
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
Serial.println("IP address: ");
Serial.println(WiFi.localIP()); //打印模块IP
}
void loop()
{
}

常用方法说明
wl_status_t begin(const char* ssid, const char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true)
wl_status_t begin(char* ssid, char *passphrase = NULL, int32_t channel = 0, const uint8_t* bssid = NULL, bool connect = true)
该方法用来接入网络;
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000)
设置网络地址;
bool disconnect(bool wifioff = false, bool eraseap = false)
断开网络连接,若wifioff 为true则还将关闭网络功能,若eraseap 为true则将清除保存于flash中的网络参数;
bool isConnected()
返回是否已接入网络;
bool setAutoReconnect(bool autoReconnect)
设置断网自动重连接;
bool getAutoReconnect()
返回是否自动重连接;
IPAddress localIP()
返回模块地址;
IPAddress subnetMask()
返回子网掩码;
IPAddress gatewayIP()
返回网关地址;
IPAddress dnsIP(uint8_t dns_no = 0)
返回DNS地址;
uint8_t * macAddress(uint8_t* mac)
String macAddress()
返回MAC地址;
const char * getHostname()
返回主机名字;
bool setHostname(const char * hostname)
设置主机名字;
wl_status_t status()
返回联网状态,状态如下:
255:WL_NO_SHIELD 不用在意(兼容WiFi Shield而设计)
0:WL_IDLE_STATUS 正在WiFi工作模式间切换;
1:WL_NO_SSID_AVAIL 无法访问设置的SSID网络;
2:WL_SCAN_COMPLETED 扫描完成;
3:WL_CONNECTED 连接成功;
4:WL_CONNECT_FAILED 连接失败;
5:WL_CONNECTION_LOST 丢失连接;
6:WL_DISCONNECTED 断开连接;
使用示例
使用下面代码进行测试:
#include <WiFi.h>
const char *ssid = "********";
const char *password = "********";
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.mode(WIFI_STA); //设置工作在STA模式
WiFi.begin(ssid, password); //连接网络
while (!WiFi.isConnected()) //等待网络连接成功
{
delay(500);
Serial.print(".");
}
Serial.println("WiFi connected!");
Serial.print("IP address: ");
Serial.println(WiFi.localIP()); //打印模块IP
Serial.print("subnetMask: ");
Serial.println(WiFi.subnetMask()); //打印子网掩码
Serial.print("gateway: ");
Serial.println(WiFi.gatewayIP()); //打印网关地址
Serial.print("dns: ");
Serial.println(WiFi.dnsIP()); //打印DNS地址
Serial.print("mac Address: ");
Serial.println(WiFi.macAddress()); //打印mac地址
WiFi.setHostname("myHostName"); //设置主机名
Serial.print("HostName: ");
Serial.println(WiFi.getHostname()); //打印主机名
Serial.println(WiFi.status());
WiFi.disconnect(); //断开当前网络
delay(1000);
Serial.println(WiFi.status());
}
void loop()
{
}

扫描网络
有时候我们需要先搜索环境中有哪些网络,然后再进行下一步动作。
同步搜索
使用下面代码搜索并打印搜索到的网络信息:
#include <WiFi.h>
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.mode(WIFI_STA); //设置为STA模式
WiFi.disconnect(); //断开当前可能的连接
delay(100);
Serial.println("scan start");
int n = WiFi.scanNetworks(); //扫描并返回搜索到的网络数量,该方法默认会阻塞
Serial.println("scan done");
if (n != 0)
{
Serial.print(n);
Serial.println(" networks found");
for (int i = 0; i < n; ++i)
{
Serial.println();
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i)); //打印网络名称
Serial.print(" ");
Serial.print(WiFi.RSSI(i)); //打印信号强度
Serial.print(" ");
Serial.print((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? "未加密" : "加密"); //打印是否加密
delay(10);
}
}
}
void loop()
{
}

上面示例为同步搜索,同步搜索在执行WiFi.scanNetworks() 语句时会阻塞程序(默认情况下会阻塞约4秒,秒,理论值)。
异步搜索
使用下面代码进行异步搜索,异步搜索不会阻塞程序运行:
#include <WiFi.h>
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.mode(WIFI_STA); //设置为STA模式
WiFi.disconnect(); //断开当前可能的连接
delay(100);
Serial.println("开始扫描");
WiFi.scanNetworks(true); //启动异步扫描
}
void loop()
{
delay(1000);
int n = WiFi.scanComplete(); //获取扫描状态
if (n >= 0)
{
Serial.println("扫描完成");
for (int i = 0; i < 3; ++i)
{
Serial.println();
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i)); //打印网络名称
Serial.print(" ");
Serial.print(WiFi.RSSI(i)); //打印信号强度
Serial.print(" ");
Serial.print((WiFi.encryptionType(i) == WIFI_AUTH_OPEN) ? "未加密" : "加密"); //打印是否加密
delay(10);
}
WiFi.scanDelete(); //清除内存中的扫描结果
}
else if (n == -1)
{
Serial.println("正在扫描");
}
else if (n == -2)
{
Serial.println("未进行扫描");
}
}

常用方法说明
int16_t scanNetworks(bool async = false, bool show_hidden = false, bool passive = false, uint32_t max_ms_per_chan = 300)
启动搜索,各项参数如下:
async:异步扫描,该值为true 时将启动异步扫描,该方法将不阻塞;
show_hidden:是否扫描不广播的网络;
passive:影响扫描速度,该值为true 时扫描速度较快(不确定);
max_ms_per_chan:每通道扫描时间;
int16_t scanComplete()
异步模式下用于获取扫描到的网络数量,如果返回值为-1,表示还在进行扫描,如果返回值为-1,表示未进行扫描或扫描失败;
void scanDelete()
删除内存中的扫描结果;
String SSID(uint8_t networkItem)
返回扫描到的网络名称;
wifi_auth_mode_t encryptionType(uint8_t networkItem)
返回扫描到的网络加密类型;
int32_t RSSI(uint8_t networkItem)
返回扫描到的网络信号强度;
int32_t channel(uint8_t networkItem)
返回扫描到的网络信道号;
通用WiFi方法
int32_t channel()
返回当前信道;
void persistent(bool persistent)
设置是否将WiFi模式、SSID、密码、自动重连等信息存储于flash中,默认为true ;
bool mode(wifi_mode_t)
设置WiFi工作模式,参数可选WIFI_OFF WIFI_STA WIFI_AP WIFI_AP_STA ;
wifi_mode_t getMode()
返回WiFi工作模式;
bool enableSTA(bool enable)
使能/失能STA模式;
bool enableAP(bool enable)
使能/失能AP模式;
bool setSleep(bool enable)
使能/失能休眠(仅STA模式);
bool getSleep()
返回时候开启休眠;
bool setTxPower(wifi_power_t power)
设置WiFi发射功率,默认为WIFI_POWER_19_5dBm(最大值) ;
wifi_power_t getTxPower()
返回WiFi发射功率;
WiFi事件
在网络出现变化时会触发事件,用户可以在事件发生时对不同的情况进行处理。
事件列表
SYSTEM_EVENT_WIFI_READY < ESP32 WiFi ready
SYSTEM_EVENT_SCAN_DONE < ESP32 finish scanning AP
SYSTEM_EVENT_STA_START < ESP32 station start
SYSTEM_EVENT_STA_STOP < ESP32 station stop
SYSTEM_EVENT_STA_CONNECTED < ESP32 station connected to AP
SYSTEM_EVENT_STA_DISCONNECTED < ESP32 station disconnected from AP
SYSTEM_EVENT_STA_AUTHMODE_CHANGE < the auth mode of AP connected by ESP32 station changed
SYSTEM_EVENT_STA_GOT_IP < ESP32 station got IP from connected AP
SYSTEM_EVENT_STA_LOST_IP < ESP32 station lost IP and the IP is reset to 0
SYSTEM_EVENT_STA_WPS_ER_SUCCESS < ESP32 station wps succeeds in enrollee mode
SYSTEM_EVENT_STA_WPS_ER_FAILED < ESP32 station wps fails in enrollee mode
SYSTEM_EVENT_STA_WPS_ER_TIMEOUT < ESP32 station wps timeout in enrollee mode
SYSTEM_EVENT_STA_WPS_ER_PIN < ESP32 station wps pin code in enrollee mode
SYSTEM_EVENT_AP_START < ESP32 soft-AP start
SYSTEM_EVENT_AP_STOP < ESP32 soft-AP stop
SYSTEM_EVENT_AP_STACONNECTED < a station connected to ESP32 soft-AP
SYSTEM_EVENT_AP_STADISCONNECTED < a station disconnected from ESP32 soft-AP
SYSTEM_EVENT_AP_PROBEREQRECVED < Receive probe request packet in soft-AP interface
SYSTEM_EVENT_GOT_IP6 < ESP32 station or ap or ethernet interface v6IP addr is preferred
SYSTEM_EVENT_ETH_START < ESP32 ethernet start
SYSTEM_EVENT_ETH_STOP < ESP32 ethernet stop
SYSTEM_EVENT_ETH_CONNECTED < ESP32 ethernet phy link up
SYSTEM_EVENT_ETH_DISCONNECTED < ESP32 ethernet phy link down
SYSTEM_EVENT_ETH_GOT_IP < ESP32 ethernet got IP from connected AP
SYSTEM_EVENT_MAX
注册及删除
wifi_event_id_t onEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX)
wifi_event_id_t onEvent(WiFiEventFuncCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX)
wifi_event_id_t onEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX)
使用上面方法用来注册事件;
void removeEvent(WiFiEventCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX)
void removeEvent(WiFiEventSysCb cbEvent, system_event_id_t event = SYSTEM_EVENT_MAX)
void removeEvent(wifi_event_id_t id)
使用上面方法用来删除已注册的事件;
使用示例
使用下面代码上传至模块中:
#include <WiFi.h>
const char *ssid = "********";
const char *password = "********";
void myEvent1(WiFiEvent_t event) //事件回调函数
{
switch (event)
{
case SYSTEM_EVENT_STA_CONNECTED:
Serial.println("已连接到网络");
break;
default:
break;
}
}
void myEvent2(WiFiEvent_t event, WiFiEventInfo_t info) //事件回调函数
{
Serial.println("获取到IP");
}
void setup()
{
Serial.begin(115200);
Serial.println();
WiFi.disconnect(true); //关闭网络
WiFi.onEvent(myEvent1); //注册事件方法一
WiFi.onEvent(myEvent2, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP); //注册事件方法二
WiFiEventId_t myEvent3ID = WiFi.onEvent( //注册事件方法三
[](WiFiEvent_t event, WiFiEventInfo_t info) {
Serial.print("网络连接已断开");
},
WiFiEvent_t::SYSTEM_EVENT_STA_DISCONNECTED);
WiFi.mode(WIFI_STA); //设置工作在STA模式
WiFi.begin(ssid, password); //连接网络
while (!WiFi.isConnected()) //等待网络连接成功
{
delay(500);
}
delay(1000);
WiFi.disconnect(); //断开当前网络
//WiFi.removeEvent(myEvent3ID); //删除事件
}
void loop()
{
}

总结
WiFi功能是其它面向用户的网络应用的基础,在学会使用这部分功能后就能够真正开始开发网络应用了。
更多内容参考如下:
https://github.com/espressif/arduino-esp32/tree/master/libraries/WiFi
|