1. 引言
在工业自动化与仪器仪表领域,上位机软件通常采用 C#、C++ 或 Python 等传统桌面技术开发。随着 Web 技术的成熟,越来越多的开发者开始考虑使用 HTML + JavaScript 构建上位机界面。本文围绕「使用 HTML 制作设备仪器上位机软件,基于 Modbus TCP 通信」这一主题,分析其可行性,并给出清晰的代码文件结构设计方案。
2. 可行性分析
使用 HTML 制作基于 Modbus TCP 通信的上位机软件,在技术上是完全可行的,但需要区分两种运行形态:
- 浏览器运行形态:通过浏览器直接访问页面,受浏览器安全策略(CORS、混合内容限制)影响,需要配合本地代理服务转发 Modbus TCP 请求。
- 桌面封装形态:使用 Electron、Tauri 等框架将 HTML 页面封装为桌面应用,Node.js 侧可直接建立 Modbus TCP 连接,不受浏览器跨域限制,体验最接近传统上位机。
无论采用哪种形态,核心通信逻辑都依赖 JavaScript 生态中的 Modbus 库(如 modbus-serial、jsmodbus),通过 TCP 协议与设备进行读写寄存器、线圈等操作。
3. 技术选型建议
| 层次 | 推荐方案 | 说明 |
|---|---|---|
| 界面框架 | Vue 3 / React | 组件化开发,适合仪表盘、实时数据刷新场景 |
| 通信库 | modbus-serial | Node.js 环境下的成熟 Modbus TCP 客户端库 |
| 桌面封装 | Electron / Tauri | 提供 Node.js 运行环境,可直接建立 TCP 连接 |
| 图表展示 | ECharts | 用于实时曲线、趋势图等可视化需求 |
4. 代码文件结构设计
针对「传统上位机依赖 Windows 小主机、成本较高」的痛点,Electron 方案确实可以运行在 ARM Linux 主机(如 RK3588、树莓派等)上,从而用更便宜的嵌入式硬件替代传统 Windows 工控机,显著降低单台设备成本。但落地前需要从硬件适配、系统环境、性能开销三个层面做评估。
- 硬件架构适配 :Electron 官方提供
linux-arm64安装包,可直接运行在 RK3588 等 ARM64 平台;若设备是 ARM32(如部分老款树莓派),则需要自行编译或寻找社区构建版本,适配成本会上升。 - 系统环境要求 :ARM Linux 主机需要安装带图形界面的桌面环境(如 X11 或 Wayland),并满足 Chromium 运行所需的依赖库(如
libgtk、libnss3等);无桌面环境的精简系统需额外安装 X 服务。 - 性能开销评估:Electron 内存占用通常高于原生应用,RK3588 这类 8 核高性能 ARM 芯片可流畅运行中等复杂度的上位机界面;但若设备内存只有 2GB 或更低,建议精简界面、减少动画,或改用 Tauri 等更轻量的方案。
- Modbus 通信不受影响 :
modbus-serial等库基于 Node.js 的 TCP 能力,与 CPU 架构无关,在 ARM Linux 上同样可稳定读写寄存器、线圈,通信逻辑无需改动。 - 成本对比:一块 RK3588 核心板加触摸屏的成本通常远低于一台 Windows 工控机,且体积更小、功耗更低,适合嵌入到设备本体或机柜中,实现「一机一屏」的紧凑部署。
- 部署与维护:ARM Linux 主机可预装精简系统镜像,配合 Electron 的自动更新机制远程推送新版本,现场维护成本进一步降低。
总体来看,Electron 运行在 ARM Linux 主机上是完全可行的,尤其适合 RK3588 这类性能足够的嵌入式平台。若追求更低的内存占用和更小的安装包,也可评估 Tauri 方案;但若团队已熟悉 Electron 技术栈,直接迁移到 ARM Linux 是降低设备成本的有效路径。
在深入代码结构之前,先对比 Electron 与传统工控软件(如基于 C# WinForms/WPF、C++ Qt 或 Delphi 开发的上位机)的差异,以便理解为何越来越多的工控项目选择 Electron 方案。
- 界面开发效率:传统工控软件多采用原生控件,界面样式偏朴素,定制仪表盘、实时曲线、动画效果需要大量底层绘图代码;Electron 直接使用 HTML + CSS + JavaScript,借助 Vue、React 和 ECharts 等成熟生态,可快速构建出高颜值、可交互的工业界面。
- 跨平台部署:传统方案通常绑定单一操作系统,C# 主要面向 Windows,Qt 虽跨平台但需针对各平台分别编译打包;Electron 基于 Chromium 和 Node.js,一套代码即可打包为 Windows、Linux、macOS 三个平台的安装包,显著降低多平台维护成本。
- 前后端分离与团队协作:传统工控软件往往界面与业务逻辑耦合紧密,改动界面容易影响通信代码;Electron 天然采用主进程与渲染进程分离架构,通信逻辑与界面展示解耦,前端工程师与后端工程师可并行开发,代码可维护性更高。
- 生态与组件复用:传统工控软件的可视化组件库相对封闭,图表、报表、拖拽布局等能力需要购买或自研;Electron 可直接复用 Web 生态中海量的开源组件,从数据可视化到 UI 框架一应俱全,功能扩展成本更低。
- 热更新与远程维护:传统桌面软件升级通常需要现场重新安装或覆盖文件;Electron 应用可结合自动更新机制,在联网条件下远程推送新版本,减少现场维护的人力与时间成本。
- 学习曲线与人才储备:传统工控技术栈(如 C++/Qt、C#/WPF)学习周期较长,相关人才相对稀缺;Web 前端技术普及度高,招聘和上手都更容易,团队扩充与交接也更顺畅。
当然,Electron 并非没有代价:其内存占用和安装包体积通常大于原生应用,对实时性要求极高的硬实时控制场景仍需谨慎评估。但对于以数据采集、状态监控、参数配置为主的仪器仪表上位机,Electron 的优势非常明显。
一个清晰的分层结构是上位机软件可维护性的关键。推荐采用「主进程 / 渲染进程」分离的 Electron 架构,将 Modbus 通信逻辑放在主进程,界面渲染放在渲染进程,通过 IPC 进行数据交互。
text
device-hmi/
├── package.json
├── main.js // Electron 主进程入口
├── preload.js // 预加载脚本,暴露安全的 IPC 接口
├── src/
│ ├── modbus/
│ │ ├── client.js // Modbus TCP 客户端封装
│ │ ├── config.js // 设备地址、寄存器映射配置
│ │ └── poller.js // 定时轮询与数据缓存
│ ├── ipc/
│ │ └── handlers.js // IPC 消息处理(读写请求分发)
│ ├── renderer/
│ │ ├── index.html // 主界面
│ │ ├── assets/
│ │ │ ├── css/
│ │ │ └── js/
│ │ └── views/
│ │ ├── dashboard.js // 仪表盘视图
│ │ ├── monitor.js // 实时监控视图
│ │ └── settings.js // 参数配置视图
│ └── utils/
│ └── formatter.js // 数据格式化与单位换算
└── config/
└── device-map.json // 设备寄存器地址映射表
5. 核心模块职责说明
各模块的职责划分如下:
- main.js:创建窗口、管理应用生命周期、初始化 Modbus 客户端。
- src/modbus/client.js:封装连接建立、断开、读写保持寄存器、读写线圈等基础操作。
- src/modbus/poller.js:按设定周期轮询设备数据,缓存最新值并推送给渲染进程。
- src/ipc/handlers.js:接收渲染进程的读写请求,调用 Modbus 客户端执行并返回结果。
- src/renderer/:纯界面层,只负责展示数据和发送用户指令,不直接接触 TCP 通信。
- config/device-map.json:集中管理寄存器地址与物理量的映射关系,便于现场调试时调整。
6. 通信流程设计
一次典型的「读取设备温度」流程如下:
- 渲染进程通过 preload 暴露的 API 发起读取请求。
- IPC 处理器接收请求,转发给 Modbus 客户端。
- 客户端向设备发送 Modbus TCP 请求帧,等待响应。
- 响应数据经格式化后,通过 IPC 回传渲染进程。
- 界面更新显示,并可选地写入图表或日志。
对于需要实时刷新的场景,建议采用轮询或订阅模式,由主进程统一调度,避免渲染进程频繁发起请求造成拥堵。
7. 注意事项与建议
- 数据缓存:主进程维护一份最新数据快照,渲染进程直接读取快照,减少 IPC 通信频率。
- 断线重连:Modbus TCP 连接可能因设备重启或网络波动中断,需实现自动重连与状态提示。
- 寄存器映射:将设备手册中的寄存器地址统一维护在配置文件中,避免硬编码散落各处。
- 安全边界:若采用浏览器形态,务必通过本地代理转发请求,不要在前端直接暴露设备 IP 和端口。
- 性能考量:高频轮询时注意控制请求频率,避免对设备造成额外负担。
8. 总结
使用 HTML 制作基于 Modbus TCP 通信的设备仪器上位机软件完全可行,尤其适合对界面美观度、跨平台部署有较高要求的场景。推荐采用 Electron 封装 + 主进程通信 + 渲染进程展示的分层架构,将 Modbus 通信逻辑与界面逻辑解耦,既保证了通信的稳定性,又提升了开发效率与可维护性。