# 7. 联网 Edge101WE 主板 具备以太网和WiFi联网功能,编写联网程序最简单的方法就是根据例程代码来修改。 ## 7.1 以太网MAC ### 7.1.1 以太网方法API #### begin() - 进行以太网接口初始化并启用以太网 **语法** ```c++ bool begin(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :------------------------------: | ---------- | | bool | 初始化成功返回true,失败返回false | true/false | #### config() - 设置IP地址、网关地址、子网掩码、dns地址; **语法** ```c++ bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000); ``` **参数** | 传入值 | 说明 | 值范围 | | :------: | :--------------------: | :-----------------------------------------------: | | local_ip | 设置本机的以太网PI地址 | 示例:192.168.0.100 | | gateway | 网关地址 | 示例:192.168.0.1 | | subnet | 子网掩码 | 示例:255.255.254.0 | | dns1 | dns1地址 | 示例:114.114.114.114,默认:(uint32_t)0x00000000 | | dns2 | dns2地址 | 示例:8.8.8.8,默认:(uint32_t)0x00000000 | **返回** | 返回值 | 说明 | 值范围 | | :----: | :----------------------------: | ---------- | | bool | 配置成功返回true,失败返回false | true/false | #### getHostname() - 获取主机名字 **语法** ```c++ const char * getHostname(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :--------------: | ------------ | | 指针 | 指向主机名的指针 | const char * | #### setHostname() - 设置主机名 **语法** ```c++ bool setHostname(const char * hostname); ``` **参数** | 传入值 | 说明 | 值范围 | | :------: | :----------: | :----------: | | hostname | 主机名首地址 | const char * | **返回** | 返回值 | 说明 | 值范围 | | :----: | :----------------------------: | ---------- | | bool | 配置成功返回true,失败返回false | true/false | #### linkUp() - 检查以太网连接是否正常 **语法** ```c++ bool linkUp(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :------------------------------------: | ---------- | | bool | 连接正常返回true,连接故障失败返回false | true/false | #### linkSpeed() - 获取传输速度,单位Mbps **语法** ```c++ uint8_t linkSpeed(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-----: | :--------------: | ------- | | uint8_t | 速度,单位为Mbps | uint8_t | #### enableIpV6() - 使能IPv6网络 **语法** ```c++ bool enableIpV6(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :----------------------------: | ---------- | | bool | 配置成功返回true,失败返回false | true/false | #### localIPv6() - 获取IPv6地址 **语法** ```c++ IPv6Address localIPv6(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :---------: | :------: | :-----: | | IPv6Address | IPv6地址 | 4个word | #### localIP() - 获取IPv4地址 **语法** ```c++ IPAddress localIP(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :------: | :-----: | | IPAddress | IPv4地址 | 4个word | #### subnetMask() - 获取子网掩码 **语法** ```c++ IPAddress subnetMask(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :------: | :-----: | | IPAddress | 子网掩码 | 4个word | #### gatewayIP() - 获取网关地址 **语法** ```c++ subnetMask(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :------: | :-----: | | IPAddress | 网关地址 | 4个word | #### dnsIP() - 获取dns服务器地址 **语法** ```c++ IPAddress dnsIP(uint8_t dns_no = 0); ``` **参数** | 传入值 | 说明 | 值范围 | | :----: | :---: | :-----: | | dns_no | dns号 | 默认为0 | **返回** | 返回值 | 说明 | 值范围 | | :-------: | :-----------: | :-----: | | IPAddress | dns服务器地址 | 4个word | #### broadcastIP() - 获取广播地址 ```c++ IPAddress broadcastIP(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :------: | :-----: | | IPAddress | 广播地址 | 4个word | #### networkID() - 获取网络ID ```c++ IPAddress networkID(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :----: | :-----: | | IPAddress | 网络ID | 4个word | #### subnetCIDR() - 获取子网网段 ```c++ uint8_t subnetCIDR(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-----: | :------: | :-----: | | uint8_t | 子网网段 | uint8_t | #### macAddress() - 获取MAC地址 ```c++ uint8_t * macAddress(uint8_t* mac); ``` **参数** | 传入值 | 说明 | 值范围 | | :----: | :--------------: | :-------: | | mac | 接收ma地址的地址 | uint8_t * | **返回** | 返回值 | 说明 | 值范围 | | :-----: | :-------------------------------: | --------- | | mac地址 | 这里是返回的没有经过处理的MAC地址 | uint8_t * | #### String macAddress() - 获取MAC地址 ```c++ String macAddress(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :----------------------------------------------------------: | ------ | | String | mac地址,这里是返回的是经过处理的MAC地址,示例:C4:4F:33:40:61:40 | String | ### 以太网示例 #### 例程1:以太网与WiFi的切换 (参考Arduino IDE例程 Examples -> Examples for Edge101WE ->Ethernet\examples\ETH_WiFi) ```c++ /* Switch between Ethernet and WIFI. By default, Ethernet mode is used during power-on. When Ethernet connection timeout is detected, switch to WIFI mode. In WIFI mode, switch to Ethernet mode when an Ethernet connection is detected. */ #include #include const char* ssid = "yourssid"; const char* password = "yourpasswd"; static bool eth_connected = false; bool wifi_mode = false; bool eth_mode = true; uint64_t time_start = 0 ; uint64_t time_connected = 0 ; void WiFiEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: //set eth hostname here ETH.setHostname("esp32-ethernet"); time_start = millis(); break; case ARDUINO_EVENT_ETH_CONNECTED: time_connected = millis(); Serial.println("ETH Connected"); if(wifi_mode){ ESP.restart(); } break; case ARDUINO_EVENT_ETH_GOT_IP: Serial.print("ETH MAC: "); Serial.print(ETH.macAddress()); Serial.print(", IPv4: "); Serial.print(ETH.localIP()); if (ETH.fullDuplex()) { Serial.print(", FULL_DUPLEX"); } Serial.print(", "); Serial.print(ETH.linkSpeed()); Serial.println("Mbps"); eth_connected = true; break; case ARDUINO_EVENT_ETH_DISCONNECTED: Serial.println("ETH Disconnected"); if(!wifi_mode){ ESP.restart(); } eth_connected = false; eth_mode = false; break; case ARDUINO_EVENT_ETH_STOP: Serial.println("ETH Stopped"); eth_connected = false; break; default: break; } } void testClient(const char * host, uint16_t port) { Serial.print("\nconnecting to "); Serial.println(host); WiFiClient client; if (!client.connect(host, port)) { Serial.println("connection failed"); return; } client.printf("GET / HTTP/1.1\r\nHost: %s\r\n\r\n", host); while (client.connected() && !client.available()); while (client.available()) { Serial.write(client.read()); } Serial.println("closing connection\n"); client.stop(); } void setup() { Serial.begin(115200); WiFi.onEvent(WiFiEvent); ETH.begin(); delay(5000); if((millis()-time_start>4000)&&(time_connected==0)){ WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); } Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); wifi_mode = true; } } void loop() { if (eth_connected||wifi_mode) { testClient("baidu.com", 80); } delay(10000); } ``` 修改WiFi的SSID和密码,后将程序烧录到主板。 ```c++ const char* ssid = "yourssid"; const char* password = "yourpasswd"; ``` 将网线连接到 Edge101WE 主板的 以太网接口上,网口的绿色LED亮代表连接好,橙色LED闪烁代表在通信。 此时串口打印以太网连接成功、以太网的MAC地址、IP地址等信息。 然后程序每10秒访问一次 www.baidu.com 并返回获取的数据。 ```html ETH Connected ETH MAC: 08:3A:F2:26:B9:4F, IPv4: 192.168.0.227, FULL_DUPLEX, 1Mbps connecting to baidu.com HTTP/1.1 200 OK Date: Fri, 17 Dec 2021 09:50:06 GMT Server: Apache Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT ETag: "51-47cf7e6ee8400" Accept-Ranges: bytes Content-Length: 81 Cache-Control: max-age=86400 Expires: Sat, 18 Dec 2021 09:50:06 GMT Connection: Keep-Alive Content-Type: text/html closing connection ``` 如果拔下网线,此时显示以太网断开,主板重启,然后通过WiFi方式去联网并访问网址。 ```html ETH Disconnected ets Jul 29 2019 12:21:46 rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT) configsip: 0, SPIWP:0xee clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00 mode:DIO, clock div:1 load:0x3fff0030,len:1252 load:0x40078000,len:12716 load:0x40080400,len:3068 entry 0x400805e4 ........... WiFi connected IP address: 192.168.0.221 connecting to baidu.com HTTP/1.1 200 OK Date: Fri, 17 Dec 2021 09:50:34 GMT Server: Apache Last-Modified: Tue, 12 Jan 2010 13:48:00 GMT ETag: "51-47cf7e6ee8400" Accept-Ranges: bytes Content-Length: 81 Cache-Control: max-age=86400 Expires: Sat, 18 Dec 2021 09:50:34 GMT Connection: Keep-Alive Content-Type: text/html closing connection ``` #### 例程2:以太网UDP通信 (参考Arduino IDE例程 Examples -> Examples for Edge101WE ->Ethernet\examples\UDPClient) ```c++ /* * This sketch sends random data over UDP on a ESP32 device * */ #include #include //IP address to send UDP data to: // either use the ip address of the server or // a network broadcast address const char * udpAddress = "192.168.1.255"; const int udpPort = 3333; //The udp library class WiFiUDP udp; boolean connected = false; #include void Event(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: //Serial.println("ETH Started"); //set eth hostname here ETH.setHostname("esp32-ethernet"); break; case ARDUINO_EVENT_ETH_CONNECTED: //Serial.println("ETH Connected"); break; case ARDUINO_EVENT_ETH_GOT_IP: Serial.print("ETH MAC: "); Serial.print(ETH.macAddress()); Serial.print(", IPv4: "); Serial.print(ETH.localIP()); if (ETH.fullDuplex()) { Serial.print(", FULL_DUPLEX"); } Serial.print(", "); Serial.print(ETH.linkSpeed()); Serial.println("Mbps"); udp.begin(WiFi.localIP(),udpPort); connected = true; break; case ARDUINO_EVENT_ETH_DISCONNECTED: Serial.println("ETH Disconnected"); connected = false; break; case ARDUINO_EVENT_ETH_STOP: Serial.println("ETH Stopped"); connected = false; break; default: break; } } void connectToETH() { WiFi.onEvent(Event); ETH.begin(); Serial.println("Waiting for Ethernet connection..."); } void setup(){ // Initilize hardware serial: Serial.begin(115200); connectToETH(); } void loop(){ //only send data when connected if(connected){ //Send a packet udp.beginPacket(udpAddress,udpPort); udp.printf("Seconds since boot: %lu", millis()/1000); udp.endPacket(); } //Wait for 1 second delay(1000); } ``` 将以上代码烧写到主板中。 **注意:根据实际的网段修改udp地址。** ```c++ const char * udpAddress = "192.168.1.255"; ``` 这里我们使用 [Packet Sender](https://packetsender.com/download#show) 软件进行调试。安装软件后,打开软件,点击File -> Settings,设置使能 UDP Servers,端口号设置为例程中定义的端口号 3333。 点击 OK 保存设置。 ![image-20220127114636836](pictures/image-20220127114636836.png) 回到软件的主菜单,可以看到端口为 3333 的UDP服务器已经打开,并且在接收数据窗口接收到UDP客户端的数据。每秒更新一次。 **注意:如果发现没有数据发送过来,请将电脑的防火墙关闭后再次尝试。** ![image-20220127114715180](pictures/image-20220127114715180.png) #### 例程3:以太网TCP通信 (参考Arduino IDE例程 Examples -> Examples for Edge101WE ->Ethernet\examples\TCPClientBasic) ```c++ /* * In this example, as a TCP client, it sends a piece of data to the server every second and monitors whether the server has sent data once a second. If so, the serial port output. * */ #include #include static bool eth_connected = false; void ETHEvent(WiFiEvent_t event) { switch (event) { case ARDUINO_EVENT_ETH_START: //Serial.println("ETH Started"); //set eth hostname here ETH.setHostname("esp32-ethernet"); break; case ARDUINO_EVENT_ETH_CONNECTED: //Serial.println("ETH Connected"); break; case ARDUINO_EVENT_ETH_GOT_IP: eth_connected = true; break; case ARDUINO_EVENT_ETH_DISCONNECTED: Serial.println("ETH Disconnected"); eth_connected = false; break; case ARDUINO_EVENT_ETH_STOP: Serial.println("ETH Stopped"); eth_connected = false; break; default: break; } } const uint16_t port = 1337; const char * host = "192.168.1.96"; // ip or dns WiFiClient client; void setup() { Serial.begin(115200); delay(10); WiFi.onEvent(ETHEvent); ETH.begin(); Serial.print("Please wait for Ethernet connection"); while(!eth_connected){ delay(1000); Serial.print("."); } Serial.println("succeed"); Serial.print("ETH MAC: "); Serial.print(ETH.macAddress()); Serial.print(", IPv4: "); Serial.print(ETH.localIP()); if (ETH.fullDuplex()) { Serial.print(", FULL_DUPLEX"); } Serial.print(", "); Serial.print(ETH.linkSpeed()); Serial.println("Mbps"); delay(500); Serial.print("Connecting to "); Serial.println(host); while (!client.connect(host, port,5)) { delay(10); } Serial.println("Connection successful"); } void loop() { client.print("Send this data to the server"); if (client.available()>0){ String line = client.readStringUntil('\r'); Serial.println(line); } if(!client.connected()){ Serial.println("The connection has been disconnected and is about to be reconnected."); delay(1000); if (!client.connect(host, port)) { Serial.println("Reconnection failure."); }else{ Serial.println("Reconnection successful."); } } delay(1000); } ``` 打开Packet Sender 软件 点击 File -> Settings,开启TCP Servers,端口号填入例程对应的端口号。点击 OK 保存设置 ![image-20220127134533592](pictures/image-20220127134533592.png) 在软件的主页顶部显示 TCP Servers 的 IP地址 192.168.1.96。 ![image-20220127134821724](pictures/image-20220127134821724.png) 修改例程中的 host IP地址为 TCP Servers的IP,将例子程序烧写到主板。 ```c++ const char * host = "192.168.1.96"; // ip or dns ``` 此时主板串口打印连接成功信息,Packet Sender 每秒钟收到主板发出的 "Send this data to the server" 字符串; **注意:如果发现没有数据发送过来,请将电脑的防火墙关闭后再次尝试。** 在对话串口输入 字符串 “This is Packet Sender speaking.” 点击发送,主板USB串口打印出收到的字符串。 ``` Please wait for Ethernet connectionsucceed ETH MAC: 08:3A:F2:26:B9:63, IPv4: 192.168.1.194, FULL_DUPLEX, 100Mbps Connecting to 192.168.1.96 Connection successful This is Packet Sender speaking. ``` ![image-20220127135405712](pictures/image-20220127135405712.png) UDP 和 TCP 协议的具体讲解请参照第 9 章节 应用层协议。 ## 7.2 WiFi ### 7.2.1 Wi-Fi 功能列表 - 支持仅 station 模式、仅 AP 模式、station/AP 共存模式 - 支持使用 IEEE 802.11B、IEEE 802.11G、IEEE 802.11N 和 API 配置协议模式 - 支持 WPA/WPA2/WPA2-企业版和 WPS - 支持 AMPDU、HT40、QoS 以及其它主要功能 - 支持 Modem-sleep - 支持WiFi MESH协议,可实现 **1 km** 数据通信 - 空中数据传输最高可达 20 MBit/s TCP 吞吐量和 30 MBit/s UDP 吞吐量 - 支持 Sniffer - 支持用于 Wi-Fi 连接的 fast_crypto 算法与普通算法的切换 - 支持快速扫描和全信道扫描 - 支持获取信道状态信息 ### 7.2.2 通用WiFi方法API #### channel() - 返回当前信道 ```c++ int32_t channel() ``` **语法** ```c++ channel = WiFi.channel(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-----: | :------------------------: | :----: | | int32_t | 当前WiFi通信的无线频率信道 | 1~13 | #### persistent() - 设置是否将WiFi模式、SSID、密码、自动重连等信息存储于flash中 ```c++ void persistent(bool persistent) ``` **语法** ```c++ WiFi.persistent(true); ``` **参数** | 传入值 | 说明 | 值范围 | | :-------------: | :----------------------------------------------------------: | :---------: | | bool persistent | 是否将WiFi模式、SSID、密码、自动重连等信息存储于flash中(默认为true,是存储到flash) | true、false | **返回** 无 #### mode() - 设置WiFi工作模式 ```c++ bool mode(wifi_mode_t) ``` **语法** ```c++ WiFi.mode(WIFI_STA); ``` **参数** | 传入值 | 说明 | 值范围 | | :---------: | :----------: | :--------------------------------------: | | wifi_mode_t | WiFi工作模式 | WIFI_OFF、WIFI_STA、WIFI_AP、WIFI_AP_STA | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | **WIFI_OFF:**WiFi 关闭 **WIFI_STA:**STA是 Station 的简称,类似于无线终端,STA本身并不接受无线的接入,它可以连接到 AP,简单来说就是和手机连接 WiFi 热点的工作状态相同,可以连接其它的热点。 ​ **Edge101WE 主板 工作在STA模式下有一下几个特点:** 1. 在连接丢失的情况下,一旦WiFi再次可用,Edge101WE 将自动重新连接到接入点(热点)。 2. 模块重启后Edge101WE存储器中的接入点认证信息(ssid,password是加密保存)连接到接入点。 3. 如果仅仅是修改了和WiFi模式不相干的代码,Edge101WE 主板仍然使用保存到Flash存储器上的认证信息。 **WIFI_AP:**AP 是 Access Point 的简称,提供无线接入服务,是一个无线网络的创建者,是网络的中心节点,允许其它无线终端接入,简单来说就是和路由器在多数情况下的工作模式相同,能让手机接入。Edge101WE 主板可使用AP模式动态修改接入点信息。 **WIFI_AP_STA:**AP 混合 STA 模式,既可以连接到其它的WIFI热点,也可以让别的无线终端连接,这两个过程能**同时**进行。 #### getMode() - 返回WiFi工作模式 ```c++ wifi_mode_t getMode() ``` **语法** ```c++ mode = WiFi.getMode(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :---------: | :--------------: | :--------------------------------------: | | wifi_mode_t | 返回WiFi工作模式 | WIFI_OFF、WIFI_STA、WIFI_AP、WIFI_AP_STA | #### enableSTA() - 使能/失能STA模式 ```c++ bool enableSTA(bool enable) ``` **语法** ```c++ WiFi.enableSTA(true); ``` **参数** | 传入值 | 说明 | 值范围 | | :---------: | :--------------: | :---------: | | bool enable | 使能/失能STA模式 | true、false | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | ----------- | | bool | true:设置成功
false:设置失败 | true、false | #### enableAP() - 使能/失能AP模式 ```c++ bool enableAP(bool enable) ``` **语法** ```c++ WiFi.enableAP(true); ``` **参数** | 传入值 | 说明 | 值范围 | | :---------: | :-------------: | :---------: | | bool enable | 使能/失能AP模式 | true、false | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | ----------- | | bool | true:设置成功
false:设置失败 | true、false | #### setSleep() - 使能/失能休眠 ```c++ bool setSleep(bool enable) ``` **语法** ```c++ WiFi.setSleep(true); ``` **参数** | 传入值 | 说明 | 值范围 | | :---------: | :----------------------------------------------------------: | :---------: | | bool enable | 仅STA模式,默认开启休眠;如果对实时响应要求较高的话需要关闭休眠; | true、false | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | ----------- | | bool | true:设置成功
false:设置失败 | true、false | #### getSleep() - 返回是否开启休眠 ```c++ bool getSleep() ``` **语法** ```c++ WiFi.getSleep(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :-----------------: | ----------- | | bool | 开启休眠,返回 true | true、false | #### setTxPower() - 设置WiFi发射功率 ```c++ bool setTxPower(wifi_power_t power) ``` **语法** ```c++ WiFi.setTxPower(WIFI_POWER_19_5dBm); ``` **参数** | 传入值 | 说明 | 值范围 | | :----------------: | :--------------------------------------------------: | :----------------------------------------------------------: | | wifi_power_t power | 设置WiFi发送功率,默认为WIFI_POWER_19_5dBm(最大值) | WIFI_POWER_19_5dBm
WIFI_POWER_19dBm
WIFI_POWER_18_5dBm
WIFI_POWER_17dBm
WIFI_POWER_15dBm
WIFI_POWER_13dBm
WIFI_POWER_11dBm
WIFI_POWER_8_5dBm
WIFI_POWER_7dBm
WIFI_POWER_5dBm
WIFI_POWER_2dBm
WIFI_POWER_MINUS_1dBm | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | ----------- | | bool | true:设置成功
false:设置失败 | true、false | #### getTxPower() - 返回WiFi发射功率 ```c++ wifi_power_t getTxPower() ``` **语法** ```c++ WiFi.getTxPower(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----------: | :--------------: | ------------------------------------------------------------ | | wifi_power_t | 返回WiFi发送功率 | WIFI_POWER_19_5dBm
WIFI_POWER_19dBm
WIFI_POWER_18_5dBm
WIFI_POWER_17dBm
WIFI_POWER_15dBm
WIFI_POWER_13dBm
WIFI_POWER_11dBm
WIFI_POWER_8_5dBm
WIFI_POWER_7dBm
WIFI_POWER_5dBm
WIFI_POWER_2dBm
WIFI_POWER_MINUS_1dBm | ### 7.2.3 扫描网络API 有时候我们需要先搜索环境中有哪些网络,然后再进行下一步动作。可使用 WiFi Scan 方法实现。 **扫描网络方法** #### scanNetworks() - 启动搜索 ```c++ int16_t scanNetworks(bool async = false, bool show_hidden = false, bool passive = false, uint32_t max_ms_per_chan = 300) ``` **语法** ```c++ WiFi.scanNetworks(); ``` **参数** | 传入值 | 说明 | 值范围 | | :----------------------: | :----------------------------------------------------------: | :----: | | bool async | 异步扫描,该值为true时将启动异步扫描,该方法将不阻塞(默认flash,同步扫描) | | | bool show_hidden | 是否扫描不广播的网络(默认false不扫描不广播网络) | | | bool passive | 影响扫描速度,该值为true时扫描速度较快(不确定) | | | uint32_t max_ms_per_chan | 每通道最大扫描时间,单位毫秒(默认为300毫秒) | | **返回** | 返回值 | 说明 | 值范围 | | :-----: | :------------------: | :----: | | int16_t | 扫描到的WiFi网络数量 | | #### scanComplete() - 异步模式下用于获取扫描到的网络数量 ```c++ int16_t scanComplete() ``` 异步模式下用于获取扫描到的网络数量,如果返回值为-1,表示还在进行扫描,如果返回值为-2,表示未进行扫描或扫描失败; **语法** ```c++ nume = WiFi.scanComplete(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-----: | :----------------------------------------------------------: | :----: | | int16_t | 扫描到的WiFi网络数量(如果未完成扫描,则返回值<0;扫描仍在进行中:**-1** ;未进行扫描或扫描失败:**-2**) | | #### scanDelete() - 删除内存中的扫描结果 ```c++ void scanDelete() ``` **语法** ```c++ WiFi.scanDelete(); ``` **参数** 无 **返回** 无 #### SSID() - 返回扫描到的网络名称 ```c++ String SSID(uint8_t networkItem) ``` **语法** ```c++ Serial.println(WiFi.SSID(i)); if (WiFi.SSID(i) == "anny"){} Serial.printf("SSID:%s", WiFi.SSID().c_str()); ``` **参数** | 传入值 | 说明 | 值范围 | | :-----------------: | :----------: | :----: | | uint8_t networkItem | WiFi网络编号 | | **返回** | 返回值 | 说明 | 值范围 | | :----: | :------------------: | :----: | | String | 返回扫描到的网络名称 | | #### encryptionType() - 返回扫描到的网络加密类型 ```c++ wifi_auth_mode_t encryptionType(uint8_t networkItem) ``` **语法** ```c++ Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? "未加密" : "加密"); ``` **参数** | 传入值 | 说明 | 值范围 | | :-----------------: | :----------: | :----: | | uint8_t networkItem | WiFi网络编号 | | **返回** | 返回值 | 说明 | 值范围 | | :--------------: | :------: | :----------------------------------------------------------: | | wifi_auth_mode_t | 加密类型 | WIFI_AUTH_OPEN
WIFI_AUTH_WEP
WIFI_AUTH_WPA_PSK
WIFI_AUTH_WPA2_PSK
WIFI_AUTH_WPA_WPA2_PSK
WIFI_AUTH_WPA2_ENTERPRISE | **wifi_auth_mode_t 内容包含:** • WIFI_AUTH_OPEN - 没有安全性。 • WIFI_AUTH_WEP - WEP安全性。 • WIFI_AUTH_WPA_PSK - WPA安全性。 • WIFI_AUTH_WPA2_PSK - WPA2安全。 • WIFI_AUTH_WPA_WPA2_PSK - WPA或WPA2安全性。 • WIFI_AUTH_WPA2_ENTERPRISE - WPA2_ENTERPRISE安全性。 #### RSSI() - 返回扫描到的网络信号强度 ```c++ int32_t RSSI(uint8_t networkItem) ``` **语法** ```c++ Serial.println(WiFi.RSSI(i)); ``` **参数** | 传入值 | 说明 | 值范围 | | :-----------------: | :----------: | :----: | | uint8_t networkItem | WiFi网络编号 | | **返回** | 返回值 | 说明 | 值范围 | | :-----: | :----------: | :----: | | int32_t | 网络信号强度 | | #### channel() - 返回扫描到的网络信道号 ```c++ int32_t channel(uint8_t networkItem) ``` **语法** ```c++ Serial.println(WiFi.channel(i)); ``` **参数** | 传入值 | 说明 | 值范围 | | :-----------------: | :----------: | :----: | | uint8_t networkItem | WiFi网络编号 | | **返回** | 返回值 | 说明 | 值范围 | | :-------------: | :--------------------: | :----: | | int32_t channel | 返回扫描到的网络信道号 | 1 ~ 13 | ### 例程:WiFi Scan 同步搜索 这个功能默认在阻塞模式下运行,程序会扫描WiFi,期间什么事情都做不了,可以通过参数设置改为异步模式。 例程首先将 WiFi 置于 station 工作模式,如果设备处于 AP 工作模式下,且正被其他设备连接,将会断开连接。 然后调用 WiFi.scanNetworks() 扫描WiFi。如果扫描到网络将网络信息打印出来。 (参考Arduino IDE例程 Examples -> Examples for Edge101WE ->WiFi\examples\WiFiScan) ```c++ /* * This sketch demonstrates how to scan WiFi networks. * The API is almost the same as with the WiFi Shield library, * the most obvious difference being the different file you need to include: */ #include "WiFi.h" void setup() { Serial.begin(115200); // Set WiFi to station mode and disconnect from an AP if it was previously connected //将WiFi置于station工作模式,如果设备处于AP工作模式下,且正被其他设备连接,将会断开连接 WiFi.mode(WIFI_STA); //设置为Station模式 WiFi.disconnect(); //断开当前连接 delay(100); Serial.println("Setup done"); } void loop() { Serial.println("scan start"); // WiFi.scanNetworks will return the number of networks found //WiFi.scanNetworks()函数会返回已发现网络数量 int n = WiFi.scanNetworks(); Serial.println("scan done"); if (n == 0) { Serial.println("no networks found"); } else { Serial.print(n); Serial.println(" networks found"); for (int i = 0; i < n; ++i) { // Print SSID and RSSI for each network found //为每个网络打印其SSID(Service Set Identifier 服务集标识) //RSSI(Received Signal Strength Indication 信号强度) Serial.print(i + 1); Serial.print(": "); Serial.print(WiFi.SSID(i)); Serial.print(" ("); Serial.print(WiFi.RSSI(i)); Serial.print(")"); //AUTH:Authentication 认证 //WIFI_AUTH_OPEN 没有认证(不需要wifi密码) //这段语句意思:如果需要密码才能连接就打印"*",否则空格 Serial.println((WiFi.encryptionType(i) == WIFI_AUTH_OPEN)?" ":"*"); delay(10); } } Serial.println(""); // Wait a bit before scanning again delay(5000); } ``` **wifi_auth_mode_t 内容包含:** • WIFI_AUTH_OPEN - 没有安全性。 • WIFI_AUTH_WEP - WEP安全性。 • WIFI_AUTH_WPA_PSK - WPA安全性。 • WIFI_AUTH_WPA2_PSK - WPA2安全。 • WIFI_AUTH_WPA_WPA2_PSK - WPA或WPA2安全性。 • WIFI_AUTH_WPA2_ENTERPRISE - WPA2_ENTERPRISE安全性。 从串口打印出扫描到的 WiFi ``` Setup done scan start scan done 17 networks found 1: dfrobotGuest (-60)* 2: dfrobotOffice (-62)* 3: dfrobotGuest (-64)* 4: dfrobotOffice (-64)* 5: dfrobotOffice (-66)* 6: dfrobotGuest (-66)* 7: hitest (-66)* 8: ChinaNet-Qip4 (-70)* 9: research (-77)* 10: DIRECT-D38F7640 (-83)* 11: dfrobotOffice (-84)* 12: dfrobotGuest (-87)* 13: dfrobotOffice (-89)* 14: Tenda_2E2950 (-90) 15: TP-LINK_8FED (-90)* 16: ChinaNet-djR7 (-94)* ``` ### 例程:异步搜索 使用下面代码进行异步搜索,异步搜索不会阻塞程序运行。代码在初始化时启动异步扫描。在主循环获取扫描状态,如果 WiFi.scanComplete() 返回值大于0,说明有扫描到 WiFi 网络,此时打印一次扫描到的 WiFi 网络。 ```c++ #include void setup() { Serial.begin(115200); Serial.println(); WiFi.mode(WIFI_STA); //设置为STA模式 WiFi.disconnect(); //断开当前可能的连接 delay(100); Serial.println("scan start"); WiFi.scanNetworks(true); //启动异步扫描 } void loop() { delay(1000); int n = WiFi.scanComplete(); //获取扫描状态 if (n >= 0) { Serial.println("scan done"); 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) ? "unencrypted" : "encrypted"); //打印是否加密 delay(10); } WiFi.scanDelete(); //清除内存中的扫描结果 } else if (n == -1) { Serial.println("Scanning"); } else if (n == -2) { Serial.println("No scanning"); } } ``` 串口打印结果 ``` scan start Scanning Scanning Scanning Scanning scan done 1: dfrobotOffice -53 encrypted 2: dfrobotGuest -53 encrypted 3: hitest -59 encrypted 4: dfrobotOffice -62 encrypted 5: dfrobotGuest -63 encrypted 6: dfrobotGuest -64 encrypted 7: dfrobotOffice -64 encrypted 8: ChinaNet-Qip4 -66 encrypted 9: research -73 encrypted 10: dfrobotGuest -82 encrypted 11: DIRECT-D38F7640 -83 encrypted 12: dfrobotOffice -83 encrypted 13: TP-LINK_KHYC -86 encrypted 14: YUXUAN -88 encrypted 15: TP-LINK_8FED -93 encrypted No scanning No scanning ``` ### 例程:扫描并连接WiFi(同步方式) 程序扫描一次 WiFi 网络,将扫描到的 WiFi 网络信息打印出来,如果有扫描到代码匹配的网络,将 SSID 和密码作为 WiFi.begin() 连接的参数。 ```c++ #include #include "WiFi.h" String ssid; String password; void setup() { Serial.begin(115200); WiFi.mode(WIFI_MODE_STA); WiFi.disconnect(); //断开可能的连接 delay(100); Serial.println("scan start:"); int n = WiFi.scanNetworks(); if (n) { Serial.print("Scan to"); 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 encryption or not:"); Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? "unencrypted" : "encrypted"); if (WiFi.SSID(i) == "your_SSID") // 修改为连接WiFi网络SSID { ssid = WiFi.SSID(i); password = "your_password"; // 修改为连接WiFi网络密码 } } } else { Serial.println("No WiFi signal scanned"); } WiFi.begin(ssid.c_str(), password.c_str()); while (!WiFi.isConnected()) { Serial.println("."); } Serial.println("Connection succeeded"); } void loop() { } ``` ### 例程:扫描并连接WiFi(异步方式) 采用异步扫描方式, 每隔0.5秒询问一下WiFi.scanComplete(); 判断是否扫描完毕。 如果扫描完毕,置标志位,停定时器。 触发连接程序, 连接完成后 ```cpp #include #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("scanning..."); break; case -2: Serial.println("No scanning"); break; default: Serial.println("scan done"); 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 encryption or not:"); Serial.println(WiFi.encryptionType(i) == WIFI_AUTH_OPEN ? "unencrypted" : "encrypted"); if (WiFi.SSID(i) == "your_SSID") // 修改为连接WiFi网络SSID { ssid = WiFi.SSID(i); password = "your_password"; // 修改为连接WiFi网络密码 }; } WiFi.scanDelete(); t1.detach(); break; } } } void connectAnny() { WiFi.begin(); while (!WiFi.isConnected()) { Serial.println("."); } Serial.println("Connection succeeded"); } void setup() { Serial.begin(115200); WiFi.mode(WIFI_MODE_STA); WiFi.disconnect(); //断开可能的连接 delay(100); Serial.println("scan start:"); WiFi.scanNetworks(true); t1.attach(0.5, aysncScanHandler); } void loop() { if (!WiFi.isConnected()) { if (ssid == "your_SSID") // 修改为连接WiFi网络SSID { Serial.println(ssid); connectAnny(); } } } ``` ### 7.2.4 建立网络(AP) **建立网络需要两步:** 引用WiFi库 #include ; 启动AP网络 WiFi.softAP(ssid); #### AP方式 ##### softAP() - 启动AP ```c++ bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4) ``` 该方法用来启动AP,在成功启动后返回true。 **语法** ```c++ WiFi.softAP(“myFireBeetleMESH”,“12345678”); ``` **参数** | 传入值 | 说明 | 值范围 | | :------------: | :-----------------------------------------: | :----------------------------------: | | ssid | 所建立AP网络的名称 | 至少需一个字节,最大一般不超过32字节 | | passphrase | 所建立AP网络的密码,默认为 NULL (无密码) | 不小于8字节且不大于63字节的密码 | | channel | WiFi网络信道(默认为1) | 1~13 | | ssid_hidden | 是否对外隐藏SSID,0-不隐藏,1-隐藏 | 0、1 | | max_connection | 最大可接入数(默认为4) | 1~4 | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | ##### softAPConfig() - 设置本地地址、网关地址和子网掩码 ```c++ bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet) ``` 设置本地地址、网关地址和子网掩码,默认分别为192.168.4.1 192.168.4.1 255.255.255.0; **语法** ```c++ WiFi.softAPConfig(IPAddress(192,168,4,1), IPAddress(192,168,4,1), IPAddress(255,255,255,0)); 或者 IPAddress local_IP(192,168,4,22); IPAddress gateway(192, 168,4,9); IPAddress subnet(255,255,255,0); WiFi.softAPConfig(local_IP, gateway, subnet); ``` **参数** | 传入值 | 说明 | 值范围 | | :----------------: | :--------------------------------------------: | :----: | | IPAddress local_ip | 所建立AP网络的IP地址(默认为192.168.4.1) | | | IPAddress gateway | 所建立AP网络的网关(默认为192.168.4.1) | | | IPAddress subnet | 所建立AP网络的子网掩码(默认为 255.255.255.0) | | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | ##### softAPdisconnect() - 关闭当前AP ```c++ bool softAPdisconnect(bool wifioff = false) ``` 关闭当前AP,若wifioff为true则还将还原网络设置。 **语法** ```c++ WiFi.softAPdisconnect(); ``` **参数** | 传入值 | 说明 | 值范围 | | :----------: | :--------------------------------: | :---------: | | bool wifioff | 关闭当前AP(默认true,关闭当前AP) | true、false | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | ##### softAPgetStationNum() - 返回连接到AP的客户端数量 ```c++ uint8_t softAPgetStationNum() ``` 返回连接到AP的客户端数量。 **语法** ```c++ num = WiFi.softAPgetStationNum(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-----: | :------------------: | :----: | | uint8_t | 连接到AP的客户端数量 | 1 ~ 4 | ##### softAPIP() - 返回当前IP ```c++ IPAddress softAPIP() ``` **语法** ```c++ IPAddress IP; IP = WiFi.softAPIP(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :----: | :----: | | IPAddress | 当前IP | | ##### softAPgetHostname() - 返回主机名字 ```c++ const char * softAPgetHostname() ``` 主机名字是标识子网中的某台主机。 **语法** ```c++ hostName = WiFi.softAPgetHostname(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----------: | :------: | :----: | | const char * | 主机名字 | | ##### softAPsetHostname() - 设置主机名字 ```c++ bool softAPsetHostname(const char * hostname) ``` **语法** ```c++ WiFi.softAPsetHostname("FireBeetleMESH"); ``` **参数** | 传入值 | 说明 | 值范围 | | :-------------------: | :------: | :----: | | const char * hostname | 主机名字 | | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | ##### softAPmacAddress() - 返回mac地址 ```c++ uint8_t* softAPmacAddress(uint8_t* mac) String softAPmacAddress(void) ``` **语法** ```c++ mac = WiFi.softAPmacAddress(); ``` **参数** | 传入值 | 说明 | 值范围 | | :----------: | :---------------------------------------------: | :----: | | uint8_t* mac | 指向长度为WL_MAC_ADDR_LENGTH的uint8_t数组的指针 | | **返回** | 返回值 | 说明 | 值范围 | | :------: | :---------------: | :----: | | uint8_t* | uint8_t数组的指针 | | | String | 返回字符串 | | ##### softAPBroadcastIP() - 获取主机广播IP ```c++ IPAddress softAPBroadcastIP() ``` **语法** ```c++ Serial.println(WiFiAP.softAPBroadcastIP()); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :--------: | :----: | | | 主机广播IP | | ##### softAPenableIpV6() - 使能IPV6 ```c++ bool softAPenableIpV6() ``` **语法** ```c++ WiFi.softAPenableIpV6(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :----: | | bool | true:设置成功
false:设置失败 | | ##### softAPIPv6() - 获取主机IPV6的IP ```c++ IPv6Address softAPIPv6() ``` **语法** ```c++ Serial.println(WiFi.softAPIPv6()); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :---------: | :----------: | :----: | | IPv6Address | 主机IPv6地址 | | ##### softAPNetworkID() - 获取主机网络ID ```c++ IPAddress softAPNetworkID() ``` 主机网络ID( NetworkID )标识Internet上的一个子网。 Network ID = (IP) & (Subnet Mask) **语法** ```c++ Serial.println(WiFiAP.softAPNetworkID()); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :--------: | :----: | | | 主机网络ID | | ##### softAPSubnetCIDR() - 获取子网CIDR(无分类域间路由)位数 ```c++ uint8_t softAPSubnetCIDR() ``` 子网无分类域间路由CIDR ( Classless Inter-Domain Routing ) 根据子网掩码( Subnet Mask )返回CIDR位数。 例如子网掩码是255.255.255.0,那么将会返回24。 **语法** ```c++ Serial.println(WiFiAP.softAPSubnetCIDR()); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :-----------------------------------------------------: | :----: | | | CIDR位数。例如子网掩码是255.255.255.0,那么将会返回24。 | | #### 例程:建立AP,并将电脑WiFi连接到这个AP,然后使用ping命令测试是否连接。 ```c++ #include ; IPAddress local_IP(192,168,4,1); IPAddress gateway(192,168,4,1); IPAddress subnet(255,255,255,0); const char *ssid = "Edge101WE_softAP_01"; const char *password = "12345678"; void setup() { Serial.begin(115200); Serial.println(); WiFi.disconnect(); // 设置WiFi前先确保断开连接 Serial.print("Setting soft-AP configuration ... "); Serial.println(WiFi.softAPConfig(local_IP, gateway, subnet) ? "Ready" : "Failed!"); Serial.print("Setting Edge101WE_softAP ... "); Serial.println(WiFi.softAP(ssid, password) ? "Ready" : "Failed!"); Serial.print("Soft-AP IP address = "); Serial.println(WiFi.softAPIP()); WiFi.softAPsetHostname("Edge101WE"); //设置主机名 } void loop() { Serial.print("Host name:"); // 主机名 Serial.println(WiFi.softAPgetHostname()); Serial.print("softAP IP:"); // AP主机IP Serial.println(WiFi.softAPIP()); Serial.print("Broadcast IP:");// 主机广播IP Serial.println(WiFi.softAPBroadcastIP()); Serial.print("MAC Address:"); // 主机mac地址 Serial.println(WiFi.softAPmacAddress()); Serial.print("Get Station Number:"); // 主机连接个数 Serial.println(WiFi.softAPgetStationNum()); Serial.print("Network ID:"); // 主机网络ID Serial.println(WiFi.softAPNetworkID()); Serial.println("-------------------------------------------"); delay(1000); } ``` 在串口打印出AP的基本信息: ``` Host name:Edge101WE softAP IP:192.168.4.1 Broadcast IP:192.168.4.255 MAC Address:08:3A:F2:26:B9:4D Get Station Number:0 Network ID:192.168.4.0 ------------------------------------------- ``` 通过Windows CMD命令行 执行 ping 192.168.4.1测试连接。 ![image-20211220135259859](./pictures/image-20211220135259859.png) #### 例程:创建WiFi AP并在其上提供web服务器 (参考Arduino IDE例程 Examples -> Examples for Edge101WE ->WiFi\examples\WiFiAccessPoint) 操作步骤: 1. 连接到接入点“Edge101WE_AP_01” 2. web浏览器访问 http://192.168.4.1/H 将点亮主板上用户LED灯,访问 http://192.168.4.1/L 将关闭用户LED灯,或者在PuTTY终端上运行原始TCP“GET/H”和“GET/L”,IP地址为192.168.4.1,端口为80。 ```c++ /* WiFiAccessPoint.ino creates a WiFi access point and provides a web server on it. Steps: 1. Connect to the access point "Edge101WE_AP_01" 2. Point your web browser to http://192.168.4.1/H to turn the LED on or http://192.168.4.1/L to turn it off OR Run raw TCP "GET /H" and "GET /L" on PuTTY terminal with 192.168.4.1 as IP address and 80 as port Created for arduino-esp32 on 04 July, 2018 by Elochukwu Ifediora (fedy0) */ #include #include #include #define LED_BUILTIN 15 // Set the GPIO pin where you connected your test LED or comment this line out if your dev board has a built-in LED // Set these to your desired credentials. const char *ssid = "Edge101WE_AP_01"; const char *password = "12345678"; WiFiServer server(80); void setup() { pinMode(LED_BUILTIN, OUTPUT); Serial.begin(115200); Serial.println(); Serial.println("Configuring access point..."); // You can remove the password parameter if you want the AP to be open. WiFi.softAP(ssid, password); IPAddress myIP = WiFi.softAPIP(); Serial.print("AP IP address: "); Serial.println(myIP); server.begin(); Serial.println("Server started"); } void loop() { WiFiClient client = server.available(); // listen for incoming clients if (client) { // if you get a client, Serial.println("New Client."); // print a message out the serial port String currentLine = ""; // make a String to hold incoming data from the client while (client.connected()) { // loop while the client's connected if (client.available()) { // if there's bytes to read from the client, char c = client.read(); // read a byte, then Serial.write(c); // print it out the serial monitor if (c == '\n') { // if the byte is a newline character // if the current line is blank, you got two newline characters in a row. // that's the end of the client HTTP request, so send a response: if (currentLine.length() == 0) { // HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK) // and a content-type so the client knows what's coming, then a blank line: client.println("HTTP/1.1 200 OK"); client.println("Content-type:text/html"); client.println(); // the content of the HTTP response follows the header: client.print("Click here to turn ON the LED.
"); client.print("Click here to turn OFF the LED.
"); // The HTTP response ends with another blank line: client.println(); // break out of the while loop: break; } else { // if you got a newline, then clear currentLine: currentLine = ""; } } else if (c != '\r') { // if you got anything else but a carriage return character, currentLine += c; // add it to the end of the currentLine } // Check to see if the client request was "GET /H" or "GET /L": if (currentLine.endsWith("GET /H")) { digitalWrite(LED_BUILTIN, HIGH); // GET /H turns the LED on } if (currentLine.endsWith("GET /L")) { digitalWrite(LED_BUILTIN, LOW); // GET /L turns the LED off } } } // close the connection: client.stop(); Serial.println("Client Disconnected."); } } ``` ### 7.2.5 连接网络(STA) **连接到网络需要两步:** 引用WiFi库 #include ; 连接到网络 WiFi.begin(ssid, password); #### API参考 ##### begin() - 接入网络 ```c++ 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) ``` 该方法用来接入网络; **语法** ```c++ WiFi.begin("your_ssid","your_password"); ``` **参数** | 传入值 | 说明 | 值范围 | | :------------------------------: | :------: | :----: | | const char* ssid 或 char* ssid | ssid | | | const char *passphrase | 密码 | | | int32_t channel | WiFi通道 | | | const uint8_t* bssid | | | | bool connect | 是否连接 | | **返回** | 返回值 | 说明 | 值范围 | | :---------: | :---------------: | :----------------------------------------------------------- | | wl_status_t | uint8_t数组的指针 | 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断开连接; | ##### config() - 设置网络地址 ```c++ bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000) ``` **语法** ```c++ WiFi.config(IPAddress(192,168,4,1), IPAddress(192,168,4,1), IPAddress(255,255,255,0)); 或者 IPAddress local_IP(192,168,4,22); IPAddress gateway(192, 168,4,9); IPAddress subnet(255,255,255,0); WiFi.config(local_IP, gateway, subnet); ``` **参数** | 传入值 | 说明 | 值范围 | | :----------------: | :------------------------------: | :----: | | IPAddress local_ip | IP地址(默认为192.168.4.1) | | | IPAddress gateway | 网关(默认为192.168.4.1) | | | IPAddress subnet | 子网掩码(默认为 255.255.255.0) | | | IPAddress dns1 | | | | IPAddress dns2 | | | **返回值** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | ##### reconnect () - 重连 ```c++ bool reconnect () ``` **语法** ```c++ WiFi.reconnect(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | ##### disconnect() - 断开网络连接 ```c++ bool disconnect(bool wifioff = false, bool eraseap = false) ``` 断开网络连接,若wifioff为true则还将还原网络设置,若eraseap为true则将清除保存于flash中的网络参数; **语法** ```c++ WiFi.disconnect(); ``` **参数** | 传入值 | 说明 | 值范围 | | :----------: | :--------------------------------------------------: | :---------: | | bool wifioff | 关闭当前AP(默认true,关闭当前AP) | true、false | | bool eraseap | 是否清除保存于flash中的网络参数(默认false,不清除) | true、false | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | **例程:WiFi断开重连** 应该在loop函数中持续判断WiFi是否连接成功,如果连接断开可以重新连接,或者使用 ``ESP.restart()``对主控进行复位重新连接。 ```c++ #include const char* ssid = "your_ssid"; const char* password = "your_password"; unsigned long previousMillis = 0; unsigned long interval = 30000; void setup() { Serial.begin(115200); WiFi.mode(WIFI_STA); WiFi.begin(ssid, password); Serial.print("Connecting to WiFi .."); while (WiFi.status() != WL_CONNECTED) { Serial.print('.'); delay(1000); } Serial.println(WiFi.localIP()); Serial.print("RRSI: "); Serial.println(WiFi.RSSI()); } void loop() { unsigned long currentMillis = millis(); // 如果WiFi连接失败将立即进行一次重连,如果30秒后还没有连接成功将再次重连 if ((WiFi.status() != WL_CONNECTED) && (currentMillis - previousMillis >=interval)) { Serial.print(millis()); Serial.println("Reconnecting to WiFi..."); WiFi.disconnect(); WiFi.reconnect(); previousMillis = currentMillis; } } ``` ##### isConnected() - 返回是否已接入网络 ```c++ bool isConnected() ``` 也可以通过 ``WiFi.status() != WL_CONNECTED``进行判断 **语法** ```c++ while (!WiFi.isConnected()) //等待网络连接成功 { delay(500); Serial.print("."); } ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | ------------------------------------- | :---------: | | bool | true:连接网络
false:未连接网络 | true、false | ##### setAutoConnect() - 设置为自动连接模式 ```c++ bool setAutoConnect (bool autoConnect) ``` Configure mainboard to automatically connect on power on to the last used access point 自动连接模式激活后,主板会在通电后自动连接到最后连接过的WiFi接入点。 **语法** ```c++ wiFi.setAutoConnect() wiFi.setAutoConnect(autoConnect) ``` **参数** | 传入值 | 说明 | 值范围 | | :---------: | :----------------------------------------------------------: | :---------: | | autoConnect | autoConnect是一个可选的参数。如果设置为false,则将禁用自动连接功能。
如果省略或设置为true,则将启用自动连接模式。 | true、false | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | **例程:设置自动连接模式** 程序首先连接上WiFi,然后执行设置自动连接模式。如果连接到的AP断开后重启,主板将自动重新尝试连接AP ```c++ #include const char* ssid = "your_ssid"; const char* password = "your_password"; bool autoConnect = true; int i = 0; // 用来判定连接是否超时的累加量 void setup(void) { // 启动串口通讯,波特率设置为115200 Serial.begin(115200); // 设置自动连接 WiFi.setAutoConnect(autoConnect); // 启用自动连接。 Serial.println("set AutoConnect"); // 调用 WiFi.begin()函数,开始连接接入点 WiFi.begin(ssid, password); Serial.println("Connecting Wifi..."); // 这里的循环用来判断是否连接成功的。连接过程中每隔500毫秒会检查一次是否连接成功,,并打一个点表示正在连接中 // 连接成功后会给出提示,但是若60秒后还是没有连接上,则会提示超时,此时主板重启 while (WiFi.status() != WL_CONNECTED) { i++; delay(500); Serial.print("."); if (i > 120) { // 60秒后如果还是连接不上,就判定为连接超时,此时主板重启 Serial.print("Connection timeout! Please check the network, the motherboard will restart"); ESP.restart(); } } } void loop(){ if (WiFi.status() == WL_CONNECTED) { Serial.println("WiFi connected"); Serial.print("WiFi SSID: "); // 串口打印出连接WiFi SSID Serial.println(WiFi.SSID()); Serial.print("IP address: "); // 串口打印出连接IP 地址 Serial.println(WiFi.localIP()); } else { Serial.println("WiFi disconnected"); } delay(1000); } ``` 串口打印结果如下,连接到手机的AP热点,串口打印connected和IP地址,此时关闭手机热点,串口打印 disconnected。如果重新打开手机热点,主板将重新连接到手机的热点,并打印出IP地址。 ``` set AutoConnect Connecting Wifi... .....WiFi connected WiFi SSID: bobophone IP address: 192.168.43.37 WiFi connected WiFi SSID: bobophone IP address: 192.168.43.37 WiFi disconnected WiFi disconnected WiFi connected WiFi SSID: bobophone IP address: 192.168.43.37 ``` ##### getAutoConnect() - 获取是否设置为自动连接 ```c++ bool getAutoConnect () ``` **语法** ```c++ if (WiFi.getAutoConnect() == true) { Serial.println("Automatic connection is set"); } ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :------------------------------------------------------ | :---------: | | bool | true:开启了自动连接功能
false:禁用了自动连接功能 | true、false | ##### setAutoReconnect() - 设置断网自动重连接 ```c++ bool setAutoReconnect(bool autoReconnect) ``` Set whether mainboard will attempt to reconnect to an access point in case it is disconnected。 设置是否要自动重新连接到最后连接过的接入点。设置后,一旦主板出现断开网络连接的状况,主板会反复尝试自动重连。 **语法** ```c++ wiFi.setAutoReconnect() wiFi.setAutoReconnect(autoReconnect) ``` **参数** | 传入值 | 说明 | 值范围 | | :-----------: | :----------------------------------------------------------- | :---------: | | autoReconnect | true:尝试重新建立与无线AP的连接
false:保持断开连接状态 | true、false | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------- | :---------: | | bool | true:设置成功
false:设置失败 | true、false | ##### getAutoReconnect() - 返回是否自动重连接 ```c++ bool getAutoReconnect() ``` **语法** ```c++ if (WiFi.getAutoReconnec() == true) { Serial.println("Automatic Reconnection is set"); } ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----: | :----------------------------------------------------------- | :---------: | | bool | true:开启了断网自动连接功能
false:禁用了断网自动连接功能 | true、false | ##### localIP() - 返回模块地址 ```c++ IPAddress localIP() ``` **语法** ```c++ wifi.localIP() ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :----------------------: | :---------: | | IPAddress | 当前无线终端分配的IP地址 | true、false | ##### subnetMask() - 返回子网掩码 ```c++ IPAddress subnetMask() ``` **语法** ```c++ wifi.subnetMask() ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :------: | :----: | | IPAddress | 子网掩码 | | ##### gatewayIP() - 返回网关地址 ```c++ IPAddress gatewayIP() ``` **语法** ```c++ wifi.gatewayIP() ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :-------: | :----: | :----: | | IPAddress | 网关IP | | ##### dnsIP() - 返回DNS地址 ```c++ IPAddress dnsIP(uint8_t dns_no = 0) ``` **语法** ```c++ WiFi.dnsIP() WiFi.dnsIP(dns_no) ``` **参数** | 传入值 | 说明 | 值范围 | | :------------: | :----------------------------------------------------------- | :----: | | uint8_t dns_no | 可选参数。通过输入参数dns_no,我们可以指定所需的域名服务器的IP。
此参数允许的值是0或1。如果未提供任何参数或参数为0,函数会返回DNS#1的IP。如果参数为1,则返回DNS#2的IP。 | | **返回** | 返回值 | 说明 | 值范围 | | :-------: | :-------------------------------------: | :----: | | IPAddress | DNS服务的IP地址,返回DNS#1或DNS#2的IP | | ##### macAddress() - 返回MAC地址 ```c++ uint8_t * macAddress(uint8_t* mac) String macAddress() ``` **语法** ```c++ WiFi.macAddress(macAddr) WiFi.macAddress() ``` ~~~c++ if (WiFi.status() == WL_CONNECTED) { uint8_t macAddr[6]; // MAC地址会储存在这个数组里面 WiFi.macAddress(macAddr); Serial.printf("用转存到数组的方式获取MAC地址: %02x:%02x:%02x:%02x:%02x:%02x\n", macAddr[0], macAddr[1], macAddr[2], macAddr[3], macAddr[4], macAddr[5]); } ~~~ ~~~c++ if (WiFi.status() == WL_CONNECTED) { // 不输入参数直接调用可以直接打印出字符串 Serial.printf("字符串获取MAC地址: %s\n", WiFi.macAddress().c_str()); } ~~~ **参数** | 传入值 | 说明 | 值范围 | | :-----: | :----------------------------------------------------------- | :----: | | macAddr | 可选参数。该参数为uint8_t类型的数组,这个数组含有6个元素。mac地址将会储存在这个数组中。
如果不输入参数,mac地址将以字符串类型返回。 | | **返回** | 返回值 | 说明 | 值范围 | | :----: | :----------------------------------------------------------: | :----: | | | 若输入参数则会返回储存了MAC地址的数组(uint8_t型)。若没有输入参数则会返回MAC地址字符串(string型) | | ##### getHostname() - 返回主机名字 ```c++ const char * getHostname() ``` **语法** ```c++ Serial.printf("当前hostname: %s\n", WiFi.getHostname()); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :----------: | :------------------: | :----: | | const char * | 返回当前的hostname。 | | ##### setHostname() - 设置主机名字 ```c++ bool setHostname(const char * hostname) ``` **语法** ```c++ WiFi.setHostname("FireBeetle_MESH"); // 设置新的hostname ``` **参数** | 传入值 | 说明 | 值范围 | | :------: | :----------------------------------------------------------: | :----: | | hostname | 设置的主机名的最大长度为32个字符。可以使用大写字母(A-Z),小写字母(a-z),数字(0-9),符号(.)和符号(-)。大小写字母之间没有区别,不允许将空格或者空格字符作为hostname。 | | **返回** | 返回值 | 说明 | 值范围 | | :----: | :----------------------------------------------------------: | :----: | | bool | 如果设置新的hostname成功,会返回true。如果超过了32个字符的限制,或者设置失败,则函数将返回false而不会分配新的主机名 | | ##### status() - 返回联网状态 ```c++ wl_status_t status() ``` **语法** ```c++ wl_status_t wifiStatus; wifiStatus = WiFi.status(); ``` **参数** 无 **返回** | 返回值 | 说明 | 值范围 | | :---------: | :--: | :----------------------------------------------------------- | | wl_status_t | | 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断开连接; | ##### WiFiMulti::addAP() - 添加WiFi信息 ```c++ bool WiFiMulti::addAP(const char* ssid, const char *passphrase) ``` **语法** ```c++ #include #include WiFiMulti wifiMulti; // 建立WiFiMulti对象,对象名称是'wifiMulti' wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); ``` **参数** | 传入值 | 说明 | 值范围 | | :--------------------: | :-------: | :----: | | const char* ssid | WiFi 名称 | | | const char *passphrase | WiFi 密码 | | **返回** | 返回值 | 说明 | 值范围 | | :----: | :---------------------------------: | :---------: | | bool | 成功设置后返回true,失败则返回false | true、false | ##### WiFiMulti::run() - 筛选并连接给出表中的 WiFi ```c++ uint8_t WiFiMulti::run(uint32_t connectTimeout) ``` **语法** ```c++ #include #include WiFiMulti wifiMulti; // 建立WiFiMulti对象,对象名称是'wifiMulti' if(wifiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } ``` **参数** | 传入值 | 说明 | 值范围 | | :---------------------: | :------: | :----: | | uint32_t connectTimeout | 定时时长 | | **返回** | 返回值 | 说明 | 值范围 | | :-----: | :---------------: | :---------: | | uint8_t | WiFi 连接状态信息 | true、false | #### 例程:连接网络并每隔1秒钟打印一次主板分配的IP地址 ```c++ #include const char *ssid = "your_ssid"; //你的网络名称 const char *password = "your_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() { Serial.println("IP address: "); Serial.println(WiFi.localIP()); //打印主板分配的IP地址 delay(1000); } ``` #### 例程:WiFiMulti 多WiFi网络连接 WiFiMulti 可保存多个WiFi网络信息。主板会在环境中搜索addAP函数所存储的WiFi,如果搜到多个存储的WiFi那么主板将会连接信号最强的那一个WiFi信号。当一个WiFi网络不能连接,程序可自动连接第二个WiFi网络。 (参考Arduino IDE例程 Examples -> Examples for Edge101WE ->WiFi\examples\WiFiMulti) ```c++ /* * This sketch trys to Connect to the best AP based on a given list * */ #include #include WiFiMulti wifiMulti; // 建立WiFiMulti对象,对象名称是'wifiMulti' void setup() { Serial.begin(115200); delay(10); //通过addAp函数存储 WiFi名称 WiFi密码 // 这三条语句通过调用函数addAP来记录3个不同的WiFi网络信息。 wifiMulti.addAP("ssid_from_AP_1", "your_password_for_AP_1"); wifiMulti.addAP("ssid_from_AP_2", "your_password_for_AP_2"); wifiMulti.addAP("ssid_from_AP_3", "your_password_for_AP_3"); Serial.println("Connecting Wifi..."); } void loop() { // 环境中搜索addAP函数所存储的WiFi。如果搜到多个存储的WiFi那么主板将会连接信号最强的那一个WiFi信号。 // 一旦连接WiFi成功,wifiMulti.run()将会返回“WL_CONNECTED” if(wifiMulti.run() == WL_CONNECTED) { Serial.println(""); Serial.println("WiFi connected"); Serial.print("WiFi SSID: "); // 串口打印出连接WiFi SSID Serial.println(WiFi.SSID()); Serial.print("IP address: "); // 串口打印出连接IP 地址 Serial.println(WiFi.localIP()); } else { Serial.println("WiFi not connected!"); } delay(3000); } ``` 如图,Edge101WE 主板先连接bobophone的 WiFi热点。此时关闭这个热点,它将会自动连接上dfrobotOffice的WiFi网络。 ![image-20210429133941614](./pictures/image-20210429133941614.png) ### 7.2.6 WiFi事件 在网络出现变化时会触发事件,用户可以在事件发生时对不同的情况进行处理。 #### 事件列表 | WiFi事件 | 说明 | | -------------------------------- | ---------------------------------------------------------- | | SYSTEM_EVENT_WIFI_READY | WiFi ready WiFi 准备好 | | SYSTEM_EVENT_SCAN_DONE | finish scanning AP 快速扫描完成 | | SYSTEM_EVENT_STA_START | station start STA模式开始 | | SYSTEM_EVENT_STA_STOP | station stop STA模式结束 | | SYSTEM_EVENT_STA_CONNECTED | station connected to AP STA连接上AP | | SYSTEM_EVENT_STA_DISCONNECTED | station disconnected from AP STA从AP上端口 | | SYSTEM_EVENT_STA_AUTHMODE_CHANGE | the auth mode of AP connected by ESP32 station changed | | SYSTEM_EVENT_STA_GOT_IP | station got IP from connected AP | | SYSTEM_EVENT_STA_LOST_IP | station lost IP and the IP is reset to 0 | | SYSTEM_EVENT_STA_WPS_ER_SUCCESS | station wps succeeds in enrollee mode | | SYSTEM_EVENT_STA_WPS_ER_FAILED | station wps fails in enrollee mode | | SYSTEM_EVENT_STA_WPS_ER_TIMEOUT | station wps timeout in enrollee mode | | SYSTEM_EVENT_STA_WPS_ER_PIN | station wps pin code in enrollee mode | | SYSTEM_EVENT_AP_START | soft-AP start | | SYSTEM_EVENT_AP_STOP | 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 | station or ap or ethernet interface v6IP addr is preferred | | SYSTEM_EVENT_ETH_START | ethernet start 以太网启动 | | SYSTEM_EVENT_ETH_STOP | ethernet stop 以太网停止 | | SYSTEM_EVENT_ETH_CONNECTED | ethernet phy link up | | SYSTEM_EVENT_ETH_DISCONNECTED | ethernet phy link down | | SYSTEM_EVENT_ETH_GOT_IP | ethernet got IP from connected AP | | SYSTEM_EVENT_MAX | 事件初始值 | #### onEvent() - 注册事件方法 ```c++ 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) ``` **语法** ```c++ WiFi.onEvent(WiFiGotIP, WiFiEvent_t::SYSTEM_EVENT_STA_GOT_IP); ``` **参数** | 传入值 | 说明 | 值范围 | | :---------------------: | :------------------------------------------: | :----: | | WiFiEventCb cbEvent | WiFi事件回调函数 | | | WiFiEventFuncCb cbEvent | WiFi事件方法回调函数 | | | WiFiEventSysCb cbEvent | WiFi事件系统回调函数 | | | system_event_id_t event | 可选参数。指定触发系统事件的ID,详见事件列表 | | **返回** | 返回值 | 说明 | 值范围 | | :-------------: | :----------: | :----: | | wifi_event_id_t | 注册的事件ID | | #### removeEvent() - 删除已注册的事件方法 ```c++ 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) ``` **语法** ```c++ ``` **参数** | 传入值 | 说明 | 值范围 | | :---------------------: | :------------------------------------------: | :----: | | WiFiEventCb cbEvent | WiFi事件回调函数 | | | WiFiEventSysCb cbEven | WiFi事件系统回调函数 | | | system_event_id_t event | 可选参数。指定触发系统事件的ID,详见事件列表 | | | wifi_event_id_t id | WiFi事件的ID | | **返回** 无 #### 例程:注册WiFi事件 通过事件可以监听到WiFi的变化。 (参考Arduino IDE例程 Examples -> Examples for Edge101WE ->WiFi\examplesWiFiClientEvents) ```c++ /* * This sketch shows the WiFi event usage * */ /* * WiFi Events 0 ARDUINO_EVENT_WIFI_READY < ESP32 WiFi ready 1 ARDUINO_EVENT_WIFI_SCAN_DONE < ESP32 finish scanning AP 2 ARDUINO_EVENT_WIFI_STA_START < ESP32 station start 3 ARDUINO_EVENT_WIFI_STA_STOP < ESP32 station stop 4 ARDUINO_EVENT_WIFI_STA_CONNECTED < ESP32 station connected to AP 5 ARDUINO_EVENT_WIFI_STA_DISCONNECTED < ESP32 station disconnected from AP 6 ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE < the auth mode of AP connected by ESP32 station changed 7 ARDUINO_EVENT_WIFI_STA_GOT_IP < ESP32 station got IP from connected AP 8 ARDUINO_EVENT_WIFI_STA_LOST_IP < ESP32 station lost IP and the IP is reset to 0 9 ARDUINO_EVENT_WPS_ER_SUCCESS < ESP32 station wps succeeds in enrollee mode 10 ARDUINO_EVENT_WPS_ER_FAILED < ESP32 station wps fails in enrollee mode 11 ARDUINO_EVENT_WPS_ER_TIMEOUT < ESP32 station wps timeout in enrollee mode 12 ARDUINO_EVENT_WPS_ER_PIN < ESP32 station wps pin code in enrollee mode 13 ARDUINO_EVENT_WIFI_AP_START < ESP32 soft-AP start 14 ARDUINO_EVENT_WIFI_AP_STOP < ESP32 soft-AP stop 15 ARDUINO_EVENT_WIFI_AP_STACONNECTED < a station connected to ESP32 soft-AP 16 ARDUINO_EVENT_WIFI_AP_STADISCONNECTED < a station disconnected from ESP32 soft-AP 17 ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED < ESP32 soft-AP assign an IP to a connected station 18 ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED < Receive probe request packet in soft-AP interface 19 ARDUINO_EVENT_WIFI_AP_GOT_IP6 < ESP32 ap interface v6IP addr is preferred 19 ARDUINO_EVENT_WIFI_STA_GOT_IP6 < ESP32 station interface v6IP addr is preferred 20 ARDUINO_EVENT_ETH_START < ESP32 ethernet start 21 ARDUINO_EVENT_ETH_STOP < ESP32 ethernet stop 22 ARDUINO_EVENT_ETH_CONNECTED < ESP32 ethernet phy link up 23 ARDUINO_EVENT_ETH_DISCONNECTED < ESP32 ethernet phy link down 24 ARDUINO_EVENT_ETH_GOT_IP < ESP32 ethernet got IP from connected AP 19 ARDUINO_EVENT_ETH_GOT_IP6 < ESP32 ethernet interface v6IP addr is preferred 25 ARDUINO_EVENT_MAX */ #include const char* ssid = "your-ssid"; const char* password = "your-password"; void WiFiEvent(WiFiEvent_t event) { Serial.printf("[WiFi-event] event: %d\n", event); switch (event) { case ARDUINO_EVENT_WIFI_READY: Serial.println("WiFi interface ready"); break; case ARDUINO_EVENT_WIFI_SCAN_DONE: Serial.println("Completed scan for access points"); break; case ARDUINO_EVENT_WIFI_STA_START: Serial.println("WiFi client started"); break; case ARDUINO_EVENT_WIFI_STA_STOP: Serial.println("WiFi clients stopped"); break; case ARDUINO_EVENT_WIFI_STA_CONNECTED: Serial.println("Connected to access point"); break; case ARDUINO_EVENT_WIFI_STA_DISCONNECTED: Serial.println("Disconnected from WiFi access point"); break; case ARDUINO_EVENT_WIFI_STA_AUTHMODE_CHANGE: Serial.println("Authentication mode of access point has changed"); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP: Serial.print("Obtained IP address: "); Serial.println(WiFi.localIP()); break; case ARDUINO_EVENT_WIFI_STA_LOST_IP: Serial.println("Lost IP address and IP address is reset to 0"); break; case ARDUINO_EVENT_WPS_ER_SUCCESS: Serial.println("WiFi Protected Setup (WPS): succeeded in enrollee mode"); break; case ARDUINO_EVENT_WPS_ER_FAILED: Serial.println("WiFi Protected Setup (WPS): failed in enrollee mode"); break; case ARDUINO_EVENT_WPS_ER_TIMEOUT: Serial.println("WiFi Protected Setup (WPS): timeout in enrollee mode"); break; case ARDUINO_EVENT_WPS_ER_PIN: Serial.println("WiFi Protected Setup (WPS): pin code in enrollee mode"); break; case ARDUINO_EVENT_WIFI_AP_START: Serial.println("WiFi access point started"); break; case ARDUINO_EVENT_WIFI_AP_STOP: Serial.println("WiFi access point stopped"); break; case ARDUINO_EVENT_WIFI_AP_STACONNECTED: Serial.println("Client connected"); break; case ARDUINO_EVENT_WIFI_AP_STADISCONNECTED: Serial.println("Client disconnected"); break; case ARDUINO_EVENT_WIFI_AP_STAIPASSIGNED: Serial.println("Assigned IP address to client"); break; case ARDUINO_EVENT_WIFI_AP_PROBEREQRECVED: Serial.println("Received probe request"); break; case ARDUINO_EVENT_WIFI_AP_GOT_IP6: Serial.println("AP IPv6 is preferred"); break; case ARDUINO_EVENT_WIFI_STA_GOT_IP6: Serial.println("STA IPv6 is preferred"); break; case ARDUINO_EVENT_ETH_GOT_IP6: Serial.println("Ethernet IPv6 is preferred"); break; case ARDUINO_EVENT_ETH_START: Serial.println("Ethernet started"); break; case ARDUINO_EVENT_ETH_STOP: Serial.println("Ethernet stopped"); break; case ARDUINO_EVENT_ETH_CONNECTED: Serial.println("Ethernet connected"); break; case ARDUINO_EVENT_ETH_DISCONNECTED: Serial.println("Ethernet disconnected"); break; case ARDUINO_EVENT_ETH_GOT_IP: Serial.println("Obtained IP address"); break; default: break; }} void WiFiGotIP(WiFiEvent_t event, WiFiEventInfo_t info) { Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(IPAddress(info.got_ip.ip_info.ip.addr)); } void setup() { Serial.begin(115200); // delete old config WiFi.disconnect(true); delay(1000); // Examples of different ways to register wifi events WiFi.onEvent(WiFiEvent); WiFi.onEvent(WiFiGotIP, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_GOT_IP); WiFiEventId_t eventID = WiFi.onEvent([](WiFiEvent_t event, WiFiEventInfo_t info){ Serial.print("WiFi lost connection. Reason: "); Serial.println(info.wifi_sta_disconnected.reason); }, WiFiEvent_t::ARDUINO_EVENT_WIFI_STA_DISCONNECTED); // Remove WiFi event Serial.print("WiFi Event ID: "); Serial.println(eventID); // WiFi.removeEvent(eventID); WiFi.begin(ssid, password); Serial.println(); Serial.println(); Serial.println("Wait for WiFi... "); } void loop() { delay(1000); } ```