| 本帖最后由 Moone 于 2025-10-3 18:36 编辑 
 WiFi网络状态监测器项目概述
 本项目是一个基于FireBeetle 2 ESP32-C5开发套件和OLED显示屏的WiFi网络状态监测器,实时显示网络连接状态、信号质量、时间信息等,具有多页面显示和动画切换效果。
 系统整体流程图
 
 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图1](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/180816dtd6zt66zfpnggvt.png) 流程说明系统启动阶段
 
 连接结果处理初始化硬件:配置OLED显示屏引脚和通信参数,设置串口通信显示欢迎界面:展示设备名称、版本信息,建立品牌认知连接WiFi:尝试连接到预设的WiFi网络,包含超时处理机制
 
 主循环处理核心连接成功:配置NTP时间服务,确保时间同步准确连接失败:显示错误提示,但系统继续运行以便后续重连
 
 详细功能流程图说明非阻塞设计:所有任务基于时间间隔执行,避免单个任务阻塞系统模块化处理:各功能模块独立运行,通过标志位协调状态驱动更新:只有状态变化时才触发显示更新,优化性能
 项目结构
 WiFi_Monitor/
 ├── WiFi_Monitor.ino # 主程序文件
 ├── WiFiConnection.h # WiFi连接管理模块
 ├── DisplayManager.h # 显示控制模块
 ├── NetworkTest.h # 网络测试模块
 ├── TimeManager.h # 时间管理模块
 ├── Configuration.h # 配置参数模块
 └── README.md # 项目说明文档
 系统初始化流程
 
 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图7](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/180858f090x01o0tfva11h.png) 功能模块详细说明
 1. 配置参数模块 (Configuration.h)
 
 2. WiFi连接管理模块 (WiFiConnection.h)复制代码/**
 * 系统配置参数定义
 * 包含WiFi配置、设备个性化设置、时间配置等常量
 */
// WiFi网络配置
const char* WIFI_SSID = "WiFi名称";      // 替换为您的WiFi名称
const char* WIFI_PWD = "WiFi密码";       // 替换为您的WiFi密码
// 设备个性化设置
const char* DEVICE_NAME = "Moone Monitor";
const char* OWNER_NAME = "Moone";
// NTP时间服务器配置
const char* ntpServer = "pool.ntp.org";
const long gmtOffset_sec = 8 * 3600;        // UTC+8 北京时间
const int daylightOffset_sec = 0;
// 硬件引脚配置
#define I2C_SDA 9
#define I2C_SCL 10
// 时间间隔配置(毫秒)
const unsigned long PING_INTERVAL = 8000;           // Ping测试间隔
const unsigned long WIFI_UPDATE_INTERVAL = 2000;    // WiFi状态更新间隔
const unsigned long DISPLAY_UPDATE_INTERVAL = 500;  // 显示更新间隔
const unsigned long PAGE_CHANGE_INTERVAL = 8000;    // 页面切换间隔
const unsigned long WELCOME_DURATION = 3000;        // 欢迎界面显示时长
const unsigned long UPTIME_UPDATE_INTERVAL = 1000;  // 运行时间更新间隔
 
 WiFi状态转换说明复制代码/**
 * WiFi连接管理模块
 * 负责WiFi连接、状态监测和重连管理
 */
class WiFiConnectionManager {
private:
    // 网络状态变量
    int wifiRSSI = 0;                    // WiFi信号强度
    String ipAddress = "No IP";          // IP地址
    bool wifiConnected = false;          // 连接状态标志
    
    // 时间管理
    unsigned long lastWiFiUpdate = 0;    // 上次WiFi状态更新时间
    
public:
    /**
     * 连接到WiFi网络
     * 显示连接过程动画,支持超时处理
     */
    void connectToWiFi() {
        displayConnectingScreen(0);
        WiFi.begin(WIFI_SSID, WIFI_PWD);
        
        unsigned long startTime = millis();
        int dotCount = 0;
        
        // 20秒连接超时
        while (WiFi.status() != WL_CONNECTED && millis() - startTime < 20000) {
            delay(300);
            dotCount = (dotCount + 1) % 4;
            displayConnectingScreen(dotCount);
        }
        
        if (WiFi.status() == WL_CONNECTED) {
            onWiFiConnected();
        } else {
            onWiFiFailed();
        }
    }
    
