项目教程 开源项目 教程 Galeros OpenIris ESP32 固件使用教程 彩咖工作室 2026-05-01 2026-07-12 Galeros OpenIris ESP32 固件开发和使用教程
本文详细介绍了基于 ESP32 的 OpenIris 摄像头固件二次开发项目,说明了网页配网系统和实时 Web 日志监控的实现方法。
更新日志 :
2026-07-12 : 日志系统重构 :废弃旧的”三通道”日志体系(ESP_LOG / Serial / SendLogToWeb),引入统一的 GLogManager + GLOG 宏,一次调用同时输出到串口和 Web;新增日志级别过滤功能;修复了 Serial.available() 相关误解。
本节详细介绍如何在 VSCode 中配置 PlatformIO 开发环境,并完成固件编译与烧录。
0.1 安装 Visual Studio Code
访问 VS Code 官网 下载并安装 VS Code
启动 VS Code,点击左侧扩展图标(或按 Ctrl+Shift+X)
图 0-1 :VS Code 左侧扩展图标位置
在扩展搜索框中输入 PlatformIO
找到 PlatformIO IDE 插件,点击安装
图 0-2 :搜索并安装 PlatformIO 插件
安装完成后,点击 Reload Now 重启 VS Code
图 0-3 :PlatformIO 安装完成,点击 Reload Now
0.3 打开项目并编译
打开 VS Code,点击 File → Open Folder
选择项目根目录 Openiris_esp32_aithinker
图 0-4 :打开项目文件夹
等待 PlatformIO 自动下载依赖(首次可能需要 1-3 分钟)
图 0-5 :PlatformIO 正在下载依赖
依赖下载完成后,在底部找到 PlatformIO 图标,点击展开菜单
图 0-6 :点击底部 PlatformIO 菜单
点击 Build (或按 Ctrl+Alt+B)开始编译
图 0-7 :点击 Build 开始编译
编译成功后会看到类似输出:
1 2 3 4 5 6 7 Advanced Memory usage is available via "Build" ================================================ INFO: Successfully burned binary to flash Environment Status Duration -------------------- --------- -------- esp32AIThinker SUCCESS 00:01:32 ================================================
图 0-8 :编译成功输出
0.4 烧录固件到开发板
用 USB 线连接 ESP32 开发板到电脑
在 PlatformIO 菜单中点击 Upload (或按 Ctrl+Alt+U)
图 0-9 :点击 Upload 烧录固件
烧录过程中开发板上的指示灯会闪烁
烧录成功后设备会自动重启
图 0-10 :烧录成功提示
一、项目背景与目标 在 ESP32 开发中,WiFi 配置一直是开发者头痛的问题。传统方式需要:
硬编码 WiFi 凭证 → 每次换环境要重新烧录
串口终端手动输入 → 依赖电脑工具
BLE 配网 → 需要额外 App
Galeros OpenIris 正是为解决这些痛点而生的二次开发固件。项目目标非常明确:
让 ESP32 设备开箱即用,通过浏览器即可完成 WiFi 配置,并实时监控设备运行日志。
二、核心功能架构 2.1 智能网页配网系统 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 ┌─────────────────────────────────────────────────────────┐ │ 首次上电流程 │ ├─────────────────────────────────────────────────────────┤ │ │ │ 设备上电 ──→ 检查 NVS 中是否有保存的 WiFi │ │ │ │ │ ┌─────────┴─────────┐ │ │ ▼ ▼ │ │ 已保存 WiFi 无保存 WiFi │ │ │ │ │ │ ▼ ▼ │ │ 尝试连接 ──→ 失败 ──→ 开启 AP 热点 │ │ │ │ │ ▼ │ │ SSID: Galeros_ESP32 │ │ 密码: Galeros_ESP32 │ │ │ │ │ ▼ │ │ 浏览器自动弹出配网页面 │ │ (Captive Portal) │ │ │ │ │ ▼ │ │ 用户输入 WiFi 信息并提交 │ │ │ │ │ ▼ │ │ 保存到 NVS 分区,重启设备 │ │ │ └─────────────────────────────────────────────────────────┘
图 2-1 :首次配网时连接 AP 热点后浏览器自动弹出的配网页面
配网成功后,设备会重启并连接 WiFi。此后可通过以下地址访问配置管理页面:
图 2-2 :STA 模式下访问 http://设备IP:8080 看到的配置管理页面,可查看当前连接的 WiFi 并重新配置
关键实现代码 (main.cpp ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 void etvr_eye_tracker_web_init () { WiFi.disconnect (true ); WiFi.mode (WIFI_STA); wifiHandler.begin (); delay (1000 ); if (WiFi.isConnected ()) { mdnsHandler.startMDNS (); streamServer.startStreamServer (); apiServer.setup (); configServer = new AsyncWebServer (CONFIG_PORT); setupConfigServer (false ); configServer->begin (); } else { WiFi.mode (WIFI_AP); WiFi.softAP (AP_SSID, AP_PASSWORD); WiFi.softAPConfig (apIP, apIP, IPAddress (255 , 255 , 255 , 0 )); dnsServer.start (DNS_PORT, "*" , apIP); configServer = new AsyncWebServer (80 ); setupConfigServer (true ); configServer->begin (); isInAPMode = true ; } }
2.2 实时 Web 日志监控(重构版) 日志系统进行了彻底重构。旧版存在三条互不相通的日志通道——Serial.printf(只到串口)、log_i/log_d(ESP_LOG 通道,Web 回调有 bug)、SendLogToWeb()(只到 Web)——导致开发者需要手动调用两个不同的函数才能实现”串口 + Web”双输出。
新版引入了统一日志管理器 GLogManager ,架构如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 ┌────────────────────────────────────────────────────────────┐ │ GLog 统一日志架构 │ ├────────────────────────────────────────────────────────────┤ │ │ │ ┌──────────────────────────────────────────────────────┐ │ │ │ 代码中任何位置 │ │ │ │ GLOG_D("TAG", "msg %d", val) │ │ │ │ GLOG_I("TAG", "msg") │ │ │ │ GLOG_W("TAG", "msg") │ │ │ │ GLOG_E("TAG", "msg") │ │ │ └──────────────────────┬───────────────────────────────┘ │ │ │ │ │ ┌──────────────┴──────────────┐ │ │ ▼ ▼ │ │ ┌──────────────┐ ┌──────────────┐ │ │ │ 串口输出 │ │ Web SSE 推送 │ │ │ │ 带 ANSI 颜色 │ │ (端口 1234) │ │ │ │ [信息][WIFI] │ │ │ │ │ └──────────────┘ └──────────────┘ │ │ │ │ 两条输出均由 GLogManager::send() 统一管理 │ │ 自动级别过滤:低于 LOG_LEVEL 的日志静默丢弃 │ │ │ └────────────────────────────────────────────────────────────┘
核心实现 (log_manager.cpp ):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 void GLogManager::send (GLogLevel level, const char * tag, const String& msg) { if (level < _minLevel) return ; Serial.printf ("%s[%s][%s] %s%s\n" , ansiColor (level), levelPrefix (level), tag, msg.c_str (), ansiReset ()); if (webReady && _webCallback) { String webMsg = "[" + String (levelPrefix (level)) + "][" + String (tag) + "] " + msg; _webCallback(webMsg); } }
便捷宏 (log_manager.hpp ):
1 2 3 4 #define GLOG_D(tag, fmt, ...) GLogManager::instance().log(GLogLevel::DEBUG, tag, fmt, ##__VA_ARGS__) #define GLOG_I(tag, fmt, ...) GLogManager::instance().log(GLogLevel::INFO, tag, fmt, ##__VA_ARGS__) #define GLOG_W(tag, fmt, ...) GLogManager::instance().log(GLogLevel::WARN, tag, fmt, ##__VA_ARGS__) #define GLOG_E(tag, fmt, ...) GLogManager::instance().log(GLogLevel::ERROR, tag, fmt, ##__VA_ARGS__)
使用示例 :
1 2 3 GLOG_I ("SETUP" , "WiFi connected" );
三、技术实现详解 3.1 配网页面实现 使用 AsyncWebServer 构建轻量级 Web 服务器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 configServer->on ("/" , HTTP_GET, [](AsyncWebServerRequest *request) { request->send (200 , "text/html, charset=utf-8" , ap_config_html); }); configServer->on ("/save" , HTTP_POST, [](AsyncWebServerRequest *request) { String ssid = request->getParam ("ssid" , true )->value (); String pass = request->getParam ("password" , true )->value (); deviceConfig.setWifiConfig ("main" , ssid.c_str (), pass.c_str (), 0 , 52 , false , true ); request->send (200 , "text/plain, charset=utf-8" , "配置已保存!设备即将重启..." ); delay (2500 ); ESP.restart (); });
3.2 Captive Portal 自动弹出 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 class CaptiveRequestHandler : public AsyncWebHandler {public : bool canHandle (AsyncWebServerRequest *request) { return true ; } void handleRequest (AsyncWebServerRequest *request) { request->redirect ("http://" + apIP.toString ()); } }; if (isAP) { configServer->addHandler (new CaptiveRequestHandler ()) .setFilter (ON_AP_FILTER); }
3.3 日志级别过滤系统 GLogManager 内置四级日志过滤,用户通过 main.cpp 顶部的 LOG_LEVEL 变量控制全局输出:
LOG_LEVEL 值
输出内容
GLogLevel::DEBUG
全部日志(调试 + 信息 + 警告 + 错误)
GLogLevel::INFO
信息 + 警告 + 错误(调试日志被跳过)
GLogLevel::WARN
警告 + 错误
GLogLevel::ERROR
仅错误
1 2 3 4 5 const GLogLevel LOG_LEVEL = GLogLevel::DEBUG; GLogManager::instance ().setLevel (LOG_LEVEL);
实战场景 :
开发调试阶段 → DEBUG(输出所有细节,包括每10秒的内存报告)
正式部署 → INFO(只保留关键信息,loop 中的调试输出自动静默)
3.4 Web SSE 桥接 1 2 3 4 5 6 7 8 9 10 11 12 void setupGLogWebCallback () { auto logCallback = [](const String &msg) { if (events != nullptr && msg.length () > 0 ) { events->send (msg.c_str (), nullptr , millis ()); } }; GLogManager::instance ().setWebCallback (logCallback); } GLogManager::instance ().webReady = true ;
✅ 已修复 :旧版 esp_log_set_vprintf 回调不工作的问题已通过架构重构彻底解决。新方案不依赖 ESP_LOG 拦截,而是由 GLOG 宏直接分发到串口和 Web 两端,不再有递归风险或通道遗漏。
四、使用教程 4.1 首次配网步骤
步骤
操作
1
设备上电,若无保存 WiFi 会自动开启热点
2
手机/电脑连接 Galeros_ESP32(密码相同)
3
浏览器自动弹出配网页面,或访问 192.168.4.1
4
输入家用 WiFi 名称和密码
5
点击「保存并重启」
6
设备自动重启并连接 WiFi
4.2 访问服务 1 2 3 4 5 6 7 8 9 ┌────────────────────────┬──────────────────────────────┐ │ 功能 │ 访问地址 │ ├────────────────────────┼──────────────────────────────┤ │ Web 日志监控 │ http://设备IP:1234 │ │ 配置管理页面 │ http://设备IP:8080 │ │ 视频流地址 │ http://设备IP/ │ │ REST API │ http://设备IP:81/control/... │ │ mDNS 访问 │ http://Galeros-ESP32.local │ └────────────────────────┴──────────────────────────────┘
图 4-1 :访问 http://设备IP:1234 看到的实时 Web 日志监控页面,可实时查看设备运行日志
五、项目结构 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Galeros-ESP/ ├── src/ │ ├── main.cpp # ★ 主程序入口(启动流程、Web服务、用户配置) │ └── html_content.h # HTML 页面(配网页、管理页、日志页) ├── lib/src/ │ ├── openiris.hpp # 主头文件 │ ├── data/ │ │ ├── utilities/ │ │ │ ├── log_manager.hpp/.cpp # ★ 统一日志管理器 (新增) │ │ │ ├── Observer.hpp # 观察者模式 │ │ │ ├── helpers.hpp/.cpp # 通用工具 │ │ │ └── network_utilities.hpp/.cpp │ │ ├── CommandManager/ # 命令管理(JSON 解析) │ │ ├── config/ # 配置管理(NVS 持久化) │ │ └── StateManager/ # 全局状态机 │ ├── io/ │ │ ├── Serial/ # 串口管理 │ │ ├── LEDManager/ # LED 状态指示 │ │ └── camera/ # 摄像头 │ └── network/ │ ├── wifihandler/ # WiFi 处理 │ ├── api/ # REST API (端口 81) │ ├── stream/ # MJPEG 视频流 (端口 80) │ └── mDNS/ # mDNS 服务 ├── ini/ # 配置文件 │ ├── boards.ini # 开发板定义 │ ├── pinouts.ini # 摄像头引脚映射 │ └── user_config.ini # 用户配置 ├── platformio.ini # PlatformIO 主配置 └── CLAUDE.md # 项目文档(AI 友好)
六、用户可配置参数 在 main.cpp 顶部的「用户自定义配置修改区域」可修改以下参数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 const GLogLevel LOG_LEVEL = GLogLevel::DEBUG; const char *AP_SSID = "Galeros_ESP32" ; const char *AP_PASSWORD = "Galeros_ESP32" ; const uint16_t CONFIG_PORT = 8080 ; const uint16_t LOG_PORT = 1234 ; const char *MDNS_HOSTNAME = "Galeros-ESP32" ;const uint8_t WIFI_CHANNEL = 1 ;const bool ENABLE_ADHOC = false ;
七、已解决问题 & 待办事项 ✅ 已解决
问题
解决方案
日志回调系统 bug(esp_log_set_vprintf 不工作)
废弃 ESP_LOG 拦截,统一为 GLogManager + GLOG 宏
旧版三通道日志分裂(Serial.printf / log_i / SendLogToWeb 互不相通)
全部统一为 GLOG 宏,一次调用 → 串口 + Web 双输出
日志级别过滤
LOG_LEVEL 变量全局控制,四级可调
中文化日志前缀
级别前缀改为中文:[调试]、[信息]、[警告]、[错误]
⬜ 待实现
八、总结 Galeros OpenIris 为 ESP32 开发者提供了一个开箱即用 的配网 + 日志解决方案:
✅ 配网系统
无需硬编码 WiFi,浏览器一键配网
Captive Portal 自动弹出配网页
配置保存在 NVS,重启后依然有效
美化后的配网和管理界面
✅ 日志系统(重构)
统一的 GLogManager,一次 GLOG_I() 同时输出到串口和 Web
四级日志过滤(DEBUG/INFO/WARN/ERROR),一行配置全局生效
串口输出带 ANSI 颜色,中文级别前缀
Web SSE 实时推送,浏览器打开日志页即可监控
不再需要手动调用 SendLogToWeb()——GLOG 自动覆盖
⚠️ 需要注意
首次使用必须通过 AP 配网方式配置 WiFi
调试时建议 LOG_LEVEL = DEBUG,部署后改为 INFO 以减少串口输出
日志级别颜色区分功能正在实现中..
项目地址 :https://github.com/mayan613/Openiris_esp32_aithinker
欢迎 Star 和 Issue!
许可证: 本项目基于 MIT 许可证开源。