7. 联网

Edge101WE 主板 具备以太网和WiFi联网功能,编写联网程序最简单的方法就是根据例程代码来修改。

7.1 以太网MAC

7.1.1 以太网方法API

begin() - 进行以太网接口初始化并启用以太网

语法

bool begin();

参数

返回

返回值 说明 值范围
bool 初始化成功返回true,失败返回false true/false

config() - 设置IP地址、网关地址、子网掩码、dns地址;

语法

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() - 获取主机名字

语法

const char * getHostname();

参数

返回

返回值 说明 值范围
指针 指向主机名的指针 const char *

setHostname() - 设置主机名

语法

bool setHostname(const char * hostname);

参数

传入值 说明 值范围
hostname 主机名首地址 const char *

返回

返回值 说明 值范围
bool 配置成功返回true,失败返回false true/false

linkUp() - 检查以太网连接是否正常

语法

bool linkUp();

参数

返回

返回值 说明 值范围
bool 连接正常返回true,连接故障失败返回false true/false

linkSpeed() - 获取传输速度,单位Mbps

语法

uint8_t linkSpeed();

参数

返回

返回值 说明 值范围
uint8_t 速度,单位为Mbps uint8_t

enableIpV6() - 使能IPv6网络

语法

bool enableIpV6();

参数

返回

返回值 说明 值范围
bool 配置成功返回true,失败返回false true/false

localIPv6() - 获取IPv6地址

语法

IPv6Address localIPv6();

参数

返回

返回值 说明 值范围
IPv6Address IPv6地址 4个word

localIP() - 获取IPv4地址

语法

IPAddress localIP();

参数

返回

返回值 说明 值范围
IPAddress IPv4地址 4个word

subnetMask() - 获取子网掩码

语法

IPAddress subnetMask();

参数

返回

返回值 说明 值范围
IPAddress 子网掩码 4个word

gatewayIP() - 获取网关地址

语法

 subnetMask();

参数

返回

返回值 说明 值范围
IPAddress 网关地址 4个word

dnsIP() - 获取dns服务器地址

语法

IPAddress dnsIP(uint8_t dns_no = 0);

参数

传入值 说明 值范围
dns_no dns号 默认为0

返回

返回值 说明 值范围
IPAddress dns服务器地址 4个word

broadcastIP() - 获取广播地址

IPAddress broadcastIP();

参数

返回

返回值 说明 值范围
IPAddress 广播地址 4个word

networkID() - 获取网络ID

IPAddress networkID();

参数

返回

返回值 说明 值范围
IPAddress 网络ID 4个word

subnetCIDR() - 获取子网网段

uint8_t subnetCIDR();

参数

返回

返回值 说明 值范围
uint8_t 子网网段 uint8_t

macAddress() - 获取MAC地址

uint8_t * macAddress(uint8_t* mac);

参数

传入值 说明 值范围
mac 接收ma地址的地址 uint8_t *

返回

返回值 说明 值范围
mac地址 这里是返回的没有经过处理的MAC地址 uint8_t *

String macAddress() - 获取MAC地址

 String macAddress();

参数

返回

返回值 说明 值范围
String mac地址,这里是返回的是经过处理的MAC地址,示例:C4:4F:33:40:61:40 String

以太网示例

例程1:以太网与WiFi的切换

(参考Arduino IDE例程 Examples -> Examples for Edge101WE ->Ethernet\examples\ETH_WiFi)

/*
    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 <ETH.h>
#include <WiFi.h>
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和密码,后将程序烧录到主板。

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

将网线连接到 Edge101WE 主板的 以太网接口上,网口的绿色LED亮代表连接好,橙色LED闪烁代表在通信。

此时串口打印以太网连接成功、以太网的MAC地址、IP地址等信息。

然后程序每10秒访问一次 www.baidu.com 并返回获取的数据。

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

<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>
closing connection

如果拔下网线,此时显示以太网断开,主板重启,然后通过WiFi方式去联网并访问网址。

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

<html>
<meta http-equiv="refresh" content="0;url=http://www.baidu.com/">
</html>
closing connection

例程2:以太网UDP通信

(参考Arduino IDE例程 Examples -> Examples for Edge101WE ->Ethernet\examples\UDPClient)

/*
 *  This sketch sends random data over UDP on a ESP32 device
 *
 */
