在浏览器里直接调设备。
Talk to industrial devices from a browser tab.
串口 · WebUSB · WebSocket · MQTT · Modbus RTU · HART · 自定义协议
![]() AOMaster 4-20 mA / 0-10 V 6 种波形 |
![]() HART 通用仪表调试 PV / SV / TV / QV |
![]() WebSocket JSON / HEX / Modbus 实时曲线 |
![]() MQTT 发布 / 订阅 · QoS 保留消息 · 统计 |
浏览器里的设备调试台,纯静态前端,没有上位机要装、没有后端要起。打开网页、选设备、连上、看原始报文、手动发命令、看实时曲线,就这样。
一个标签页,一根线,跟设备直接对话。
- 临时调一块 Modbus RTU 板子,不想装某厂家 200MB 的上位机
- 进车间带个 USB 转 485,笔记本插上就是 HART 调试工具
- 新设备走 WebSocket 或 MQTT,想边看流量边看曲线
- 调 RP2040 WebUSB 小电流采集,不想单独装桌面上位机
- 把链接发给同事,比发
setup.exe省事 - 内部协议没有现成工具,用 自定义设备 页面拼一个,不用写 JS
不适合:长时间数据采集、生产监控、SCADA。这是个调试工具。
| 设备 | 传输 | 默认参数 | 说明 |
|---|---|---|---|
| AOMaster | 串口 | 115200 8N1 | 4-20mA / 0-10V 信号源,6 种波形 |
| Modbus RTU | 串口 | 9600 8N1 | 读写保持 / 输入寄存器 |
| HART | 串口 | 1200 8O1 | 设备搜索、通用命令、PV/SV/TV/QV |
| WebSocket | WebSocket | — | JSON / HEX / Modbus 报文调试 |
| MQTT | MQTT over WS | — | 发布订阅、QoS、保留消息、统计 |
| MicroScope Power | WebUSB | VID 0xCAFE, PID 0x4011 |
RP2040 小电流波形采集、游标、校准、CSV/PNG 导出 |
| 自定义设备 | 任意 | — | 模板 + 解析规则,无需写代码 |
普通设备切换时通讯方式和参数会跟着自动切换。MicroScope Power 这类独立 WebUSB 工具会在设备页内部保留自己的连接和采集控制。
开发模式不用构建,起一个静态服务即可:
python -m http.server 4173用 Chrome / Edge 打开 http://localhost:4173。
要发布的话:
npm install
npm run build
npm run preview构建脚本是 scripts/build.mjs(基于 esbuild),产物在 _site/。
适合在笔记本、工控机或现场环境拷贝一份,无需联网拉代码。
获取离线包
- 每次推送到
main:打开 Actions → Offline package,在最新一次运行里下载 Artifactmodusignal-offline-<版本>.zip。 - 打
v*标签发布:在 Releases 下载modusignal-offline-<标签>.zip。
本地运行
解压后双击 start-modusignal.bat(Windows)或运行 start-modusignal.sh(macOS/Linux),会自动起服务并打开浏览器。
也可手动执行:
python -m http.server 4173用 Chrome / Edge 打开 http://localhost:4173。串口和 WebUSB 功能需在 localhost 或 HTTPS 下使用。
自己打包
npm install
npm run build:offline产物在 _release/modusignal-offline-<版本>.zip(系统无 zip 命令时为 .tar.gz)。解压目录内的 OFFLINE.txt 有简要说明。
| 功能 | 浏览器 |
|---|---|
| 串口(Web Serial) | Chrome / Edge 89+,需要 HTTPS 或 localhost |
| WebUSB | Chrome / Edge,需要 HTTPS 或 localhost |
| WebSocket | 现代浏览器都行 |
| MQTT over WebSocket | 现代浏览器都行 |
Firefox 和 Safari 没有 Web Serial / WebUSB,串口和 WebUSB 设备用不了,其它功能正常。
英文版的 Architecture 表已经列得很清楚了,这里不重复。简单说就是:设备层和传输层分开,加新设备 = 写一个驱动 + 注册 + 加一个页面。像 MicroScope Power 这种自己管理 WebUSB 和曲线的专用上位机,可以在注册表里标记为 standalone,详见 CONTRIBUTING.md。
MicroScope Power 页面嵌入了 pages/devices/microscope-power/ 下的浏览器上位机。它直接通过 WebUSB 连接 RP2040 固件(VID 0xCAFE、PID 0x4011),页面内自带采样率、假信号/ADC 模式、曲线缩放平移、游标、校准、CSV/PNG 导出。
使用时通过 localhost 或 HTTPS 用 Chrome / Edge 打开站点,在设备库选择 MicroScope Power,再在内嵌上位机里点击 连接设备。这里没有打包原项目的 Pico 固件、SDK 和构建产物,只集成浏览器上位机源码。
| 地址 | 读写 | 含义 |
|---|---|---|
| 0x0000 | R/W | 信号类型(电流 / 电压) |
| 0x0001 | R/W | 波形:0=恒定 1=阶跃 2=斜坡 3=方波 4=三角 5=正弦 |
| 0x0002 | R/W | 设定值 / 低值 |
| 0x0003 | R/W | 高值 / 阶跃保持时间 |
| 0x0004 | R/W | 周期(ms)/ 循环次数 |
| 0x0005 | R/W | 占空比 × 10 |
| 0x0006 | R | 实际输出(回读) |
| 0x0007+ | R/W | 步进序列值 |
上位机用 01 03 00 00 00 07 04 08 读取 0x0000..0x0006。回包必须包含全部 7 个寄存器;0x0000 选择电流/电压单位,0x0006 是实际输出回读值。模拟量原始值按 1000 缩放:原始值 10600 在电压模式表示 10.600 V,在电流模式表示 10.600 mA。实际输出曲线的 Y 轴会随回包类型切换为 0..10 V 或 4..20 mA。
默认轮询周期 50ms,阶跃模式先写 0x0007+ 序列值,再写头部寄存器。
不想写 JS 也能配一个驱动出来:
- 输出范围、单位、步长
- 发送模板,支持
{value}、{value:2}、{unit}占位符 - 解析规则:正则、JSON 路径、HEX 偏移、Modbus 载荷
- 数值换算:
解析值 × 比例 + 偏移
仍在持续迭代。新设备和解析能力会陆续加进来,欢迎在 issues 里讨论你想要的功能。需要新设备但不方便自己写驱动的,提一个 issue 附上协议文档、报文样例和默认连接参数即可。
欢迎 PR 增加设备或修复驱动,提交前请看 CONTRIBUTING.md。
如果 modusignal 帮你省下了一个下午跟厂家上位机较劲的时间,点个 star 能让更多人看到它。
A static web app for debugging serial / WebUSB / WebSocket / MQTT devices from a browser. No installer, no backend, no database. Open the page, pick a device, connect, and you get raw frames, manual send, parsed values, and a real-time chart.
Open a tab. Plug in a device. Talk to it.
- Bench-test a Modbus RTU board without firing up a 200 MB vendor tool
- Walk into a plant with a USB-to-485 dongle and a laptop, and you have a HART debugger
- Bring up a new MQTT/WebSocket-speaking device and watch traffic on a live curve
- Capture RP2040 WebUSB current waveforms without installing a desktop host
- Hand a colleague a URL instead of a
setup.exe - Build a quick UI for an in-house protocol with the Custom device page (no JS required)
Not what it's for: long-running data acquisition, plant monitoring, anything you'd actually call SCADA.
| Device | Transport | Default | Notes |
|---|---|---|---|
| AOMaster | Serial | 115200 8N1 | 4-20 mA / 0-10 V signal source, 6 waveforms |
| Modbus RTU | Serial | 9600 8N1 | Read / write holding & input registers |
| HART | Serial | 1200 8O1 | Device search, universal commands, PV/SV/TV/QV |
| WebSocket | WebSocket | — | JSON / HEX / Modbus message debug |
| MQTT | MQTT over WS | — | Pub / sub, QoS, retain, message stats |
| MicroScope Power | WebUSB | VID 0xCAFE, PID 0x4011 |
RP2040 current waveform capture, cursors, calibration, CSV/PNG export |
| Custom | any | — | Template + parser, no code |
Switching regular devices also switches the transport and its defaults. Standalone WebUSB tools, such as MicroScope Power, keep their own connection and capture controls inside the device page.
Serve the repo as static files:
python -m http.server 4173Open http://localhost:4173 in Chrome or Edge. That's it — no install, no build.
To produce a deployable build:
npm install
npm run build
npm run previewThe build script is scripts/build.mjs (esbuild). Output goes to _site/.
Use this when you want a self-contained copy on a laptop or a plant PC without cloning the repo.
Download
- Push to
main: open Actions → Offline package, pick the latest run, download the artifactmodusignal-offline-<version>.zip. - Tagged release (
v*): downloadmodusignal-offline-<tag>.zipfrom Releases.
Run locally
Double-click start-modusignal.bat (Windows) or run start-modusignal.sh (macOS/Linux). It starts a local server and opens the browser.
Or manually:
python -m http.server 4173Open http://localhost:4173 in Chrome or Edge. Web Serial and WebUSB need localhost or HTTPS.
Build the zip yourself
npm install
npm run build:offlineOutput: _release/modusignal-offline-<version>.zip (or .tar.gz if zip is not installed).
| Feature | Browsers |
|---|---|
| Serial (Web Serial API) | Chrome / Edge 89+, HTTPS or localhost |
| WebUSB | Chrome / Edge, HTTPS or localhost |
| WebSocket | any modern browser |
| MQTT over WebSocket | any modern browser |
Firefox and Safari don't ship Web Serial or WebUSB, so serial and WebUSB devices won't work there. Everything else works.
index.html app shell (topbar, sidebar, mount points)
pages/
home.html home and device grid
request.html new-device request form
devices/ one HTML page per device
devices/microscope-power/
standalone MicroScope Power WebUSB host assets
shared/workbench.html shared log + chart panel
src/
app.js state, routing, events, device orchestration
protocols.js command / telemetry dispatch
device-registry.js device registry
page-loader.js async HTML fragment loader
chart.js Canvas 2D real-time chart
echarts-charts.js ECharts waveform preview
config.js app metadata
transports/ serial / websocket / mqtt sessions
devices/ per-device drivers
modbus/modbus.js Modbus RTU framing
hart/hart.js HART framing
framing/ generic frame parsing (lines, header/tail, CRC16)
Devices and transports are kept separate. Adding a new device is usually: a driver file in src/devices/, an entry in device-registry.js, and a page in pages/devices/. Dedicated browser-tool pages can be registered as standalone when they own their transport and UI, as MicroScope Power does. See CONTRIBUTING.md for details (the contributing guide is in Chinese).
The MicroScope Power page embeds the browser host from pages/devices/microscope-power/. It talks directly to the RP2040 firmware over WebUSB (VID 0xCAFE, PID 0x4011) and keeps its own controls for sample rate, fake/ADC source mode, chart zoom/pan, cursors, calibration, and CSV/PNG export.
Use Chrome or Edge from localhost or HTTPS, then choose MicroScope Power in the device library and click Connect device inside the embedded host. The Pico firmware, SDK, and build outputs from the source project are not bundled here; only the browser host files are integrated.
| Addr | R/W | Meaning | Raw unit |
|---|---|---|---|
| 0x0000 | R/W | Signal type: 0=current, 1=voltage | enum |
| 0x0001 | R/W | Waveform: 0=const 1=step 2=ramp 3=square 4=triangle 5=sine | enum |
| 0x0002 | R/W | Setpoint / low value; step count in step mode | mV or uA |
| 0x0003 | R/W | High value; step dwell in step mode | mV/uA or ms |
| 0x0004 | R/W | Period (ms); loop count in step mode | ms / count |
| 0x0005 | R/W | Duty cycle | permille |
| 0x0006 | R | Actual output (readback) | mV or uA |
| 0x0007..0x0016 | R/W | Step sequence values, max 16 points | mV or uA |
Raw analog values are scaled by 1000: voltage uses mV (10600 = 10.600 V), current uses uA (10600 = 10.600 mA). The web UI polls registers 0x0000..0x0006 in one Modbus RTU read so the response contains both signal type and actual output:
01 03 00 00 00 07 04 08
The response must include all seven registers. Register 0x0000 selects the engineering unit (0=current, 1=voltage), and register 0x0006 is plotted as the actual output. The actual-output chart Y axis follows the response type: 4..20 mA for current and 0..10 V for voltage. Default poll interval is 50 ms. In step mode the step sequence is written first, then the header.
If your device isn't built in, the Custom page lets you describe it without writing JS:
- Output range, unit, step
- Send template with
{value},{value:2},{unit}placeholders - Parser: regex, JSON path, HEX offset, Modbus payload
- Scaling:
parsed × scale + offset
modusignal is actively maintained. New devices and parsers land regularly — see open issues for what's being discussed and feel free to chime in. If you'd like a device supported but don't want to write the driver yourself, open a request with the protocol doc, sample frames, and default connection parameters.
PRs that add devices or improve existing drivers are welcome. Please read CONTRIBUTING.md first (Chinese; English version coming).
Apache License 2.0. See LICENSE.txt.
If modusignal saved you an afternoon of fighting with a vendor installer, a star helps other people find it.
by 飞起小鹏 · modusignal.cn




