15、ESP32 Wifi

时间:2024-05-05 07:07:19

       ESP32 的 WIFI 功能是模块内置的,通过 ESP32 的基础库调用一些函数就可以轻松使用它。

Wifi STA 模式:

        让 ESP32 连接附近 WIFI,可以上网访问数据。

// 代码显示搜索连接附近指定的 WIFI
// 通过 pin 按键可断开连接

#include <WiFi.h>
#include <Arduino.h>

const char* ssd = "么么";
const char* pasd= "yaoqiao321";

const byte LED = 2;
const byte PIN = 4;

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

    pinMode(PIN, INPUT_PULLUP);
    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);

    Serial.print("[WiFi] 开始连接:");
    Serial.println(ssd);

    WiFi.begin(ssd, pasd);
    for(uint8_t i=0; i<20; i++)
    {
        switch(WiFi.status())   // 检查 WiFi 连接状态
        {
            case WL_NO_SSID_AVAIL:
            {
                Serial.println("[WiFi] 没有找到 SSID");
                break;
            }
            case WL_SCAN_COMPLETED:
            {
                Serial.println("[WiFi] 扫描完成");
                break;
            }
            case WL_CONNECTED:
            {
                Serial.println("[WiFi] 已连接!");
                Serial.print("[WiFi] IP 地址:");
                Serial.println(WiFi.localIP());
                i = 21;
                break;
            }
            case WL_CONNECT_FAILED:
            {
                Serial.print("[WiFi] 失败 - 未连接! ");
                return;
            }
            case WL_CONNECTION_LOST:
            {
                Serial.println("[WiFi] 连接丢失");
                break;
            }
            case WL_DISCONNECTED:
            {
                Serial.println("[WiFi] 连接已断开");
                break;
            }
            default:
            {
                Serial.print("[WiFi] WiFi 状态:");
                Serial.println(WiFi.status());
                break;
            }
        }
        delay(1000);
        
        if(i == 20)
        {
            Serial.print("[WiFi] 连接失败!");
            WiFi.disconnect();      // 断开连接
            return;
        }
    }

    digitalWrite(LED, HIGH);
}

void loop()
{
    if (digitalRead(PIN) == LOW)
    {
        Serial.println("[WiFi] 正在断开连接!");
        if(WiFi.disconnect(true, false))
        {
            Serial.println("[WiFi] 已断开连接");
        }
        delay(1000);
    }
}

         官方 API:

// 代码连接 WIFI 访问 NTP 服务器时间

#include <Arduino.h>
#include <WiFi.h>

const char* ssd = "vivo X80";
const char* pasd= "YQY1122334455";
const char* ntp_server = "ntp.aliyun.com";  // NTP 服务器
const int gmt_offset = 8 * 60 * 60;         // UTC/GMT+8,东 8 时区偏移量,单位秒
const int daylight_offset = 0;              // 夏令时偏移值,单位秒

const byte LED = 2;

void setup()
{
    pinMode(LED, OUTPUT);
    digitalWrite(LED, LOW);

    Serial.begin(115200);
    
    // 设置时区
    setenv("TZ", "CST-8", 1);   // TZ 是时区环境变量,CST-8 是中国标准时间,1 表示覆盖旧值
    tzset();    // 作用时区变量

    Serial.print("[WiFi] 开始连接:");
    Serial.println(ssd);

    WiFi.begin(ssd, pasd);
    while (WiFi.status() != WL_CONNECTED)
    {
        Serial.println("[WiFi] 正在尝试连接...");
        delay(1000);
    }
    Serial.println("[WiFi] 连接成功");

    // 同步时间
    configTime(gmt_offset, daylight_offset, ntp_server);
    Serial.println("完成时间同步");

    digitalWrite(LED, HIGH);
}

void loop()
{
    time_t now = 0;
    struct tm time_info;
    char strftime_buf[64] = {'\0'};

    time(&now);
    localtime_r(&now, &time_info);
    strftime(strftime_buf, sizeof(strftime_buf), "%Y.%m.%d %A %T", &time_info);
    Serial.println(strftime_buf);
    delay(1000);
}


