【YFIOs】用C#开发硬件之WiFi网络

本篇将介绍如何使用 nanoFramework 配置 WiFi 网络连接,包括 STA 模式的自动重连机制和 AP 模式的热点配置。

ESP32-S3 内置 WiFi 模块,支持两种工作模式:

模式 说明 典型应用
STA 模式 作为站点连接到路由器 连接互联网、云平台通信
AP 模式 作为热点让其他设备连接 设备配网

所需 NuGet 包

包名 说明
nanoFramework.System.Device.Wifi WiFi 核心操作库
nanoFramework.Networking 网络辅助工具(含 WifiNetworkHelper)
nanoFramework.Iot.Device.DhcpServer DHCP 服务器库(AP模式必需)
nanoFramework.Logging 日志记录框架(可选)
nanoFramework.Logging.Debug 调试日志实现(可选)
nanoFramework.Runtime.Events 事件运行时支持
nanoFramework.Runtime.Native 原生运行时支持
nanoFramework.System.Net 网络功能支持

核心概念

网络状态枚举

public enum WifiState 
{ 
    Idle,               // 空闲状态
    Connecting,         // 连接中
    Connected,          // 已连接
    Reconnecting,       // 重连中   
    APMode              // AP模式
}

WiFi 管理器类

使用示例

WifiManager.cs

using System;
using System.Device.Wifi;
using System.Net;
using System.Net.NetworkInformation;
using System.Threading;
using Microsoft.Extensions.Logging;
using nanoFramework.Logging;
using nanoFramework.Networking;
using Iot.Device.DhcpServer;

namespace WIFI_StaApTest
{
    public enum WifiState 
    { 
        Idle,               // 空闲状态
        Connecting,         // 连接中
        Connected,          // 已连接
        Reconnecting,       // 重连中   
        APMode              // AP模式
    }

    // internal:仅本程序集可见,封装内部实现
    // 不对外暴露具体实现细节,保证API稳定性
    internal class WifiManager
    {
        // 日志记录器
        private ILogger _logger;
        
        // WIFI硬件适配器(系统唯一)
        private WifiAdapter _wifiAdapter;
        
        // 当前连接的网络凭证
        private string _currentSSID = null;
        private string _currentPassword = null;

        // ========== 状态机与同步工具 ==========
        // 当前WIFI状态(线程安全的状态机)
        public WifiState CurrentState { get; private set; } = WifiState.Idle;
        
        // 云端通信唤醒事件(连接成功时通知上云线程)
        public AutoResetEvent CloudWakeUpEvent { get; private set; }
        
        // 重连任务取消令牌(用于安全终止重连线程)
        private CancellationTokenSource _reconnectCts;
        
        // 网络状态防抖定时器(避免频繁触发重连)
        private Timer _debounceTimer;

        // 构造函数:初始化WIFI管理器
        // 1. 创建日志记录器
        // 2. 初始化同步事件
        // 3. 获取系统WIFI适配器
        public WifiManager()
        {
            // 创建日志记录器
            _logger = LogDispatcher.LoggerFactory.CreateLogger("WifiManager");
            
            // 初始化云端唤醒事件(非信号状态)
            CloudWakeUpEvent = new AutoResetEvent(false);
            
            // 获取系统中的第一个WIFI适配器
            var adapters = WifiAdapter.FindAllAdapters();
            if (adapters.Length > 0)
            {
                _wifiAdapter = adapters[0];
            }
            else
            {
                throw new Exception("未找到 WIFI 硬件适配器");
            }
        }

        #region STA模式连接

        // 连接到指定的WIFI网络(STA模式)
        public bool ConnectSTA(string ssid, string password, bool enableReconnect = true)
        {
            // 保存连接凭证
            _currentSSID = ssid;
            _currentPassword = password;

            // ========== 连接前检查 ==========
            // 检查是否已经连接(避免重复连接)
            if (IsSTAConnected())
            {
                _logger.LogInformation($"[WifiManager] 已连接到网络,无需重复连接");
                CurrentState = WifiState.Connected;
                
                if (enableReconnect)
                {
                    RegisterNetworkEvents();
                }
                return true;
            }

            // 更新状态为连接中
            CurrentState = WifiState.Connecting;

            // 首次连接,超时15秒
            var firstTryCts = new CancellationTokenSource(15000);
            bool connectResult = ConnectWithHelper(ssid, password, firstTryCts.Token);

            // 根据连接结果更新状态
            CurrentState = connectResult ? WifiState.Connected : WifiState.Reconnecting;

            // 如果启用自动重连
            if (enableReconnect)
            {
                // 注册网络状态变化事件
                RegisterNetworkEvents();

                // 如果首次连接失败,立即启动重连任务
                if (!connectResult)
                {
                    StartReconnectTask();
                }
            }

            return connectResult;
        }

