用ESP32打造动态网页仪表盘
手把手教你用Mongoose Wizard打造ESP32动态网页仪表盘(附代码管理秘籍)
引言
在物联网项目中,用ESP32构建一个网页来实时显示传感器数据是非常常见的需求。虽然我们可以手动编写HTML+CSS+JS,但效率和美观度往往难以兼得。Mongoose Wizard 是一个强大的在线可视化工具,只需拖拽组件就能生成完整的ESP32网页仪表盘代码,支持Arduino IDE直接编译。本文将带你从零开始,完成一个能自动刷新动态数据(0~100循环)的仪表盘,并重点解决一个痛点:如何在重新生成UI代码时不丢失手动添加的业务逻辑。
第一部分:Mongoose Wizard快速入门
1. 访问在线工具
打开浏览器,访问 https://mongoose.ws/wizard/
https://mongoose.ws/wizard/。你将看到一个可视化的UI编辑器界面。
2. 设计你的仪表盘
-
从左侧组件库拖拽一个 数值显示卡片 到画布。
-
可以添加一个仪表盘,用于显示速度。

-
选择开发板

-
布局调整满意后,点击右上角的 Generate code 按钮。
第二部分:本地编译与基础配置
1. 解压并打开项目
将下载的.zip文件解压,你会看到一个包含.ino文件和src文件夹的目录。用Arduino IDE打开.ino文件。
2. 添加WiFi连接
编译上传,打开串口监视器,你应该能看到IP地址正常显示。浏览器访问该IP,即可看到你设计的仪表盘(可能需要输入默认用户名密码admin/admin,可后续禁用)。
第三部分:添加动态数据(0~100循环)
现在我们要让仪表盘上的数字自动从0循环到100。Wizard生成的代码中,所有UI组件的数据都由src/mongoose_glue.c中的glue_get_state()函数提供。该函数返回一个结构体,包含所有UI组件的当前值。
1. 在mongoose_glue.c中添加动态变量和更新函数
打开src/mongoose_glue.c,在文件顶部添加全局变量和update函数:
#include <Arduino.h> // 如果还没有,需要包含以使用millis()
static int g_dynamic_value = 0; // 动态值,从0到100循环
void update_dynamic_value() {
static unsigned long lastUpdate = 0;
unsigned long now = millis();
if (now - lastUpdate > 100) { // 每100ms更新一次
lastUpdate = now;
g_dynamic_value++;
if (g_dynamic_value > 100) {
g_dynamic_value = 0;
}
}
}
2. 修改glue_get_state函数
找到glue_get_state(struct state *data)函数,它通常是将静态的s_state复制给data。我们需要用动态值覆盖对应的成员。假设你在Wizard中将数值组件的Key设为dynamic_value,那么结构体中应该有一个同名成员(具体名称取决于Wizard生成,可能是dynamic_value或类似)。安全起见,可以用成员名直接赋值:
void glue_get_state(struct state *data) {
*data = s_state; // 先复制静态初始值
data->dynamic_value = g_dynamic_value; // 用动态值覆盖
}
如果不知道成员的确切名字,可以查看mongoose_glue.h中struct state的定义。
3. 在头文件中声明更新函数
打开src/mongoose_glue.h,在末尾添加:
void update_dynamic_value(void);
4. 在主循环中调用更新函数
修改wizard.ino的loop()函数:
void loop() {
update_dynamic_value(); // 定期更新动态值
mongoose_poll();
}
重新编译上传,再次访问网页,你会发现只有手动刷新页面时数字才会变化。这是因为前端还没有配置自动刷新。
第四部分:实现前端自动刷新
要让浏览器自动获取最新数据,需要在Wizard中为UI组件启用轮询(polling)功能。
1. 重新打开Wizard并加载设计
由于之前的设计保存在浏览器缓存中,再次打开Wizard页面时,你的仪表盘布局应该还在。如果没有,只能重新拖拽组件,并设置相同的Key(dynamic_value)。
2. 配置API端点和自动刷新
-
在Wizard中,点击画布上的数值显示组件。
-
在右侧属性面板中,找到 API Reference 或 Data Source 选项,将其绑定到
state.dynamic_value(这里的state是默认的端点名称,dynamic_value是你的Key)。 -
查找 Auto-refresh 或 Polling interval 选项,将其设置为
1s(或其他你想要的间隔)。 -
如果还有其他组件需要动态更新,同样设置。
3. 重新生成代码并迁移逻辑
点击 Generate code,再次下载Arduino项目压缩包。解压后,将之前手写的动态逻辑文件(即包含g_dynamic_value和update_dynamic_value的代码)复制到新项目。这里建议采用下一节的“代码分离”策略,以避免重复劳动。
4. 编译上传
在新项目的src/mongoose_glue.c中,重新添加#include <Arduino.h>、全局变量和update_dynamic_value函数,并在glue_get_state中覆盖动态值。主循环中调用update_dynamic_value。编译上传后,打开网页,数字就会自动跳动,无需手动刷新!
第五部分:终极方案——分离UI与业务逻辑(避免代码丢失)
每次修改UI都要重新生成代码,然后重复复制手写逻辑,非常繁琐。推荐采用分离架构,将你的核心业务逻辑独立出来,Wizard生成的代码只负责“粘合”。
1. 创建业务逻辑文件
在项目根目录新建两个文件:app_logic.h 和 app_logic.cpp。
app_logic.h
#ifndef APP_LOGIC_H
#define APP_LOGIC_H
#include <Arduino.h>
extern int g_dynamic_value; // 声明全局变量
void update_dynamic_value(); // 声明更新函数
#endif
app_logic.cpp
#include "app_logic.h"
int g_dynamic_value = 0;
void update_dynamic_value() {
static unsigned long lastUpdate = 0;
unsigned long now = millis();
if (now - lastUpdate > 100) {
lastUpdate = now;
g_dynamic_value++;
if (g_dynamic_value > 100) g_dynamic_value = 0;
}
}
2. 修改mongoose_glue.c引用业务逻辑
在src/mongoose_glue.c顶部添加:
#include "app_logic.h"
在glue_get_state中,用g_dynamic_value赋值:
data->dynamic_value = g_dynamic_value;
3. 在主循环中调用更新
wizard.ino保持不变,仍调用update_dynamic_value()。
4. 未来更新流程
-
在Wizard中修改UI → 重新生成代码 → 解压新项目。
-
将旧的
app_logic.h和app_logic.cpp复制到新项目根目录。 -
在新
mongoose_glue.c中添加#include "app_logic.h",恢复赋值代码(可提前备份赋值语句,直接粘贴)。 -
编译上传,所有业务逻辑完好无损!
总结与进阶
现在,你可以在此基础上扩展更多功能:接入真实传感器(如DHT22)、添加图表、通过开关控制设备等。Mongoose Wizard还支持OTA更新、用户认证等高级特性,值得深入探索。
提示:Wizard的项目数据存储在浏览器缓存中,如果需要永久保存设计,可以导出为JSON文件或定期备份屏幕截图和Key配置。
更多推荐
所有评论(0)