更新记录
1.3.13(2026-09-07)
- 修复 Android:init 等成功回调 ClassCast(InitOption 不可强转为 BaseOption;按具体 Option 取 success/fail)
- 须重打自定义基座并云端传统打包;.vue 直接传对象,.uvue 仍须 as XxxOption
1.3.12(2026-09-07)
- 修复 Android:
.vue调用带数字字段与 success/fail 时 ClassCast(对外形参改回 XxxOption,由 JS 桥接正确映射回调) - uni-app x 调用请对入参使用
as XxxOption;须重打自定义基座并云端传统打包 - 不传参行为与上一版兼容
1.3.11(2026-09-07)
- 修复 Android:带数字参数(如 port/unitId/maxQueue)与 success/fail 同时传入时 ClassCast 崩溃
- 入口透传对象字面量,按键名读取字段与回调;uni-app / uni-app x 均可直接传对象
- 使用须制作自定义基座,并走云端传统打包(不支持离线打包、安心打包)
平台兼容性
uni-app(4.11)
| Vue2 | Vue3 | Vue3插件版本 | Chrome | Safari | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| × | √ | 1.3.10 | × | × | √ | 1.3.10 | √ | 1.3.10 | 5.0 | 1.3.10 | 12 | 1.3.10 | 12 | 1.3.10 |
| 微信小程序 | 支付宝小程序 | 抖音小程序 | 百度小程序 | 快手小程序 | 京东小程序 | 鸿蒙元服务 | QQ小程序 | 飞书小程序 | 小红书小程序 | 快应用-华为 | 快应用-联盟 |
|---|---|---|---|---|---|---|---|---|---|---|---|
| × | × | × | × | × | × | × | × | × | - | × | × |
uni-app x(4.11)
| Chrome | Safari | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 | 微信小程序 |
|---|---|---|---|---|---|---|---|---|
| × | × | 5.0 | 1.3.10 | 12 | 1.3.10 | 12 | 1.3.10 | × |
breao-modbustcp 使用说明
轻量 Modbus TCP 客户端,适用于工控采集、网关读写下发、多从站巡检,以及经串口服务器的 RTU-over-TCP 场景。
当前版本:1.3.13
- Android / iOS / 鸿蒙:TCP 长连接;FC01~06、FC15、FC16;uni-app 与 uni-app x(含鸿蒙)
- 能力:标准 MBAP 与可选 RTU-over-TCP;忙碌时请求队列与
maxQueue;pollUnits支持多从站与同一从站多地址批量读写;clearQueue/cancelPending;ABCD/BADC/CDAB/DCBA 四字序数值辅助;异常码中文 errMsg - 不做微信小程序(无原始 TCP)、不做真串口 / USB-RS485、不做 MQTT 云平台
建议调用顺序:init → connect → 读/写 / pollUnits(可夹数值辅助)→ disconnect / destroy。各异步方法均支持 success / fail / complete;fail 含 errCode / errMsg。插件为单例连接语义:再次 init 会重置配置并断开旧连接。
调用入参:uni-app(.vue)直接传对象;uni-app x(.uvue)须 as XxxOption(见 §5.2、§8)。须 1.3.13+ 自定义基座。
1. 环境要求
- HBuilderX 4.11 及以上
- uni-app Vue3(App-vue / App-nvue)或 uni-app x(App-Android / App-iOS / App-鸿蒙)
- 支持:App-Android、App-iOS、App-鸿蒙(uni-app 与 uni-app x)
- 不支持:H5、微信及其它小程序
- Android 最低 API:21;iOS 最低 12;鸿蒙最低 API:12
- App 真机调试须制作自定义基座;正式发版须购买授权后走云端传统打包
- 授权绑定唯一 appid + 包名
2. 安装与引入
将插件目录放入工程的 uni_modules/breao-modbustcp,或从插件市场导入后同步。
import {
init,
connect,
disconnect,
destroy,
getConnectionState,
clearQueue,
cancelPending,
pollUnits,
readCoils,
readDiscreteInputs,
readHoldingRegisters,
readInputRegisters,
writeSingleCoil,
writeSingleRegister,
writeMultipleCoils,
writeMultipleRegisters,
registerToI16,
i16ToRegister,
registersToU32BE,
u32BEToRegisters,
registersToFloat32BE,
float32BEToRegisters,
registersToU32,
u32ToRegisters,
registersToFloat32,
float32ToRegisters,
setDefaultByteOrder,
getDefaultByteOrder,
// 可选:异常码中文与字序规范化
// exceptionCodeLabel,
// exceptionErrMsg,
// normalizeByteOrder,
} from '@/uni_modules/breao-modbustcp'
3. API
3.1 init / connect / destroy
init({
host: '192.168.1.10',
port: 502,
unitId: 1,
// transport: 'rtu-over-tcp', // 串口服务器时开启;默认 tcp
// maxQueue: 32, // 忙碌时排队上限;不传=不限制;满队 9050002
// defaultByteOrder: 'ABCD', // 或 BADC / CDAB / DCBA;BE/LE 为别名
onConnectionLost(res) { console.log('lost', res) },
success() {},
fail(err) { console.error(err.errCode, err.errMsg) },
})
connect({ timeout: 10000, success() {}, fail(err) { console.error(err.errCode, err.errMsg) } })
disconnect({ success() {} })
destroy({ success() {} })
全量 init 参数见 §4。destroy 会取消排队中的请求(fail:插件已销毁)、关闭连接并复位默认字序。
3.2 读(FC01~04)
readCoils({ address: 0, quantity: 8, success(res) { /* res.bits */ } })
readHoldingRegisters({ address: 0, quantity: 4, success(res) { /* res.registers */ } })
| 方法 | 功能码 | quantity | 结果 |
|---|---|---|---|
| readCoils | 01 | 1~2000 | bits: boolean[] |
| readDiscreteInputs | 02 | 1~2000 | bits |
| readHoldingRegisters | 03 | 1~125 | registers: number[](u16) |
| readInputRegisters | 04 | 1~125 | registers |
3.3 写(FC05 / 06 / 15 / 16)
writeSingleCoil({ address: 0, value: true })
writeSingleRegister({ address: 0, value: 1234 })
writeMultipleCoils({ address: 0, values: [true, false, true] })
writeMultipleRegisters({ address: 0, values: [1, 2, 3] })
读写均可单次覆盖 unitId / timeout。忙碌时自动入队;可用 maxQueue 限制长度。
3.4 多从站 / 同从站多地址巡检 · 清空队列
pollUnits 完整支持在一次调用里按 items 顺序串行调度多条读写:
- 多从站:不同
unitId混排(经网关访问多台设备) - 同一从站多地址:相同
unitId、不同address/op/quantity(本机批量采多段点位) - 可读写混排;单项失败默认继续(
continueOnError: true)
地址连续时,优先用一条更大的 quantity 一次读完;地址不连续或需分段处理时,拆成多条 item 即可。
// 多从站
pollUnits({
items: [
{ unitId: 1, op: 'readHoldingRegisters', address: 0, quantity: 2 },
{ unitId: 2, op: 'readHoldingRegisters', address: 0, quantity: 2 },
{ unitId: 3, op: 'writeSingleRegister', address: 10, value: 1 },
],
continueOnError: true, // 默认 true;false 时遇错提前结束(仍 success,aborted=true)
success(res) {
// res.results: [{ index, unitId, op, ok, address, registers?/bits?/value?/quantity?/errMsg? }, ...]
},
})
// 同一 Modbus 设备、多地址批量读(unitId 相同,address 不同)
pollUnits({
items: [
{ unitId: 1, op: 'readHoldingRegisters', address: 0, quantity: 2 },
{ unitId: 1, op: 'readHoldingRegisters', address: 10, quantity: 4 },
{ unitId: 1, op: 'readCoils', address: 100, quantity: 8 },
],
success(res) {
;(res.results || []).forEach((row) => {
if (row.ok) console.log(row.address, row.registers || row.bits)
})
},
})
clearQueue({ success(res) { /* res.cleared */ } })
cancelPending({ success(res) { /* 与 clearQueue 相同 */ } })
pollUnits success 字段:
| 字段 | 说明 |
|---|---|
| results | 按 items 顺序的结果数组;每项含 index、unitId、op、ok、address,成功时含 registers/bits/value/quantity,失败时含 errCode、errMsg |
| count | results 长度 |
| aborted | continueOnError: false 且中途遇错时为 true;全部完成则为 false |
clearQueue / cancelPending success 字段:
| 字段 | 说明 |
|---|---|
| cleared | 本次从等待队列移除的请求数 |
clearQueue / cancelPending 只清空等待队列,不影响进行中的请求;被取消项 fail:9050002「队列已清空」。
3.5 状态
getConnectionState({
success(res) {
// res.state: idle | connecting | connected | disconnected
},
})
3.6 辅助函数(同步)
const i16 = registerToI16(regs[0])
const f = registersToFloat32(regs[0], regs[1], 'CDAB') // 四字序
const u = registersToU32(regs[0], regs[1], 'ABCD')
setDefaultByteOrder('BADC')
// 异常码与字序(由 index 导出,无需连接)
const label = exceptionCodeLabel(2) // 如「非法数据地址」
const msg = exceptionErrMsg(2) // 如「从站异常响应:非法数据地址(02)」
const order = normalizeByteOrder('LE') // 规范为 CDAB;BE→ABCD
| 函数 | 说明 |
|---|---|
| exceptionCodeLabel | Modbus 异常码 01~08 中文名;其它返回「异常码 N」 |
| exceptionErrMsg | 组装 9050008 用中文 errMsg(含异常码两位编号) |
| normalizeByteOrder | 将 BE/LE 等别名规范为 ABCD/BADC/CDAB/DCBA |
| 字序 | 含义 | 别名 |
|---|---|---|
| ABCD | 大端(默认) | BE |
| BADC | 字内字节交换 | — |
| CDAB | 字交换 | LE |
| DCBA | 全小端 | — |
数值辅助为纯函数,无需连接。defaultByteOrder / setDefaultByteOrder 只影响通用辅助默认字序,不改变原始 registers 回传。历史 registersToFloat32BE / registersToU32BE 仍可用(固定大端)。
4. 可配置项
| 字段 | 位置 | 默认 | 说明 |
|---|---|---|---|
| host | init | 必填 | 从站或网关 IP / 主机名 |
| port | init | 502 | TCP 端口(串口服务器按其映射口填写) |
| unitId | init / 读写 / poll 项 | 1 | 单元标识;读写与巡检项可覆盖 |
| timeout | init / 读写 / poll 项 | 3000 | 单次请求超时毫秒 |
| addressBase | init | 0 | 0=传入即协议地址;1=传入值减 1 后下发 |
| defaultByteOrder | init | ABCD | 数值辅助默认字序;可选 BADC/CDAB/DCBA;BE/LE 为别名 |
| transport | init | tcp | tcp=标准 MBAP;rtu-over-tcp=RTU 帧+CRC,经 TCP |
| maxQueue | init | 0(不限制) | 忙碌时读写请求队列上限;>0 时满队返回 9050002;可用 clearQueue 清空 |
| autoReconnect | init | false | 断线自动重连 |
| reconnectInterval | init | 3000 | 重连间隔毫秒 |
| debug | init | false | 调试日志 |
| onConnectionLost | init | 无 | 被动断线回调 |
| timeout | connect | 10000 | 建连超时毫秒 |
| address | 读写 / poll 项 | 必填 | 线圈或寄存器起始地址 |
| quantity | 读 / poll 读项 | 必填 | 读取数量(见 §3.2 范围) |
| value | writeSingleRegister / poll 项 | 必填 | 单寄存器写入值 |
| coilValue | poll 写线圈项 | false | writeSingleCoil 值 |
| values | writeMultipleRegisters / poll 项 | 必填 | 批量寄存器 |
| coilValues | writeMultipleCoils / poll 项 | 必填 | 批量线圈 |
| items | pollUnits | 必填 | 巡检项数组;可混多 unitId,也可同 unitId 多 address 批量读写;按序串行 |
| continueOnError | pollUnits | true | 单项失败后是否继续 |
| op | poll 项 | 必填 | 见 §3.4:readHoldingRegisters 等 |
不传参即用默认值。
4.1 串口服务器(RTU-over-TCP)
当设备侧为 Modbus RTU,中间经以太网串口服务器 / 协议网关透传时:
init({
host: '192.168.1.50',
port: 4001, // 串口服务器映射端口,按设备说明填写
unitId: 1,
transport: 'rtu-over-tcp',
})
链路仍为 TCP;报文为 [unitId][PDU][CRC16_lo][CRC16_hi]。功能码 API 与 tcp 模式相同。CRC 失败返回 9050012;半包未齐在超时内返回 9050006。不传 transport 或传 tcp 时使用标准 Modbus TCP(MBAP),与 1.0.0 一致。
5. 完整示例
5.1 uni-app(.vue)
直接传对象即可(JS 桥接按 XxxOption 映射回调与数字字段)。
import {
init,
connect,
pollUnits,
registersToFloat32,
disconnect,
destroy,
} from '@/uni_modules/breao-modbustcp'
init({
host: '192.168.1.10',
port: 502,
unitId: 1,
maxQueue: 64,
defaultByteOrder: 'ABCD',
success() {
connect({
success() {
pollUnits({
items: [
// 同一从站多地址
{ unitId: 1, op: 'readHoldingRegisters', address: 0, quantity: 2 },
{ unitId: 1, op: 'readHoldingRegisters', address: 10, quantity: 2 },
// 也可换 unitId 做多从站
{ unitId: 2, op: 'readHoldingRegisters', address: 0, quantity: 2 },
],
success(res) {
const rows = res.results || []
rows.forEach((row) => {
if (row.ok && row.registers && row.registers.length >= 2) {
console.log(row.unitId, row.address, registersToFloat32(row.registers[0], row.registers[1]))
}
})
disconnect({ success() { destroy({}) } })
},
})
},
})
},
fail(err) { console.error(err.errCode, err.errMsg) },
})
5.2 uni-app x(.uvue)
对象字面量默认为 UTSJSONObject,须在调用处 as XxxOption,否则编译报 error17。嵌套的 connect / pollUnits 同样要断言。
import {
init,
connect,
pollUnits,
registersToFloat32,
disconnect,
destroy,
ModbusTcpInitOption,
ModbusTcpConnectOption,
ModbusTcpPollUnitsOption,
ModbusTcpDisconnectOption,
ModbusTcpDestroyOption,
} from '@/uni_modules/breao-modbustcp'
init({
host: '192.168.1.10',
port: 502,
unitId: 1,
maxQueue: 64,
defaultByteOrder: 'ABCD',
success() {
connect({
success() {
pollUnits({
items: [
{ unitId: 1, op: 'readHoldingRegisters', address: 0, quantity: 2 },
{ unitId: 1, op: 'readHoldingRegisters', address: 10, quantity: 2 },
],
success(res) {
const rows = res.results || []
rows.forEach((row) => {
if (row.ok && row.registers != null && row.registers.length >= 2) {
console.log(row.unitId, row.address, registersToFloat32(row.registers[0], row.registers[1]))
}
})
disconnect({
success() {
destroy({} as ModbusTcpDestroyOption)
},
} as ModbusTcpDisconnectOption)
},
} as ModbusTcpPollUnitsOption)
},
} as ModbusTcpConnectOption)
},
fail(err) { console.error(err.errCode, err.errMsg) },
} as ModbusTcpInitOption)
若希望页面少写 as,可在业务层收口(参数类型已是 Option,调用处传对象即可):
import { init, ModbusTcpInitOption } from '@/uni_modules/breao-modbustcp'
export function initModbus(opt : ModbusTcpInitOption) {
init(opt)
}
// 页面:initModbus({ host: '...', port: 502, success() {} })
6. 权限
请在应用 manifest / 隐私弹窗中按需声明,并说明用于连接局域网 Modbus TCP 从站读写寄存器。
| 平台 | 权限 | 说明 |
|---|---|---|
| Android | android.permission.INTERNET | 访问网络连接从站 |
| Android | android.permission.ACCESS_NETWORK_STATE | 检测网络状态 |
| iOS | NSLocalNetworkUsageDescription | 访问局域网从站时说明用途 |
| 鸿蒙 | ohos.permission.INTERNET | 访问网络连接从站 |
7. 错误码(905)
| 码 | 含义 |
|---|---|
| 9050001 | 操作成功 |
| 9050002 | 操作失败(含队列已满、队列已清空、销毁取消等) |
| 9050003 | 未连接 |
| 9050004 | 参数非法(含未 init、地址/数量越界) |
| 9050005 | 连接失败 |
| 9050006 | 请求超时(含 RTU 半包未齐) |
| 9050007 | 当前平台不支持 |
| 9050008 | 从站异常响应(errMsg 含 01~08 中文说明) |
| 9050009 | 事务号不匹配(仅 tcp/MBAP) |
| 9050010 | 能力未实现 |
| 9050011 | 协议错误(帧解析失败等) |
| 9050012 | CRC 校验失败(rtu-over-tcp) |
从站异常码映射(写入 9050008 的 errMsg):01 非法功能码;02 非法数据地址;03 非法数据值;04 从站设备故障;05 已确认;06 从站设备忙;07 否定确认;08 存储器奇偶校验错误。
8. 平台注意
- 入参与端: uni-app(
.vue)直接传对象;uni-app x(.uvue)每个 API 对象字面量须as XxxOption(完整示例见 §5.2)。勿把对外形参改成any或自行 coerce 重建 Option,Android 易Integer cannot be cast to Function1。须 1.3.13+ 并重打自定义基座 - 手机与从站须网络可达;经网关时注意 Unit ID 与地址映射
- iOS 须允许本地网络访问,并在 Info.plist 填写用途说明
- 同一 TCP 连接可连续发起读写:忙碌时自动入队;
maxQueue>0 时满队返回 9050002;可用clearQueue/cancelPending清空等待项 pollUnits按 items 串行调度:支持多从站,也支持同一unitId下多address批量读写;可与其它读写共用同一队列;地址连续时优先单次大quantityaddressBase: 1时传入地址会减 1 后下发,适配部分组态软件习惯transport: 'rtu-over-tcp'仅改组帧方式,不提供真串口;端口以串口服务器配置为准(常见非 502)- 默认字序仍为大端(ABCD);勿把历史 BE/LE 业务数据无说明地改为其它四字序
- 从站异常响应 9050008 的
errMsg已由exceptionErrMsg输出中文说明;亦可单独用exceptionCodeLabel/exceptionErrMsg解析异常码

收藏人数:
购买普通授权版(
试用
赞赏(0)
下载 26
赞赏 0
下载 12594002
赞赏 1949
赞赏
京公网安备:11010802035340号