#include <WiFi.h>
#include <WiFiUdp.h>

//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 <ETH.h>
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地址。

const char * udpAddress = "192.168.1.255";

这里我们使用 Packet Sender 软件进行调试。安装软件后,打开软件,点击File -> Settings,设置使能 UDP Servers,端口号设置为例程中定义的端口号 3333。

点击 OK 保存设置。

image-20220127114636836

回到软件的主菜单,可以看到端口为 3333 的UDP服务器已经打开,并且在接收数据窗口接收到UDP客户端的数据。每秒更新一次。

注意:如果发现没有数据发送过来,请将电脑的防火墙关闭后再次尝试。

image-20220127114715180

例程3:以太网TCP通信

(参考Arduino IDE例程 Examples -> Examples for Edge101WE ->Ethernet\examples\TCPClientBasic)

/*
 *  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 <WiFiClient.h>
#include <ETH.h>
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

在软件的主页顶部显示 TCP Servers 的 IP地址 192.168.1.96。

image-20220127134821724

修改例程中的 host IP地址为 TCP Servers的IP,将例子程序烧写到主板。

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

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() - 返回当前信道

int32_t channel() 

语法

channel = WiFi.channel();

参数

返回

返回值 说明 值范围
int32_t 当前WiFi通信的无线频率信道 1~13

persistent() - 设置是否将WiFi模式、SSID、密码、自动重连等信息存储于flash中

void persistent(bool persistent)

语法

WiFi.persistent(true);

参数

传入值 说明 值范围
bool persistent 是否将WiFi模式、SSID、密码、自动重连等信息存储于flash中(默认为true,是存储到flash) true、false

返回

mode() - 设置WiFi工作模式

bool mode(wifi_mode_t) 

语法

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工作模式

wifi_mode_t getMode()

语法

mode = WiFi.getMode();

参数

返回

返回值 说明 值范围
wifi_mode_t 返回WiFi工作模式 WIFI_OFF、WIFI_STA、WIFI_AP、WIFI_AP_STA

enableSTA() - 使能/失能STA模式

bool enableSTA(bool enable)

语法

WiFi.enableSTA(true);

参数

传入值 说明 值范围
bool enable 使能/失能STA模式 true、false

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
true、false

enableAP() - 使能/失能AP模式

bool enableAP(bool enable)

语法

WiFi.enableAP(true);

参数

传入值 说明 值范围
bool enable 使能/失能AP模式 true、false

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
true、false

setSleep() - 使能/失能休眠

bool setSleep(bool enable) 

语法

WiFi.setSleep(true);

参数

传入值 说明 值范围
bool enable 仅STA模式,默认开启休眠;如果对实时响应要求较高的话需要关闭休眠; true、false

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
true、false

getSleep() - 返回是否开启休眠

bool getSleep()

语法

WiFi.getSleep();

参数

返回

返回值 说明 值范围
bool 开启休眠,返回 true true、false

setTxPower() - 设置WiFi发射功率

bool setTxPower(wifi_power_t power)

语法

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发射功率

wifi_power_t getTxPower()

语法

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() - 启动搜索

int16_t scanNetworks(bool async = false, bool show_hidden = false, bool passive = false, uint32_t max_ms_per_chan = 300) 

语法

WiFi.scanNetworks();

参数

传入值 说明 值范围
bool async 异步扫描,该值为true时将启动异步扫描,该方法将不阻塞(默认flash,同步扫描)
bool show_hidden 是否扫描不广播的网络(默认false不扫描不广播网络)
bool passive 影响扫描速度,该值为true时扫描速度较快(不确定)
uint32_t max_ms_per_chan 每通道最大扫描时间,单位毫秒(默认为300毫秒)

返回

返回值 说明 值范围
int16_t 扫描到的WiFi网络数量

scanComplete() - 异步模式下用于获取扫描到的网络数量

int16_t scanComplete()

异步模式下用于获取扫描到的网络数量,如果返回值为-1,表示还在进行扫描,如果返回值为-2,表示未进行扫描或扫描失败;

语法

nume = WiFi.scanComplete();

参数

返回

返回值 说明 值范围
int16_t 扫描到的WiFi网络数量(如果未完成扫描,则返回值<0;扫描仍在进行中:-1 ;未进行扫描或扫描失败:-2

scanDelete() - 删除内存中的扫描结果

void scanDelete()

语法

WiFi.scanDelete();

参数

返回

SSID() - 返回扫描到的网络名称

String SSID(uint8_t networkItem) 

语法

Serial.println(WiFi.SSID(i));
if (WiFi.SSID(i) == "anny"){}
Serial.printf("SSID:%s", WiFi.SSID().c_str());

参数

传入值 说明 值范围
uint8_t networkItem WiFi网络编号

返回

返回值 说明 值范围
String 返回扫描到的网络名称

encryptionType() - 返回扫描到的网络加密类型

wifi_auth_mode_t encryptionType(uint8_t networkItem)

语法

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() - 返回扫描到的网络信号强度

int32_t RSSI(uint8_t networkItem)

语法

Serial.println(WiFi.RSSI(i));

参数

传入值 说明 值范围
uint8_t networkItem WiFi网络编号

返回

返回值 说明 值范围
int32_t 网络信号强度

channel() - 返回扫描到的网络信道号

int32_t channel(uint8_t networkItem) 

语法

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)

/*
 *  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 网络。

#include <WiFi.h>

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() 连接的参数。

#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("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(); 判断是否扫描完毕。 如果扫描完毕,置标志位,停定时器。 触发连接程序, 连接完成后

#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("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 <WiFi.h>; 启动AP网络 WiFi.softAP(ssid);

AP方式

softAP() - 启动AP
bool softAP(const char* ssid, const char* passphrase = NULL, int channel = 1, int ssid_hidden = 0, int max_connection = 4)

该方法用来启动AP,在成功启动后返回true。

语法

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() - 设置本地地址、网关地址和子网掩码
bool softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet)

设置本地地址、网关地址和子网掩码,默认分别为192.168.4.1 192.168.4.1 255.255.255.0;

语法

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
bool softAPdisconnect(bool wifioff = false)

关闭当前AP,若wifioff为true则还将还原网络设置。

语法

WiFi.softAPdisconnect();

参数

传入值 说明 值范围
bool wifioff 关闭当前AP(默认true,关闭当前AP) true、false

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
true、false
softAPgetStationNum() - 返回连接到AP的客户端数量
uint8_t softAPgetStationNum()

返回连接到AP的客户端数量。

语法

num = WiFi.softAPgetStationNum();

参数

返回

返回值 说明 值范围
uint8_t 连接到AP的客户端数量 1 ~ 4
softAPIP() - 返回当前IP
IPAddress softAPIP()

语法

IPAddress IP;
IP = WiFi.softAPIP();

参数

返回

返回值 说明 值范围
IPAddress 当前IP
softAPgetHostname() - 返回主机名字
const char * softAPgetHostname()

主机名字是标识子网中的某台主机。

语法

hostName = WiFi.softAPgetHostname();

参数

返回

返回值 说明 值范围
const char * 主机名字
softAPsetHostname() - 设置主机名字
bool softAPsetHostname(const char * hostname) 

语法

WiFi.softAPsetHostname("FireBeetleMESH"); 

参数

传入值 说明 值范围
const char * hostname 主机名字

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
true、false
softAPmacAddress() - 返回mac地址
uint8_t* softAPmacAddress(uint8_t* mac)
String softAPmacAddress(void)

语法

mac = WiFi.softAPmacAddress();

参数

传入值 说明 值范围
uint8_t* mac 指向长度为WL_MAC_ADDR_LENGTH的uint8_t数组的指针

返回

返回值 说明 值范围
uint8_t* uint8_t数组的指针
String 返回字符串
softAPBroadcastIP() - 获取主机广播IP
IPAddress  softAPBroadcastIP()

语法

Serial.println(WiFiAP.softAPBroadcastIP());

参数

返回

返回值 说明 值范围
主机广播IP
softAPenableIpV6() - 使能IPV6
bool softAPenableIpV6()

语法

WiFi.softAPenableIpV6();

参数

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
softAPIPv6() - 获取主机IPV6的IP
IPv6Address softAPIPv6()

语法

Serial.println(WiFi.softAPIPv6());

参数

返回

返回值 说明 值范围
IPv6Address 主机IPv6地址
softAPNetworkID() - 获取主机网络ID
IPAddress softAPNetworkID() 	

主机网络ID( NetworkID )标识Internet上的一个子网。

Network ID = (IP) & (Subnet Mask)

语法

Serial.println(WiFiAP.softAPNetworkID());

参数

返回

返回值 说明 值范围
主机网络ID
softAPSubnetCIDR() - 获取子网CIDR(无分类域间路由)位数
uint8_t  softAPSubnetCIDR()

子网无分类域间路由CIDR ( Classless Inter-Domain Routing )

根据子网掩码( Subnet Mask )返回CIDR位数。

例如子网掩码是255.255.255.0,那么将会返回24。

语法

Serial.println(WiFiAP.softAPSubnetCIDR());

参数

返回

返回值 说明 值范围
CIDR位数。例如子网掩码是255.255.255.0,那么将会返回24。

例程:建立AP,并将电脑WiFi连接到这个AP,然后使用ping命令测试是否连接。

#include <WiFi.h>;

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

例程:创建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。

/*
  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 <WiFi.h>
#include <WiFiClient.h>
#include <WiFiAP.h>

#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 <a href=\"/H\">here</a> to turn ON the LED.<br>");
            client.print("Click <a href=\"/L\">here</a> to turn OFF the LED.<br>");

            // 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.h>; 连接到网络 WiFi.begin(ssid, password);

API参考

begin() - 接入网络
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)

该方法用来接入网络;

语法

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() - 设置网络地址
bool config(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dns1 = (uint32_t)0x00000000, IPAddress dns2 = (uint32_t)0x00000000)

语法

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 () - 重连
bool 	reconnect ()

语法

WiFi.reconnect();

参数

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
true、false
disconnect() - 断开网络连接
bool disconnect(bool wifioff = false, bool eraseap = false)

断开网络连接,若wifioff为true则还将还原网络设置,若eraseap为true则将清除保存于flash中的网络参数;

语法

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()对主控进行复位重新连接。

#include <WiFi.h>

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() - 返回是否已接入网络
bool isConnected()

也可以通过 WiFi.status() != WL_CONNECTED进行判断

语法

while (!WiFi.isConnected()) //等待网络连接成功
  {
    delay(500);
    Serial.print(".");
  }

参数

返回

返回值 说明 值范围
bool true:连接网络
false:未连接网络
true、false
setAutoConnect() - 设置为自动连接模式
bool 	setAutoConnect (bool autoConnect)

Configure mainboard to automatically connect on power on to the last used access point

自动连接模式激活后,主板会在通电后自动连接到最后连接过的WiFi接入点。

语法

wiFi.setAutoConnect()
wiFi.setAutoConnect(autoConnect)

参数

传入值 说明 值范围
autoConnect autoConnect是一个可选的参数。如果设置为false,则将禁用自动连接功能。
如果省略或设置为true,则将启用自动连接模式。
true、false

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
true、false

例程:设置自动连接模式

程序首先连接上WiFi,然后执行设置自动连接模式。如果连接到的AP断开后重启,主板将自动重新尝试连接AP

#include <WiFi.h>

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() - 获取是否设置为自动连接
bool 	getAutoConnect ()

语法

if (WiFi.getAutoConnect() == true) {
    Serial.println("Automatic connection is set");
  }

参数

返回

返回值 说明 值范围
bool true:开启了自动连接功能
false:禁用了自动连接功能
true、false
setAutoReconnect() - 设置断网自动重连接
bool setAutoReconnect(bool autoReconnect)

Set whether mainboard will attempt to reconnect to an access point in case it is disconnected。

设置是否要自动重新连接到最后连接过的接入点。设置后,一旦主板出现断开网络连接的状况,主板会反复尝试自动重连。

语法

wiFi.setAutoReconnect()
wiFi.setAutoReconnect(autoReconnect)

参数

传入值 说明 值范围
autoReconnect true:尝试重新建立与无线AP的连接
false:保持断开连接状态
true、false

返回

返回值 说明 值范围
bool true:设置成功
false:设置失败
true、false
getAutoReconnect() - 返回是否自动重连接
bool getAutoReconnect()

语法

if (WiFi.getAutoReconnec() == true) {
    Serial.println("Automatic Reconnection is set");
  }

参数

返回

返回值 说明 值范围
bool true:开启了断网自动连接功能
false:禁用了断网自动连接功能
true、false
localIP() - 返回模块地址
IPAddress localIP()

语法

wifi.localIP()

参数

返回

返回值 说明 值范围
IPAddress 当前无线终端分配的IP地址 true、false
subnetMask() - 返回子网掩码
IPAddress subnetMask()

语法

wifi.subnetMask()

参数

返回

返回值 说明 值范围
IPAddress 子网掩码
gatewayIP() - 返回网关地址
IPAddress gatewayIP()

语法

wifi.gatewayIP()

参数

返回

返回值 说明 值范围
IPAddress 网关IP
dnsIP() - 返回DNS地址
IPAddress dnsIP(uint8_t dns_no = 0)

语法

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地址
uint8_t * macAddress(uint8_t* mac)
String macAddress()

语法

WiFi.macAddress(macAddr)
WiFi.macAddress()
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]);
}
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() - 返回主机名字
const char * getHostname()

语法

Serial.printf("当前hostname: %s\n", WiFi.getHostname());

参数

返回

返回值 说明 值范围
const char * 返回当前的hostname。
setHostname() - 设置主机名字
bool setHostname(const char * hostname)

语法

WiFi.setHostname("FireBeetle_MESH"); // 设置新的hostname

参数

传入值 说明 值范围
hostname 设置的主机名的最大长度为32个字符。可以使用大写字母(A-Z),小写字母(a-z),数字(0-9),符号(.)和符号(-)。大小写字母之间没有区别,不允许将空格或者空格字符作为hostname。

返回

返回值 说明 值范围
bool 如果设置新的hostname成功,会返回true。如果超过了32个字符的限制,或者设置失败,则函数将返回false而不会分配新的主机名
status() - 返回联网状态
wl_status_t status()

语法

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信息
bool WiFiMulti::addAP(const char* ssid, const char *passphrase)

语法

#include <WiFi.h>
#include <WiFiMulti.h>

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
uint8_t WiFiMulti::run(uint32_t connectTimeout)

语法

#include <WiFi.h>
#include <WiFiMulti.h>

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地址

#include <WiFi.h>

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)

/*
 *  This sketch trys to Connect to the best AP based on a given list
 *
 */

#include <WiFi.h>
#include <WiFiMulti.h>

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

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() - 注册事件方法

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)

语法

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() - 删除已注册的事件方法

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)

语法


参数

传入值 说明 值范围
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)

/*
 *  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 <WiFi.h>

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);
}