手把手教你用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.hstruct state的定义。

3. 在头文件中声明更新函数

打开src/mongoose_glue.h,在末尾添加:

        void update_dynamic_value(void);

4. 在主循环中调用更新函数

修改wizard.inoloop()函数:

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_valueupdate_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.happ_logic.cpp复制到新项目根目录。

  • 在新mongoose_glue.c中添加#include "app_logic.h",恢复赋值代码(可提前备份赋值语句,直接粘贴)。

  • 编译上传,所有业务逻辑完好无损!


总结与进阶

现在,你可以在此基础上扩展更多功能:接入真实传感器(如DHT22)、添加图表、通过开关控制设备等。Mongoose Wizard还支持OTA更新、用户认证等高级特性,值得深入探索。

提示:Wizard的项目数据存储在浏览器缓存中,如果需要永久保存设计,可以导出为JSON文件或定期备份屏幕截图和Key配置。

Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