    /**
     * WiFi连接成功处理
     * 更新状态变量并显示成功界面
     */
    void onWiFiConnected() {
        wifiConnected = true;
        ipAddress = WiFi.localIP().toString();
        wifiRSSI = WiFi.RSSI();
        
        displaySuccessScreen();
        Serial.println("WiFi Connected - IP: " + ipAddress);
    }
    
    /**
     * WiFi连接失败处理
     * 显示错误界面并设置连接状态为false
     */
    void onWiFiFailed() {
        wifiConnected = false;
        displayErrorScreen();
        Serial.println("WiFi Connection Failed");
    }
    
    /**
     * 更新WiFi连接状态
     * 定期检查连接状态,处理断开重连情况
     */
    void updateWiFiStatus() {
        bool previousStatus = wifiConnected;
        wifiConnected = (WiFi.status() == WL_CONNECTED);
        
        if (wifiConnected) {
            // 更新信号强度(变化超过2dBm才更新)
            int newRSSI = WiFi.RSSI();
            if (abs(newRSSI - wifiRSSI) > 2) {
                wifiRSSI = newRSSI;
                displayNeedsUpdate = true;
            }
            ipAddress = WiFi.localIP().toString();
            
            // WiFi重连处理
            if (!previousStatus) {
                Serial.println("WiFi Reconnected");
                displayNeedsUpdate = true;
            }
        } else if (previousStatus) {
            // WiFi断开处理
            Serial.println("WiFi Disconnected");
            displayNeedsUpdate = true;
        }
    }
    
    // Getter方法
    bool isConnected() { return wifiConnected; }
    int getRSSI() { return wifiRSSI; }
    String getIP() { return ipAddress; }
};
 
 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图6](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/180858lrr6b5fxrf6axat5.png) 连接生命周期
 
 状态持久性完整状态机:覆盖从初始到连接的完整流程异常处理:处理各种连接失败场景自动恢复:连接断开后自动尝试重连
 
 这个详细的流程图说明文档完整地解释了WiFi网络状态监测器的程序架构、设计理念和实现细节,为后续的维护、扩展和故障排查提供了完整的技术参考。状态记忆:系统记住当前连接状态条件执行:基于连接状态决定功能可用性用户反馈:每个状态变化都有相应的用户提示
 WiFi连接管理流程说明
 流程图概述
 
 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图4](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/180857fdlognuidwp5twnt.png) 连接过程设计说明用户反馈优化
 
 超时管理策略动态指示:通过动态点动画显示连接进行中状态进度感知:每300ms更新一次界面,让用户感知系统运行明确结果:成功或失败都有明确的视觉反馈
 
 信息记录合理超时:20秒超时时间平衡了连接成功率和用户体验** graceful失败**:连接失败后系统继续运行,支持后续手动恢复
 
 3. 显示控制模块 (DisplayManager.h)关键数据保存:连接成功后立即保存IP地址和信号强度状态同步:确保显示数据与实际连接状态一致
 
 显示页面管理流程说明复制代码/**
 * 显示控制模块
 * 管理OLED显示屏的所有绘制操作和页面管理
 */
class DisplayManager {
private:
    U8G2_SSD1306_128X64_NONAME_F_SW_I2C u8g2;
    
    // 显示状态
    int displayPage = 0;                 // 当前显示页面
    bool displayNeedsUpdate = true;      // 显示更新标志
    bool showWelcome = true;             // 欢迎界面显示标志
    
    // 动画状态
    bool isAnimating = false;
    int previousPage = 0;
    unsigned long animationStartTime = 0;
    
public:
    DisplayManager() : u8g2(U8G2_R0, 10, 9, U8X8_PIN_NONE) {}
    
    /**
     * 初始化OLED显示屏
     * 设置字体、颜色等基础参数
     */
    void begin() {
        u8g2.begin();
        u8g2.setFont(u8g2_font_6x10_tf);
        u8g2.setFontRefHeightExtendedText();
        u8g2.setDrawColor(1);
        u8g2.setFontPosTop();
        u8g2.setFontDirection(0);
        Serial.println("OLED Display Initialized");
    }
    
    /**
     * 显示欢迎界面
     * 设备启动时显示设备名称和版本信息
     */
    void showWelcomeScreen() {
        u8g2.firstPage();
        do {
            u8g2.setFont(u8g2_font_7x14_tf);
            u8g2.drawStr(15, 10, DEVICE_NAME);
            
            u8g2.setFont(u8g2_font_6x10_tf);
            u8g2.drawStr(25, 30, "Initializing...");
            u8g2.drawStr(20, 45, "WiFi Monitor v2.0");
        } while (u8g2.nextPage());
    }
    
