更新记录

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;忙碌时请求队列与 maxQueuepollUnits 支持多从站与同一从站多地址批量读写clearQueue / cancelPending;ABCD/BADC/CDAB/DCBA 四字序数值辅助;异常码中文 errMsg
  • 不做微信小程序(无原始 TCP)、不做真串口 / USB-RS485、不做 MQTT 云平台

建议调用顺序:initconnect → 读/写 / pollUnits(可夹数值辅助)→ disconnect / destroy。各异步方法均支持 success / fail / completefailerrCode / 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 批量读写;可与其它读写共用同一队列;地址连续时优先单次大 quantity
  • addressBase: 1 时传入地址会减 1 后下发,适配部分组态软件习惯
  • transport: 'rtu-over-tcp' 仅改组帧方式,不提供真串口;端口以串口服务器配置为准(常见非 502)
  • 默认字序仍为大端(ABCD);勿把历史 BE/LE 业务数据无说明地改为其它四字序
  • 从站异常响应 9050008 的 errMsg 已由 exceptionErrMsg 输出中文说明;亦可单独用 exceptionCodeLabel / exceptionErrMsg 解析异常码

隐私、权限声明

1. 本插件需要申请的系统权限列表:

Android: android.permission.INTERNET、android.permission.ACCESS_NETWORK_STATE。 iOS: NSLocalNetworkUsageDescription。 鸿蒙: ohos.permission.INTERNET。 用途:Modbus TCP 连接与读写。

2. 本插件采集的数据、发送的服务器地址、以及数据用途说明:

不采集、不上传任何数据;Modbus 报文仅在本机与用户配置的从站/网关之间传输

3. 本插件是否包含广告,如包含需详细说明广告表达方式、展示频率:

暂无用户评论。