Wifi AP 模式:

        ESP32会自建一个WIFI热点,其他设备可以加入这个热点进行数据交换,类似局域网,不可联网。

        开启 AP 模式:

/**
 * 设置一个接入点 AP
 * @param ssid              WiFi 名称 SSID(最多 63 字符)
 * @param passphrase        WiFi 密码(WPA2 密码最少 8 位),不设置默认为开放性网络
 * @param channel           WiFi 信道号(1 - 13),最好区分开环境中其他网络,避免信号干扰
 * @param ssid_hidden       隐藏信号 (0 = 开放网络, 1 = 隐藏网络,需要指定查找)
 * @param max_connection    最大连接数(1 - 4),默认 4
*/
bool WiFiAPClass::softAP(const char* ssid, const char* passphrase, int channel, int ssid_hidden, int max_connection, bool ftm_responder)

         配置 IP(不是必须的):

/**
 * 配置接入点
 * @param local_ip      WIFI IP
 * @param gateway       网关
 * @param subnet        子网掩码
 */
bool WiFiAPClass::softAPConfig(IPAddress local_ip, IPAddress gateway, IPAddress subnet, IPAddress dhcp_lease_start)

        关闭 AP 模式:

/**
 * 断开网络连接 (关闭 AP)
 * @param wifioff disable mode?
 * @return one value of wl_status_t enum
 */
bool WiFiAPClass::softAPdisconnect(bool wifioff)
#include <Arduino.h>
#include <WiFi.h>

WiFiAPClass WiFiAP;

const char* ssd = "ESP32_Wifi"; 
const char* pasd = "12345678";

IPAddress local_IP(192, 168, 1, 1);
IPAddress gateway(192, 168, 1, 1);
IPAddress subnet(255, 255, 255, 0);

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

    WiFi.softAPConfig(local_IP, gateway, subnet);   // 配置 本地IP 网关IP 子网掩码
    WiFi.softAP(ssd, pasd);   // AP 模式,创建一个 ESP32_Wifi 热点
}

void loop()
{
    delay(2000);
    Serial.print("本地 IP: ");
    Serial.println(WiFi.softAPIP());

    Serial.print("广播 IP: ");
    Serial.println(WiFi.softAPBroadcastIP());

    Serial.print("接入网络 ID: ");
    Serial.println(WiFi.softAPNetworkID());

    Serial.print("子网掩码: ");
    Serial.println(WiFi.softAPSubnetCIDR());

    Serial.print("主机名: ");
    Serial.println(WiFi.softAPgetHostname());

    Serial.print("热点 MAC: ");
    Serial.println(WiFi.softAPmacAddress());

    Serial.print("连接客户端: ");
    Serial.println(WiFi.softAPgetStationNum());
}


连接附近指定 WIFI:

#include <Arduino.h>
#include <WiFi.h>

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

    int num = WiFi.scanNetworks();

    Serial.print("可用WIFI数:");
    Serial.println(num);

    Serial.println("WIFI信息如下:");
    for(int a=0; a<=num; a++)
        Serial.println(WiFi.SSID(a));

    Serial.println("输入 WIFI 和密码:");
}

void loop()
{
    while(Serial.available()>0)
    {
        String SD = Serial.readStringUntil(',');    // 读取","以前的字符串
        const char* ssd = SD.c_str();   // String 转换 char*
        delay(100);

        String PSD = Serial.readStringUntil('\0');    // 读取"\0"以前的字符串
        const char* pasd = PSD.c_str();
        delay(1000);

        Serial.print("WIFI:");
        Serial.println(SD);
        Serial.print("PSD:");
        Serial.println(PSD);

        WiFi.begin(ssd,pasd);

        while(WiFi.status() != WL_CONNECTED)
        {
            delay(500);
            Serial.print(".");
        }
        Serial.println("connected success!");

        Serial.print("IP:");
        Serial.println(WiFi.localIP());
    }
}