        // 注册网络状态变化事件(事件驱动)
        private void RegisterNetworkEvents()
        {
            // 订阅网络地址变化事件
            NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;

            // 初始化防抖定时器(3秒防抖窗口)
            if (_debounceTimer == null)
            {
                _debounceTimer = new Timer(DebounceAction, null, Timeout.Infinite, Timeout.Infinite);
            }

            _logger.LogInformation("[WifiManager] 已注册防抖网络事件");
        }

        // 取消注册网络事件
        public void UnregisterNetworkEvents()
        {
            NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged;
            _logger.LogInformation("[WifiManager] 已取消网络事件");
        }
        #endregion

        #region 防抖核心逻辑
        // 网络状态变化事件处理函数(防抖入口)
        // 当检测到网络波动时,重置防抖计时器
        private void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
        {
            // AP模式下忽略网络事件
            if (CurrentState == WifiState.APMode)
            {
                return;
            }

            _logger.LogInformation("[WifiManager] 检测到波动,重置3秒计时...");

            // 重置防抖定时器,3秒后执行实际检测
            // 如果3秒内再次触发事件,计时器将被重新设置
            if (_debounceTimer != null)
            {
                _debounceTimer.Change(3000, Timeout.Infinite);
            }
        }

        // 防抖动作 - 防抖窗口结束后执行的实际检测逻辑
        private void DebounceAction(object state)
        {
            // 获取实际连接状态
            bool actuallyConnected = IsSTAConnected();

            // 状态流转判断
            // 场景1:已连接 -> 断开
            if (CurrentState == WifiState.Connected && !actuallyConnected)
            {
                CurrentState = WifiState.Reconnecting;
                _logger.LogWarning("[WifiManager] 确认断开,触发重连...");
                StartReconnectTask();
            }
            // 场景2:连接中/重连中 -> 已连接
            else if ((CurrentState == WifiState.Reconnecting || CurrentState == WifiState.Connecting) && actuallyConnected)
            {
                CurrentState = WifiState.Connected;
                _logger.LogInformation("[WifiManager] 确认恢复!唤醒上云线程...");
                CloudWakeUpEvent.Set(); // 唤醒等待中的云端通信线程
            }
        }
        #endregion

        #region 安全重连核心逻辑
        // 启动安全重连任务
        // 取消之前的重连任务(如果存在),启动新的重连任务
        private void StartReconnectTask()
        {
            // 取消之前的重连任务(如果正在运行)
            if (_reconnectCts != null)
            {
                _reconnectCts.Cancel();
            }

            // 创建新的取消令牌源
            _reconnectCts = new CancellationTokenSource();

            // 在新线程中启动重连任务(nanoFramework不支持ThreadPool和IsBackground)
            Thread reconnectThread = new Thread(() => AttemptReconnect(_reconnectCts.Token));
            reconnectThread.Start();
        }

        // 执行重连尝试(带指数退避策略)
        private void AttemptReconnect(CancellationToken ct)
        {
            int retryCount = 0;                           // 重试次数
            const int maxRetryDelay = 60000;              // 最大重试延迟(60秒)

            // 循环重连,直到连接成功或被取消
            while (CurrentState == WifiState.Reconnecting)
            {
                // 检查是否被取消
                if (ct.IsCancellationRequested)
                {
                    _logger.LogInformation("[WifiManager] 重连任务已被取消");
                    break;
                }

                // 尝试连接
                if (ConnectWithHelper(_currentSSID, _currentPassword, ct))
                {
                    // 连接成功,更新状态并退出循环
                    CurrentState = WifiState.Connected;
                    _logger.LogInformation("[WifiManager] 重连成功!");
                    CloudWakeUpEvent.Set(); // 唤醒云端通信线程
                    break;
                }

                // 计算指数退避延迟:2^n * 2000ms,最大60秒
                int delay = Math.Min((int)Math.Pow(2, retryCount) * 2000, maxRetryDelay);

                _logger.LogWarning($"[WifiManager] 第 {retryCount + 1} 次失败,等待 {delay / 1000} 秒后重试...");

                // 分段等待,每500ms检查一次取消信号
                for (int elapsed = 0; elapsed < delay; elapsed += 500)
                {
                    if (ct.IsCancellationRequested)
                    {
                        _logger.LogInformation("[WifiManager] 等待期间收到取消信号");
                        return;
                    }
                    Thread.Sleep(500);
                }

                retryCount++;
            }
        }
        #endregion