    /**
     * 显示WiFi连接过程界面
     * 带动态点动画显示连接状态
     */
    void displayConnectingScreen(int dotCount) {
        u8g2.firstPage();
        do {
            u8g2.drawStr(20, 15, "Connecting WiFi");
            
            // 动态点动画
            char dots[5] = "...";
            dots[dotCount] = '\0';
            u8g2.drawStr(55, 35, dots);
            u8g2.drawStr(25, 50, "Please wait");
        } while (u8g2.nextPage());
    }
    
    /**
     * 显示连接成功界面
     * 显示IP地址和信号强度
     */
    void displaySuccessScreen() {
        u8g2.firstPage();
        do {
            u8g2.drawStr(40, 15, "Connected!");
            
            String shortIP = getShortIP(ipAddress);
            u8g2.drawStr(10, 35, shortIP.c_str());
            
            char signalStr[15];
            snprintf(signalStr, sizeof(signalStr), "%d dBm", wifiRSSI);
            u8g2.drawStr(45, 50, signalStr);
        } while (u8g2.nextPage());
    }
    
    /**
     * 显示状态页面
     * 包含WiFi状态、信号强度、Ping延迟、IP地址和时间
     */
    void displayStatusPage() {
        u8g2.firstPage();
        do {
            char wifiStatus[20];
            snprintf(wifiStatus, sizeof(wifiStatus), "WiFi:%s", 
                     wifiConnected ? "ON" : "OFF");
            
            char signalStr[15];
            snprintf(signalStr, sizeof(signalStr), "Sig:%ddBm", wifiRSSI);
            
            char pingStr[15];
            snprintf(pingStr, sizeof(pingStr), "Ping:%s", 
                     pingTime > 0 ? String(pingTime) + "ms" : "--ms");
            
            String shortIP = getShortIP(ipAddress);
            String currentTime = getCurrentTime();
            
            // 紧凑的5行布局
            u8g2.setCursor(0, 2);
            u8g2.print(wifiStatus);
            u8g2.setCursor(64, 2);
            u8g2.print(signalStr);
            
            u8g2.setCursor(0, 14);
            u8g2.print(pingStr);
            
            u8g2.setCursor(0, 26);
            u8g2.print(shortIP.c_str());
            
            u8g2.setCursor(0, 38);
            u8g2.print("Time:");
            u8g2.setCursor(30, 38);
            u8g2.print(currentTime.c_str());
            
            u8g2.setCursor(0, 50);
            u8g2.print("Page 1/3");
        } while (u8g2.nextPage());
    }
    
    /**
     * 处理页面切换动画
     * 实现平滑的页面切换效果
     */
    void handleAnimation() {
        unsigned long elapsed = millis() - animationStartTime;
        float progress = (float)elapsed / 400;
        
        if (progress > 1.0) {
            isAnimating = false;
            return;
        }
        
        int offset = (progress < 0.5) ? 
                   (int)(64 * (0.5 - progress) * 2) : 
                   (int)(64 * (progress - 0.5) * 2);
        
        u8g2.firstPage();
        do {
            if (progress < 0.5) {
                displayPageContent(previousPage, 0, offset);
            } else {
                displayPageContent(displayPage, 0, offset - 64);
            }
        } while (u8g2.nextPage());
    }
    
    // 其他显示相关方法...
};
 流程图概述
 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图2](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/180857o57eoc15o11kku5z.png) 显示系统架构说明优先级管理
 
 页面切换动画欢迎界面优先:系统启动时优先显示欢迎界面动画优先:页面切换动画期间暂停常规内容更新状态驱动:根据系统状态选择显示内容
 
 三页面内容设计平滑过渡:400ms动画时长提供舒适的视觉体验双向滑动:前半段移出旧页面,后半段移入新页面精确控制:基于时间进度的精确动画控制
 
 布局优化状态页面:核心网络参数实时监控质量页面:网络质量分析和评级个人页面:个性化信息和设备状态
 
 4. 网络测试模块 (NetworkTest.h)5行紧凑布局:充分利用128x64像素显示区域信息分层:重要信息突出显示,次要信息适当位置一致性设计:各页面保持统一的布局风格
 
 网络测试流程说明复制代码/**
 * 网络测试模块
 * 负责网络连通性测试和延迟测量
 */
