我用 3 个月,把 20 年的工业调试经验做成了微信小程序
从 Modbus 调试到 PID 整定,从串口通信到传感器标定,这款工具集成了工程师最常用的 20+ 专业计算器
前言:一个工程师的”执念”
我是一名工业自动化工程师,从业 20 年,待过设备厂商、集成商,也做过甲方。
这些年,我见过太多工程师在现场的”狼狈”:
- 背着十几斤重的电脑跑现场,就为了调试一个 Modbus 设备
- 忘带 USB 转串口线,整个项目停工半天
- 电脑上的软件要收费,破解版还怕有病毒
- PID 参数不会整,打电话问厂家,等半天回复
- 传感器标定靠手算,计算器按错一次,全部重来
最痛苦的一次,是某次深夜抢修。客户的 PLC 通信故障,我赶到时已经是晚上 10 点。结果发现忘带电脑,只能打电话让同事送,折腾到凌晨 3 点才搞定。
那一刻我就想:为什么不能只带手机就去现场?
于是,我花了整整 3 个月,利用业余时间开发了这款 Modbus 调试助手 微信小程序。
它不仅仅是一个调试工具,更是我 20 年经验的结晶。
一、核心功能:20+ 专业工具,装进手机
1.1 Modbus 调试全家桶
小程序最核心的功能,就是 完整的 Modbus 协议栈支持。
(1)Modbus Poll – 主站轮询工具
这是使用频率最高的功能,没有之一。
支持的功能码:
| 功能码 | 名称 | 用途 |
|---|---|---|
| FC01 | Read Coils | 读取线圈状态(开关量输出) |
| FC02 | Read Discrete Inputs | 读取离散输入(开关量输入) |
| FC03 | Read Holding Registers | 读取保持寄存器(最常用) |
| FC04 | Read Input Registers | 读取输入寄存器(只读) |
| FC05 | Write Single Coil | 写入单个线圈 |
| FC06 | Write Single Register | 写入单个寄存器 |
| FC15 | Write Multiple Coils | 写入多个线圈 |
| FC16 | Write Multiple Registers | 写入多个寄存器 |
| FC17 | Report Slave ID | 通报客户端 ID |
| FC22 | Mask Write Register | 掩码写寄存器(改单个 bit) |
| FC23 | Read/Write Multiple | 同时读/写多个寄存器 |
| FC43/14 | Read Device ID | 读取设备标识 |
连接方式:
- Modbus TCP:支持任意 IP 和端口,自动保存连接历史
- 蓝牙连接:支持普通蓝牙转 485 模块和 PACO 蓝牙适配器
- 端口转发:支持路由器端口映射(如外部 1502 → 内部 502)
数据显示格式:
同一个寄存器的原始数据,支持 7 种显示格式 一键切换:
Signed(有符号) → -32768 ~ 32767 Unsigned(无符号) → 0 ~ 65535 Hex(十六进制) → 0x0000 ~ 0xFFFF Long(长整型) → 32 位整数 Float(浮点型) → IEEE 754 单精度 Float Swapped → 字节反转浮点 Binary(二进制) → 0000 0000 0000 0001
💡 实际案例:某温度传感器返回 0x4248 0x0000,如果按 16 位整数看是 17480 和 0,完全不对。切换到 Float 格式,显示 50.0,这才是实际温度值。
高级工具:
- 通讯监视面板:实时记录所有 Tx/Rx 原始报文,支持暂停/继续,一键分享
- TC 测试中心:手动输入 Hex 字符串发送,查看原始响应,调试自定义协议
- 实时图表:输入要监控的寄存器地址,柱状图实时显示数值变化
- 请求报文预览:在设置界面实时显示即将发送的 RTU/ASCII 帧结构(含 CRC/LRC 校验)
(2)Modbus Slave – 从站模拟器
这个功能很多人忽略,但其实非常实用。
使用场景:
- 测试上位机软件(如组态王、WinCC)
- 验证 PLC 程序逻辑
- 培训新员工(无需真实设备)
- 开发阶段模拟从站响应
支持功能:
- 模拟线圈、离散输入、保持寄存器、输入寄存器
- 自定义初始值
- 支持批量设置地址范围
- 实时显示主站请求报文
(3)Modbus RTU/TCP/ASCII – 协议详解
小程序对三种传输模式都有详细说明和实战示例。
RTU vs ASCII 对比:
| 特性 | RTU | ASCII |
|---|---|---|
| 编码方式 | 二进制 | ASCII 文本 |
| 校验方式 | CRC16 | LRC |
| 帧长度 | 较短(高效) | 约为 RTU 2 倍 |
| 帧标识 | 3.5 字符静默间隔 | “:” 开头 + CR LF 结尾 |
| 适用场景 | 大多数工业设备 | 老旧设备/调制解调器 |
CRC16 算法实现(核心代码):
// MODBUS CRC-16 (低字节在前)
calcCRC16(bytes) {
let crc = 0xFFFF;
for (let i = 0; i < bytes.length; i++) {
crc ^= bytes[i];
for (let j = 0; j < 8; j++) {
if (crc & 0x0001) {
crc = (crc >> 1) ^ 0xA001;
} else {
crc >>= 1;
}
}
}
const lo = crc & 0xFF;
const hi = (crc >> 8) & 0xFF;
return lo.toString(16).toUpperCase().padStart(2, '0') + ' ' +
hi.toString(16).toUpperCase().padStart(2, '0');
}
LRC 算法实现:
// MODBUS ASCII LRC
calcLRC(bytes) {
let sum = 0;
for (let i = 0; i < bytes.length; i++) {
sum += bytes[i];
}
const lrc = ((~sum) + 1) & 0xFF;
return lrc.toString(16).toUpperCase().padStart(2, '0');
}
1.2 串口调试助手
这是第二个高频使用的功能。
核心特性:
- 三种连接方式:蓝牙 / TCP / UDP
- 全参数配置:波特率(9600/19200/38400/57600/115200)、数据位、停止位、校验位
- 收发区独立设置:
- 接收区:ASCII/HEX 切换、时间戳、自动换行、显示行号、自动滚动
- 发送区:ASCII/HEX 切换、自动解析转义符(\r\n \t)、循环发送
- 四种校验方式:CRC-16、累加和、LRC、异或校验
- 实时统计:RX/TX 字节数、一键复位
实战案例 1:蓝牙调试 PACO 设备
PACO 是一款常用的蓝牙 485 适配器,小程序对其做了深度优化。
// 构建 PACO 命令 (80 字节固定长度)
buildPacoCommand(cmdType, param = '') {
let cmd = '';
switch(cmdType) {
case 'read485':
cmd = 'PACO-Setting-Code-PACO-FXY-BT-485-R-485Setting.';
break;
case 'write485':
cmd = `PACO-Setting-Code-PACO-FXY-BT-485-W-485Setting:${param}.`;
break;
case 'readName':
cmd = 'PACO-Setting-Code- -R-PartNumber.';
break;
case 'writeName':
cmd = `PACO-Setting-Code-PACO-FXY-BT-485-W-DeviceName:${param}.`;
break;
}
// 补齐到 76 字符,末尾加 PACO
const paddedCmd = cmd.padEnd(76, ' ') + 'PACO';
return paddedCmd;
}
可以读写 PACO 设备的:
- 485 参数(波特率/数据位/停止位/校验位)
- 设备名称(最大 7 字符)
实战案例 2:TCP 端口限制问题
微信小程序对端口有严格限制,这是一个大坑。
// 微信小程序端口限制检查
const forbiddenPorts = [1099, 1433, 1521, 1719, 1720, 1723,
2049, 2375, 3128, 3306, 3389, 3659, 4045, 5060, 5061,
5432, 5984, 6379, 6000, 6566, 7001, 7002, 8443, 8888,
9200, 9300, 10051, 10080, 11211, 27017, 27018, 27019];
if (portNum < 1024) {
// 禁止连接 1024 以下端口(如 502)
uni.showModal({
title: '端口受限',
content: '微信小程序禁止连接 1024 以下端口,请使用 APP 版本或更换端口',
showCancel: false
});
return;
}
if (portNum >= 8000 && portNum <= 8100) {
// 禁止连接 8000-8100 端口
uni.showModal({
title: '端口受限',
content: '微信小程序禁止连接 8000-8100 端口,请更换端口',
showCancel: false
});
return;
}
解决方案:
在路由器做端口转发,比如外部 1502 → 内部 502。
1.3 专业计算器系列
这部分是我花心思最多的,也是最能体现”经验价值”的地方。
(1)PID 自整定计算器
PID 参数整定是自动控制系统的核心,也是很多工程师的痛点。
支持的整定方法:
| 方法 | 适用场景 | 特点 |
|---|---|---|
| 齐格勒 – 尼科尔斯第一法 | 阶跃响应实验 | 经典方法,适用面广 |
| 齐格勒 – 尼科尔斯第二法 | 临界振荡法 | 需要找到临界增益 |
| Cohen-Coon | 大滞后系统 | 对滞后系统效果好 |
| IMC(内模控制) | 高性能要求 | 参数可调,灵活性高 |
| 极点配置 | 特定动态响应 | 需要系统模型 |
输入参数:
- 延迟时间 L(秒)
- 时间常数 T(秒)
- 过程增益 K
- λ 参数(IMC 专用)
输出结果:
- 比例增益 Kp
- 积分时间 Ti
- 微分时间 Td
- 推荐配置(如控制器类型、控制变量选择)
核心算法(齐格勒 – 尼科尔斯第一法):
// Ziegler-Nichols 第一法(阶跃响应法)
zieglerNichols1st(L, T, K) {
// Kp = 1.2 * T / (K * L)
// Ti = 2 * L
// Td = 0.5 * L
const kp = 1.2 * T / (K * L);
const ti = 2 * L;
const td = 0.5 * L;
return { kp, ti, td };
}
实战案例:
某温度控制系统,通过阶跃响应实验得到:
- 延迟时间 L = 2.5s
- 时间常数 T = 8.0s
- 过程增益 K = 1.0
代入公式计算:
- Kp = 1.2 × 8.0 / (1.0 × 2.5) = 3.84
- Ti = 2 × 2.5 = 5.0s
- Td = 0.5 × 2.5 = 1.25s
将这三个参数输入 PID 控制器,系统响应快速且超调小。
(2)传感器标定计算器
传感器标定是现场调试的常规工作,但手算容易出错。
支持四种模式:
① 线性标定(最常用)
适用于 4-20mA、0-10V 等线性传感器。
标定公式:Y = kX + b 其中: k = (Y2 - Y1) / (X2 - X1) // 斜率 b = Y1 - k * X1 // 截距
快速换算表:
| 百分比 | 信号值 (mA) | 工程值 (℃) |
|---|---|---|
| 0% | 4.00 | 0.00 |
| 25% | 8.00 | 25.00 |
| 50% | 12.00 | 50.00 |
| 75% | 16.00 | 75.00 |
| 100% | 20.00 | 100.00 |
② 多点拟合
适用于非线性传感器(如热电偶、热电阻)。
支持:
- 二次曲线拟合
- 三次曲线拟合
- 最小二乘法
③ 温度专用模式
内置常用温度传感器分度表:
- PT100 热电阻
- K 型热电偶
- J 型热电偶
- E 型热电偶
- T 型热电偶
④ 误差分析
计算:
- 绝对误差
- 相对误差
- 满量程误差
- 线性度
实战案例:
某压力变送器,量程 0-10bar,输出 4-20mA。
标定点设置:
- 低点:4mA → 0bar
- 高点:20mA → 10bar
计算结果:
- k = (10 – 0) / (20 – 4) = 0.625
- b = 0 – 0.625 × 4 = -2.5
标定公式:Y = 0.625X – 2.5
验证:
- 输入 12mA → Y = 0.625 × 12 – 2.5 = 5.0bar ✓
- 输入 20mA → Y = 0.625 × 20 – 2.5 = 10.0bar ✓
(3)校验计算工具
这个工具集成了 10+ 种工业通信协议常用的校验算法。
支持功能:
| 校验类型 | 说明 | 适用场景 |
|---|---|---|
| MODBUS RTU CRC-16 | 16 位循环冗余校验 | Modbus RTU 协议 |
| MODBUS ASCII LRC | 纵向冗余校验 | Modbus ASCII 协议 |
| 校验和(16 位) | 累加和取低 16 位 | 简单协议 |
| 异或校验(8 位) | 所有字节异或 | 自定义协议 |
| 西门子 S7 校验和 | S7 通信协议专用 | 西门子 PLC |
| 三菱 FX 求和校验 | 三菱通信协议 | 三菱 PLC |
| BCC 校验 | 块校验字符 | 串口通信 |
| IP/TCP 校验和 | 网络协议校验 | TCP/IP 栈 |
| 欧姆龙 FINS FCS | FINS 协议校验 | 欧姆龙 PLC |
| CAN CRC | CAN 总线校验 | 汽车电子 |
使用方法:
- 选择校验类型
- 输入原始 HEX 数据
- 自动计算校验码
- (可选)附加校验码后发送
实战案例:Modbus RTU 命令
原始数据:01 03 00 00 00 01
计算 CRC-16:
- 输入 6 字节
- 计算得 CRC = 0x840A
- 低字节在前:
84 0A
完整报文:01 03 00 00 00 01 84 0A
1.4 其他专业工具
小程序还有 15+ 专业工具,这里简单列举:
(1)PLC 调试工具
- Q06 开关调试助手:专门针对 Q06 系列开关的调试工具
- X160 调试工具:X160 设备专用调试
- ZLAN 设备管理器:有人物联网 ZLAN 系列设备管理
(2)执行器调试
- 调光调试助手:0-10V/PWM 调光器调试
- 8 路继电器控制:多路继电器批量控制
- 伺服脉冲计算:伺服电机脉冲当量计算
(3)变频器调试
- 变频器调试工具:支持主流变频器参数设置
(4)其他计算器
- 压力变送器调试:差压/压力变送器计算
- 远程协助工具:实时共享调试画面
二、技术架构:小程序也能做专业工具
2.1 技术选型
前端框架: uni-app
选择理由:
- 一套代码编译到微信小程序、H5、APP
- 丰富的组件库
- 良好的蓝牙/TCP/UDP API 支持
UI 框架: colorUI + 自定义组件
数据存储:
- 本地存储:uni.setStorageSync
- 连接历史记录
- 项目配置保存
2.2 核心技术难点
(1)蓝牙 BLE 连接
微信小程序的蓝牙 API 有一些限制,需要特殊处理。
难点 1:服务特征值查找
不同蓝牙模块的 Service UUID 和 Characteristic UUID 不同,需要智能查找。
// 遍历所有服务查找可写特征
findWritableCharacteristic() {
if (this.currentServiceIndex >= this.allServices.length) {
// 所有服务都遍历完了
if (this.foundWriteChar) {
this.finishBluetoothConnection();
} else {
uni.showToast({ title: '未找到可写特征', icon: 'none' });
}
return;
}
const service = this.allServices[this.currentServiceIndex];
uni.getBLEDeviceCharacteristics({
deviceId: this.connectedDeviceId,
serviceId: service.uuid,
success: (res) => {
const characteristics = res.characteristics;
// 查找策略:
// 1. 优先找同时支持 write 和 notify 的特征(双向通信)
// 2. 其次找只支持 write 的特征
// 3. 最后找支持 writeNoResponse 的特征
let writeChar = characteristics.find(c =>
c.properties.write === true &&
(c.properties.notify === true || c.properties.indicate === true)
);
if (!writeChar) {
writeChar = characteristics.find(c => c.properties.write === true);
}
if (!writeChar) {
writeChar = characteristics.find(c => c.properties.writeNoResponse === true);
}
if (writeChar) {
this.writeCharacteristicId = writeChar.uuid;
this.foundWriteChar = true;
this.finishBluetoothConnection();
return;
}
// 当前服务未找到,继续下一个
this.currentServiceIndex++;
this.findWritableCharacteristic();
}
});
}
难点 2:PACO 设备 80 字节单包发送
PACO 设备需要一次发送 80 字节,但 BLE 默认 MTU 只有 20 字节。
解决方案:
// 设置 BLE MTU(最大传输单元)
setBLEMTU(deviceId, callback) {
if (wx.setBLEMTU) {
wx.setBLEMTU({
deviceId: deviceId,
mtu: 512, // 设置为 512 字节
success: (res) => {
console.log('MTU 设置成功');
callback && callback();
},
fail: (err) => {
console.error('MTU 设置失败', err);
callback && callback();
}
});
} else {
callback && callback();
}
}
(2)TCP Socket 通信
微信小程序的 TCP Socket API 是异步的,需要处理连接超时、数据分包、粘包等问题。
连接超时处理:
const connTimeout = setTimeout(() => {
if (!self.isConnected) {
uni.hideLoading();
uni.showToast({ title: '连接超时', icon: 'none' });
try { tcp.close(); } catch(e) {}
self.tcpSocket = null;
}
}, 8000); // 8 秒超时
tcp.onConnect(function(res) {
clearTimeout(connTimeout);
self.isConnected = true;
// ...
});
数据分包处理:
handleTcpResponse(hexData) {
const hex = hexData.replace(/\s+/g, '');
// 将接收到的数据添加到缓冲区
for (let i = 0; i < hex.length; i += 2) {
this.receiveBuffer.push(parseInt(hex.substr(i, 2), 16));
}
// 使用 MBAP 头的 Length 字段判断帧完整性
while (this.receiveBuffer.length >= 7) {
const mbapLength = (this.receiveBuffer[4] << 8) | this.receiveBuffer[5];
const totalFrameLength = 6 + mbapLength;
if (this.receiveBuffer.length >= totalFrameLength) {
// 提取完整的一帧
const frame = this.receiveBuffer.splice(0, totalFrameLength);
this.parseModbusTcpResponse(frame);
} else {
// 数据不完整,等待更多数据
break;
}
}
}
(3)大数据处理
串口调试时,如果长时间运行,会产生大量数据。
优化策略:
// 消息缓冲区管理
maxMessageCount: 800, // 最多保存 800 条
maxVisibleMessageChars: 240, // 每条最多显示 240 字符
trimMessageBuffer() {
const maxTotalChars = this.maxMessageCount * this.maxVisibleMessageChars * 2;
while (this.messages.length > this.maxMessageCount ||
this.totalMessageChars > maxTotalChars) {
const removed = this.messages.shift();
if (removed && removed.data) {
this.totalMessageChars -= removed.data.length;
}
}
}
// 超长消息自动截断,支持展开/收起
isMessageTruncated(msg) {
return !!(msg && msg.data &&
msg.data.length > this.maxVisibleMessageChars);
}
getDisplayMessage(msg) {
if (!msg || !msg.data) return '';
if (msg.expanded || !this.isMessageTruncated(msg)) {
return msg.data;
}
return msg.data.slice(0, this.maxVisibleMessageChars) + '…';
}
三、设计理念:工程师懂工程师
3.1 Win7 风格界面
很多人问为什么用 Win7 风格?
因为 熟悉。
大多数工业工程师天天对着电脑,Win7 的界面是最熟悉的。看到这种风格,就有”专业工具”的感觉。
设计细节:
- 渐变蓝色标题栏
- 立体边框(外浅内深)
- 灰色背景 + 白色内容区
- 等宽字体显示数据(Courier New)
3.2 远程协助功能
这个功能是我在现场调试时想到的。
场景:
现场设备故障,我搞不定,需要同事远程协助。但传统方式只能电话描述,效率极低。
解决方案:
// 生成协助会话码
startRemoteAssist() {
const sessionId = generateRandomSessionId();
this.remoteAssistSessionId = sessionId;
this.remoteAssistShowPanel = true;
// 实时转发通信数据
this.remoteAssistForward('tx', 'Tx', data);
this.remoteAssistForward('rx', 'Rx', data);
// 接收远程命令
this._executeRemoteCommand(cmd);
}
使用流程:
- 点击”远程协助”
- 生成 6 位会话码
- 分享给微信好友
- 对方打开后,实时查看通信数据
- 对方可以远程发送命令
价值:
- 无需截图/录屏
- 实时双向通信
- 支持多人协作
3.3 数据导出分享
现场调试完,经常需要把数据发给同事或存档。
导出格式:
【串口调试 - 通信记录】 导出时间:2026-04-05 11:00:00 共 50 条记录 发送:1200 字节,接收:800 字节 ======================================== [11:00:00.123] 发送:01 03 00 00 00 01 84 0A [11:00:00.456] 接收:01 03 02 00 0A B9 C8 [11:00:01.123] 发送:01 03 00 00 00 0A C5 CD ... ======================================== 来自:Modbus 调试助手 微信小程序
实现方式:
buildExportLogContent(options = {}) {
let content = `${options.title || '【串口调试 - 通信记录】'}\n`;
content += `导出时间:${new Date().toLocaleString()}\n`;
content += `共 ${this.messages.length} 条记录\n`;
content += `发送:${this.sentCount} 字节,接收:${this.receivedCount} 字节\n`;
content += `${'='.repeat(40)}\n\n`;
this.messages.forEach((msg) => {
const direction = msg.type === 'sent' ? '发送' : '接收';
content += `[${msg.time}] ${direction}: ${msg.data}\n`;
});
content += `\n${'='.repeat(40)}\n`;
content += `来自:Modbus 调试助手 微信小程序`;
return content;
}
四、用户反馈:真实的声音
上线 2 个月,已经有 5000+ 工程师在使用。
反馈 1:
“太方便了!以后出差只带手机就够了。昨天去现场,客户都惊讶我怎么只带个手机就搞定了。”
—— 江苏,自动化工程师,王工
反馈 2:
“PID 整定计算器帮了大忙。以前整定参数要试半天,现在输入 L/T/K,直接出结果。”
—— 广东,控制工程师,李工
反馈 3:
“远程协助功能太强了。现场遇到问题,直接分享给同事,5 分钟搞定,以前至少要半小时电话沟通。”
—— 浙江,技术支持,张工
反馈 4:
“传感器标定计算器很实用。我们厂有几百个传感器,以前标定要手算,现在输入两个点,自动出公式。”
—— 山东,仪表工程师,刘工
五、未来规划
5.1 短期计划(1-3 个月)
- 增加 OPC UA 客户端
- 支持 MQTT 协议调试
- 增加 BACnet 协议支持
- 云端项目同步(VIP 功能)
5.2 中期计划(3-6 个月)
- APP 版本(突破微信小程序端口限制)
- 支持脚本功能(Lua/JavaScript)
- 增加图表分析功能(趋势图、频谱分析)
- 设备数据库(常见设备参数模板)
5.3 长期愿景
做一个工业工程师的”百宝箱”。
只要是现场调试能用到的工具,都集成到这个小程序里。
让工程师:
- 少背点东西,轻装上阵
- 少加点班,早点回家
- 少一些烦恼,多一些效率
六、写在最后
做这个小程序的初衷,不是为了赚钱。
只是想解决自己的痛点,顺便帮到更多同行。
20 年的经验告诉我:工具的价值,不在于功能多花哨,而在于真正解决问题。
每一个功能,都是我现场调试时真实遇到过的痛点。
每一行代码,都凝聚着我对这个行业的热爱。
如果你也是工业工程师,希望这个小程序能帮到你。
如果你有任何建议,欢迎反馈。
让我们一起,让工业调试变得更简单。
附录:使用方式
方式 1:微信扫码

方式 2:微信搜索
搜索”Modbus 调试助手”
方式 3:朋友分享
点击朋友分享的卡片直接进入
关于作者
20 年工业自动化经验,待过设备厂商、集成商、甲方。
现专注于工业物联网、边缘计算、智能控制。
欢迎交流:
- 📧 邮箱:support@modbus.cn
- 💬 微信群:扫码添加助手入群
参考资料
[1] Modbus Application Protocol Specification V1.1b3
[2] 齐格勒 – 尼科尔斯 PID 整定方法
[3] 微信小程序蓝牙开发文档
[4] IEEE 754 浮点数标准
[5] CRC16 算法原理与实现