        #region 底层连接辅助
        // 底层连接辅助函数 使用 nanoFramework 内置的 WifiNetworkHelper 进行连接
        private bool ConnectWithHelper(string ssid, string password, CancellationToken ct)
        {
            try
            {
                // 使用内置助手类连接,禁用日期时间检查(嵌入式设备可能没有RTC)
                bool success = WifiNetworkHelper.ConnectDhcp(
                    ssid, 
                    password, 
                    token: ct                 // 取消令牌
                );

                if (success)
                {
                    // 获取并记录分配的IP地址
                    var ip = NetworkInterface.GetAllNetworkInterfaces()[0].IPv4Address;
                    _logger.LogInformation($"[WifiManager] 连接成功,IP: {ip}");
                }

                return success;
            }
            catch (OperationCanceledException)
            {
                // 连接被取消
                _logger.LogInformation("[WifiManager] 连接操作已取消");
                return false;
            }
            catch (Exception ex)
            {
                // ConnectDhcp可能在物理连接成功后因DNS/NTP检查失败而抛异常
                // 需要检查实际连接状态
                _logger.LogWarning($"[WifiManager] ConnectDhcp异常: {ex.Message}");
                
                // 检查实际连接状态
                if (IsSTAConnected())
                {
                    var ip = NetworkInterface.GetAllNetworkInterfaces()[0].IPv4Address;
                    _logger.LogInformation($"[WifiManager] 实际已连接,IP: {ip}");
                    return true;
                }
                
                return false;
            }
        }