class NetworkTestManager {
private:
    int pingTime = 0;                    // Ping延迟时间
    unsigned long lastPingTime = 0;      // 上次Ping测试时间
    
public:
    /**
     * 异步执行Ping测试
     * 测试多个服务器的连通性,取最快响应时间
     */
    void performPingTestAsync() {
        HTTPClient http;
        
        // 测试服务器列表
        const char* servers[] = {
            "http://www.bing.com",
            "http://www.qq.com", 
            "http://www.baidu.com"
        };
        
        bool success = false;
        
        // 尝试多个服务器,直到成功或全部失败
        for (int i = 0; i < 3 && !success; i++) {
            http.begin(servers[i]);
            http.setTimeout(2000);  // 2秒超时
            
            unsigned long startTime = millis();
            int httpCode = http.GET();
            unsigned long responseTime = millis() - startTime;
            
            if (httpCode > 0) {
                updatePingTime(responseTime);
                success = true;
            }
            
            http.end();
            if (!success && i < 2) delay(100); // 服务器间短暂延迟
        }
        
        if (!success) {
            pingTime = -1;  // 测试失败
            displayNeedsUpdate = true;
        }
    }
    
    /**
     * 更新Ping时间
     * 只有变化超过10ms才触发显示更新
     */
    void updatePingTime(unsigned long responseTime) {
        int newPingTime = responseTime;
        if (abs(newPingTime - pingTime) > 10) {
            pingTime = newPingTime;
            displayNeedsUpdate = true;
        }
    }
    
    /**
     * 获取网络质量评级
     * 基于信号强度和延迟的综合评价
     */
    String getOverallRating() {
        if (!wifiConnected) return "Offline";
        
        int score = 0;
        
        // 信号强度评分
        if (wifiRSSI >= -55) score += 2;
        else if (wifiRSSI >= -65) score += 1;
        
        // 延迟评分
        if (pingTime > 0 && pingTime < 100) score += 2;
        else if (pingTime > 0 && pingTime < 200) score += 1;
        
        // 综合评级
        if (score >= 4) return "Excel";
        else if (score >= 3) return "Good";
        else if (score >= 2) return "Fair";
        else return "Poor";
    }
    
    // Getter方法
    int getPingTime() { return pingTime; }
};
 流程图概述
 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图5](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/180858rspqztitip5esstp.png) 网络测试策略说明多服务器容错机制
 
 性能优化设计服务器多样性:选择不同服务商的服务器提高测试可靠性顺序测试:依次测试直到成功,避免不必要的并行请求智能切换:当前服务器失败后自动切换到下一个
 
 用户体验考虑合理超时:2秒超时平衡了响应速度和成功率变化检测:只有显著变化(>10ms)才触发显示更新服务器间延时:100ms间隔避免请求过于密集
 
 5. 时间管理模块 (TimeManager.h)快速失败:单个服务器快速超时,整体测试时间可控明确状态:成功和失败都有明确的状态标识渐进式反馈:通过显示更新向用户反馈测试结果
 
 时间管理流程说明复制代码
 流程图概述
 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图3](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/180857m8xmtg8htjegnegg.png) 时间系统设计说明NTP时间同步
 
 运行时间统计自动配置:WiFi连接成功后自动配置时间服务时区支持:支持UTC+8北京时间配置容错处理:时间获取失败时提供默认值显示
 
 智能问候系统精确计时:基于millis()的精确运行时间计算友好显示:自动在小时和分钟格式间切换低开销:每秒更新一次,性能开销极小
 
 错误处理机制时间段划分:按早晨、下午、晚上、深夜四个时段个性化消息:每个时段提供相应的问候语自动更新:每小时检查更新,确保问候语及时性
 
 6. 主程序模块 (WiFi_Monitor.ino)优雅降级:NTP服务不可用时显示默认时间状态保持:运行时间统计不受网络状态影响用户透明:时间显示异常时用户仍可获取基本功能
 
 硬件要求复制代码
 
 使用说明FireBeetle 2 ESP32-C5开发套件0.96寸OLED显示屏(SSD1306,128x64)WiFi网络接入
 
 实物照片修改Configuration.h中的WiFi配置根据需要调整设备个性化设置上传程序到FireBeetle 2 ESP32-C5开发套件设备将自动连接WiFi并开始监测
 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图8](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/182634hes6dgy942jqng6k.jpg) 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图9](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/182634qmpxtzfsxcwprfpn.jpg) 
 ![[FireBeetle 2 ESP32-C5]ESP32-C5 WiFi网络状态监测器图10](https://mc.dfrobot.com.cn/data/attachment/forum/202510/03/182634actaup2aiieaeacp.jpg) 
 
 
 
 
 |