        // 检查STA模式是否已连接(带网络可达性检测)
        // 判断条件:
        // 1. 无线STA接口 + 非零IP + 接口状态正常(基本连接)
        // 2. DNS解析成功(网络可达性,确保NTP/MQTT能正常工作)
        private bool IsSTAConnected()
        {
            try
            {
                string deviceIp = null;
                
                // 步骤1:检查基本连接状态
                foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
                {
                    if (nic.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
                    {
                        string ip = nic.IPv4Address.ToString();
                        // nanoFramework中NetworkInterface没有OperationalStatus属性
                        // 仅通过IP地址判断连接状态
                        bool hasValidIP = (ip != "0.0.0.0" && ip != "127.0.0.1");
                        
                        if (hasValidIP)
                        {
                            deviceIp = ip;
                            break;
                        }
                    }
                }

                // 如果基本连接都不满足,直接返回false
                if (string.IsNullOrEmpty(deviceIp))
                {
                    return false;
                }

                // 步骤2:网络可达性检测(DNS解析)
                // 通过解析域名验证网络是否真正可达
                // 这确保后续NTP校时、MQTT等网络操作能正常工作
                if (IsNetworkReachable())
                {
                    _logger.LogInformation($"[WifiManager] STA已连接,IP: {deviceIp},网络可达");
                    return true;
                }
                else
                {
                    _logger.LogWarning($"[WifiManager] STA有IP但网络不可达");
                    return false;
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning($"[WifiManager] 检查连接状态异常: {ex.Message}");
            }
            return false;
        }

        // 网络可达性检测(通过DNS解析验证)
        // 返回true表示网络可达,可以进行NTP校时、MQTT等操作
        private bool IsNetworkReachable()
        {
            try
            {
                // 尝试解析公共DNS域名
                // 使用多个域名提高可靠性
                string[] testDomains = { "www.baidu.com", "time.windows.com", "pool.ntp.org" , "ntp.ntsc.ac.cn", "ntp.aliyun.com" };
                
                foreach (string domain in testDomains)
                {
                    try
                    {
                        _logger.LogInformation($"[WifiManager] 正在检测网络可达性: {domain}");
                        var hostEntry = System.Net.Dns.GetHostEntry(domain);
                        
                        if (hostEntry != null && hostEntry.AddressList != null && hostEntry.AddressList.Length > 0)
                        {
                            _logger.LogInformation($"[WifiManager] DNS解析成功: {domain} -> {hostEntry.AddressList[0]}");
                            return true;
                        }
                    }
                    catch { /* 继续尝试下一个域名 */ }
                }
                
                _logger.LogWarning("[WifiManager] 所有域名解析失败,网络不可达");
                return false;
            }
            catch (Exception ex)
            {
                _logger.LogWarning($"[WifiManager] 网络可达性检测异常: {ex.Message}");
                return false;
            }
        }
        #endregion

        #region AP模式(热点模式)
        // 启动AP热点模式(参考官方WifiAP示例实现)
        // 【配置AP必需的7个关键步骤】:
        // 1. 取消STA相关任务和事件(STA/AP互斥)
        // 2. 彻底关闭STA模式(使用Wireless80211Configuration.Options = None | SmartConfig)
        // 3. 查找WirelessAP网络接口
        // 4. 配置静态IP地址
        // 5. 通过SpecificConfigId获取正确的配置槽
        // 6. 设置AP参数(SSID/密码/认证类型/Options)
        // 7. 启动DHCP服务器(关键!否则AP不会广播SSID)
        // 热点密码(WPA2模式下最少8位)
        // AP静态IP地址(默认192.168.4.1)
        public bool StartAP(string ssid, string password, string ipAddress = "192.168.4.1")
        {
            _logger.LogInformation($"[WifiManager] AP准备启动...");

            // ========== 步骤1:互斥保护 - 取消STA相关任务 ==========
            // STA模式与AP模式互斥,必须先清理STA相关资源
            if (_reconnectCts != null) _reconnectCts.Cancel();
            Thread.Sleep(200);           // 等待任务取消完成
            UnregisterNetworkEvents();   // 取消网络状态监听
            CurrentState = WifiState.APMode;  // 更新状态机

            // ========== 步骤2:彻底关闭STA模式(关键!否则射频冲突) ==========
            // 参考官方Wireless80211.Disable()实现
            // 使用 None | SmartConfig 确保STA完全禁用
            DisableSTAMode();
            Thread.Sleep(300); // 等待射频切换完成

            // ========== 步骤3:查找WirelessAP网络接口 ==========
            NetworkInterface apInterface = null;
            foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
            {
                if (nic.NetworkInterfaceType == NetworkInterfaceType.WirelessAP)
                {
                    apInterface = nic;
                    break;
                }
            }
            if (apInterface == null)
            {
                _logger.LogError("[WifiManager] 未找到AP网络接口");
                return false;
            }

            // ========== 步骤4:配置AP静态IP地址 ==========
            // 参数:IP地址、子网掩码、网关(AP自身作为网关)
            apInterface.EnableStaticIPv4(ipAddress, "255.255.255.0", ipAddress);
            _logger.LogInformation($"[WifiManager] AP接口IP配置完成: {ipAddress}");

            // ========== 步骤5:获取AP配置对象(关键!使用SpecificConfigId) ==========
            // 【重要】必须通过接口的SpecificConfigId获取配置对象
            // 直接new WirelessAPConfiguration(1)可能修改错误的配置槽
            WirelessAPConfiguration apConfig = null;
            try
            {
                WirelessAPConfiguration[] apConfigs = WirelessAPConfiguration.GetAllWirelessAPConfigurations();
                if (apConfigs != null && apConfigs.Length > 0)
                {
                    uint configIdUInt = apInterface.SpecificConfigId;
                    int configId = (int)configIdUInt;
                    apConfig = (configId >= 0 && configId < apConfigs.Length) ? apConfigs[configId] : apConfigs[0];
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning($"[WifiManager] 获取AP配置失败: {ex.Message}");
            }
            if (apConfig == null) apConfig = new WirelessAPConfiguration(0);

            // ========== 步骤6:配置AP热点参数 ==========
            apConfig.Ssid = ssid;                          // 热点名称
            apConfig.Password = password;                  // 热点密码(WPA2需≥8位)
            apConfig.Authentication = AuthenticationType.WPA2;       // 认证类型:WPA2
            apConfig.Encryption = EncryptionType.WPA2_PSK;           // 加密类型:WPA2-PSK
            apConfig.Channel = 6;                          // WIFI信道(信道6兼容性最好)
            apConfig.MaxConnections = 8;                   // 最大连接数
            // 【关键】Options必须同时包含AutoStart和Enable
            // AutoStart: 配置保存后立即启动AP
            // Enable: 启用AP模式
            apConfig.Options = WirelessAPConfiguration.ConfigurationOptions.AutoStart 
                            | WirelessAPConfiguration.ConfigurationOptions.Enable;

            // 保存配置到Flash
            apConfig.SaveConfiguration();
            _logger.LogInformation($"[WifiManager] AP配置已保存,SSID: {ssid}");

            // ========== 步骤7:(关键)启动DHCP服务器(官方示例必需步骤) ==========
            // 官方示例中明确需要启动DHCP服务器,否则AP可能不会广播SSID
            try
            {
                var dhcpServer = new DhcpServer
                {
                    CaptivePortalUrl = "http://" + ipAddress
                };
                bool dhcpStarted = dhcpServer.Start(IPAddress.Parse(ipAddress), new IPAddress(new byte[] { 255, 255, 255, 0 }));
                if (dhcpStarted)
                {
                    _logger.LogInformation("[WifiManager] DHCP服务器启动成功");
                }
                else
                {
                    _logger.LogWarning("[WifiManager] DHCP服务器启动失败,AP可能无法正常工作");
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning($"[WifiManager] 启动DHCP服务器异常: {ex.Message}");
            }

            // 等待AP启动(增加等待时间确保射频模块初始化完成)
            Thread.Sleep(2000);

            // 验证AP是否真正启动
            bool apStarted = VerifyAPStarted(apInterface, ipAddress);
            if (!apStarted)
            {
                // nanoFramework.Runtime.Native.Power.RebootDevice();
                _logger.LogWarning("[WifiManager] AP配置已保存,但射频可能未立即启动");
                _logger.LogWarning("[WifiManager] 建议重启设备以确保AP完全生效");
                // 不强制重启,让用户决定是否重启
            }

            _logger.LogInformation($"[WifiManager] AP启动成功,IP: {ipAddress}");
            return true;

            // 验证AP是否真正启动
            bool VerifyAPStarted(NetworkInterface ni, string expectedIP)
            {
                try
                {
                    // 检查IP是否配置正确
                    if (ni.IPv4Address != expectedIP)
                    {
                        _logger.LogWarning($"[WifiManager] AP IP不匹配: 期望 {expectedIP}, 实际 {ni.IPv4Address}");
                        return false;
                    }

                    // 获取当前AP配置检查Options
                    var currentConfigs = WirelessAPConfiguration.GetAllWirelessAPConfigurations();
                    if (currentConfigs != null && currentConfigs.Length > 0)
                    {
                        uint configId = ni.SpecificConfigId;
                        if (configId < currentConfigs.Length)
                        {
                            var currentConfig = currentConfigs[configId];
                            bool hasAutoStart = (currentConfig.Options & WirelessAPConfiguration.ConfigurationOptions.AutoStart) != 0;
                            bool hasEnable = (currentConfig.Options & WirelessAPConfiguration.ConfigurationOptions.Enable) != 0;
                            
                            if (!hasAutoStart || !hasEnable)
                            {
                                _logger.LogWarning("[WifiManager] AP Options未正确设置");
                                return false;
                            }
                        }
                    }
                    return true;
                }
                catch (Exception ex)
                {
                    _logger.LogWarning($"[WifiManager] 验证AP状态失败: {ex.Message}");
                    return false;
                }
            }
        }

        // 禁用STA模式(参考官方示例Wireless80211.Disable())
        // 使用System.Net.NetworkInformation中的Wireless80211Configuration
        private void DisableSTAMode()
        {
            try
            {
                // 获取STA网络接口
                NetworkInterface staInterface = null;
                foreach (var nic in NetworkInterface.GetAllNetworkInterfaces())
                {
                    if (nic.NetworkInterfaceType == NetworkInterfaceType.Wireless80211)
                    {
                        staInterface = nic;
                        break;
                    }
                }

                if (staInterface != null)
                {
                    // 通过接口的SpecificConfigId获取STA配置(与官方一致)
                    var staConfigs = Wireless80211Configuration.GetAllWireless80211Configurations();
                    if (staConfigs != null && staConfigs.Length > 0)
                    {
                        uint configId = staInterface.SpecificConfigId;
                        Wireless80211Configuration staConfig = staConfigs[configId];
                        
                        // 禁用STA模式(与官方一致:None | SmartConfig)
                        staConfig.Options = Wireless80211Configuration.ConfigurationOptions.None | 
                                           Wireless80211Configuration.ConfigurationOptions.SmartConfig;
                        staConfig.SaveConfiguration();
                        _logger.LogInformation("[WifiManager] STA模式已禁用");
                    }
                }
            }
            catch (Exception ex)
            {
                _logger.LogWarning($"[WifiManager] 禁用STA模式失败: {ex.Message}");
                // 降级方案:断开连接
                try { _wifiAdapter.Disconnect(); } catch { }
            }
        }

        // 关闭AP热点模式(参考官方示例WirelessAP.Disable())
        public void StopAP()
        {
            // 获取当前AP配置
            var configs = WirelessAPConfiguration.GetAllWirelessAPConfigurations();

            if (configs != null && configs.Length > 0)
            {
                // 禁用AP模式(与官方一致:使用None而非Disable)
                configs[0].Options = WirelessAPConfiguration.ConfigurationOptions.None;
                // 保存配置以应用更改
                configs[0].SaveConfiguration();
            }

            // 更新状态为空闲
            CurrentState = WifiState.Idle;
            _logger.LogInformation("[WifiManager] AP 已关闭");
        }
        #endregion

        #region 断开连接
        // 断开STA连接并安全地取消所有相关任务
        public void DisconnectSTA()
        {
            // 取消重连任务
            if (_reconnectCts != null)
            {
                _reconnectCts.Cancel();
            }

            // 取消注册网络事件
            UnregisterNetworkEvents();

            // 断开WIFI连接
            _wifiAdapter.Disconnect();

            // 更新状态为空闲
            CurrentState = WifiState.Idle;

            _logger.LogInformation("[WifiManager] STA 已断开连接");
        }
        #endregion
    }
}

Program.cs

using Microsoft.Extensions.Logging;
using nanoFramework.Logging;
using nanoFramework.Logging.Debug;
using System;
using System.Diagnostics;
using System.Threading;
using WIFI_StaApTest;

namespace WIFI_StaApTest
{
    public class Program
    {
        // STA配置
        const string STA_SSID = "YOUR_WIFI_SSID";
        const string STA_PASSWORD = "YOUR_WIFI_PASSWORD";

        // AP配置
        const string AP_SSID = "YF3300_ESP32S3-AP";
        const string AP_PASSWORD = "12345678";

        private static ILogger _logger;

        public static void Main()
        {
            // 1. 初始化日志工厂(必须先初始化)
            LogDispatcher.LoggerFactory = new DebugLoggerFactory();
            
            // 2. 创建 Logger 实例
            _logger = LogDispatcher.LoggerFactory.CreateLogger("Program");
            
            _logger.LogInformation($"YF3300_ESP32S3 WIFI功能测试");

            // 启用 AP 模式
            TestAPFunction();

            // 启用 STA 模式
            //  TestSTAFunction();

            Thread.Sleep(Timeout.Infinite);
        }

        static void TestSTAFunction()
        {
            _logger.LogInformation($"开始测试STA功能");
            WifiManager wifiManager = new WifiManager();

            bool success = wifiManager.ConnectSTA(STA_SSID, STA_PASSWORD);
            if (!success)
            {
                _logger.LogError($"连接STA失败");
                return;
            }

            Thread.Sleep(Timeout.Infinite);
        }

        // 测试AP功能
        static void TestAPFunction()
        {
            _logger.LogInformation($"开始测试AP功能");
            WifiManager wifiManager = new WifiManager();

            bool success = wifiManager.StartAP(AP_SSID, AP_PASSWORD);

            if (success)
            {
                _logger.LogInformation($"启动AP成功");
            }
            else
            {
                _logger.LogError($"启动AP失败");
            }

            Thread.Sleep(Timeout.Infinite);
        }
    }
}

注意事项

  1. STA/AP 互斥:ESP32 的 WiFi 模块在同一时间只能工作在一种模式,切换模式前需要先禁用当前模式。

  2. 日志初始化:使用日志功能前需要先初始化 LogDispatcher.LoggerFactory

  3. 重连机制:示例中包含了完整的重连机制,包括:

    • 防抖定时器(避免频繁触发重连)
    • 指数退避策略(重试间隔逐渐增加)
    • 取消令牌(安全终止重连任务)
  4. AP 模式配置

    • 密码长度要求:WPA2 模式下最少 8 位
    • 默认 IP 地址:192.168.4.1
    • 必须启动 DHCP 服务器才能正常工作
  5. 网络可达性检测:通过 DNS 解析验证网络是否真正可达,确保后续 NTP、MQTT 等操作能正常工作。

文档链接:https://docs.yfios.net/docs/sdk/yfesp32s3-sdk/wifi-network

posted on 2026-06-10 08:55  刘洪峰AIoT  阅读(51)  评论(0)    收藏  举报