DS1603 超声波液位计接入 ThinkLink 对接文档
1. 传感器简介
DS1603 是深圳市星科创科技有限公司生产的一款 超声波液位计,采用非接触超声波穿透容器壁检测液位的原理,可输出 RS485(Modbus-RTU) 信号,适用于各类工业储罐、水处理池的液位连续监测。设备具备 IP67 防护等级,可穿透 ≤20mm 的非金属容器壁,不接触液体即可完成测量。
本次对接方案中,设备型号为 DS1603,业务代码为 22109,模板名称为 DS1603。
2. 产品特点
根据厂家资料,DS1603 具备以下特点:
- 非接触检测 — 穿透塑料、玻璃、陶瓷等非金属容器壁,无需开孔
- 抗腐蚀 — 不接触强酸强碱等液体,寿命耐久
- 抗干扰 — 针对工频干扰和共模干扰特殊处理
- 高精度 — 毫米级分辨率(±1.5mm),实时连续输出
- 液体普适性 — 不受液体密度、形状、杂质、泡沫、水垢影响
- IP67 防护 — 适用于潮湿和户外环境
- RS485 Modbus RTU — 支持多点串联(最多 32 点)
3. 适用范围
DS1603 可广泛应用于以下场景:
- 工业储罐液位监测 — 化工厂、电镀厂酸/碱/溶剂储罐
- 水处理液位监控 — 水塔、水箱、废水处理池液位实时监测
- 多仓集中监控 — RS485 总线一主多从,集中管理多个储罐
- 农业灌溉水位管理 — 大棚营养液罐、灌溉水箱液位监测
4. 采集器信息
4.1 硬件信息
本方案采集设备采用 KC21。
- 设备型号:KC21
- 接口:RS-485
- 供电方式:内置电池 10800mAH / DC 5-12V
4.2 接线信息
电源与通讯接口
DS1603 的 RS485 输出接线定义如下:
- Pin 1:VCC(12-24V 电源正极)
- Pin 2:GND(电源负极)
- Pin 3:RS485 A (+)
- Pin 4:RS485 B (-)
传感器接口
本方案中,DS1603 自带 RS485 输出接口,直接接入 KC21 的 RS485 接口即可。 接线端子为 2.54mm 间距 4pin 排针。
5. 数据采集
本方案中,通过 Modbus 读取以下寄存器:
- 0x00:液位处理值,uint16BE,单位 mm(本集成仅采集此寄存器)
平台侧约定:
- 上传/采集周期参数地址:70(共用同一周期)
5.1 寄存器定义
根据厂家 Modbus 寄存器表(功能码 03H 读 / 06H 写),寄存器定义如下:
| 地址 | 项目描述 | 数据类型 | 读写 | 说明 |
|---|---|---|---|---|
| 0x00 | 液位处理值 | uint16BE | R | 多次采样处理后的稳定液位,单位 mm(本集成采集此点) |
| 0x01 | 液位实时值 | uint16BE | R | 每次采样的瞬时液位,单位 mm(本集成未采集) |
| 0x04 | 从机地址 | uint16BE | R/W | Modbus 从站地址,默认 1,范围 1-247,掉电保存 |
| 0x05 | 测量介质 | uint16BE | R/W | 1=水,2=油,默认 1 |
| 0x06 | 工作周期 | uint16BE | R/W | N 秒工作一次,N=1-60s,默认 2s |
注:设备无波特率寄存器,串口固定 9600,N,8,1。
支持的 Modbus 功能码:
- 03H:读保持寄存器
- 06H:写单个寄存器
5.2 通信示例
读取液位处理值 (0x00):
Request: 01 03 00 00 00 01 84 0A
Response: 01 03 02 00 DD F9 85 (示例: 处理值 = 0x00DD = 221mm)写测量介质 (0x05) — 改为油:
Request: 01 06 00 05 00 02 18 0A
Response: 01 06 00 05 00 02 18 0A (原帧回显 = 成功)6. EdgeBus 模型
6.1 EB 配置参数
主要配置参数如下:
name: "xkc-ds1603"port: 22version: "0x87"dataType: "0x10"upPeriodIndex: 70- Modbus 默认串口参数:
BaudRate: 9600StopBits: 1DataBits: 8Checkbit: NONE
BzType: 22109BzVersion: 1
6.2 EB 代码
import { Buffer } from "buffer";
import { buildOtaFile } from "@EBSDK/run";
import { EBModel } from "@EBSDK/EBCompiler/EBModel/EBModel";
import { EventInfoItem } from "@EBSDK/EBCompiler/plugins/EBHelper";
import type { UserConfUPItem } from "@EBSDK/EBCompiler/plugins/EBHelper";
import { CheckbitEnum, getOtaConfig } from "@EBSDK/otaConfig";
const eventInfo: UserConfUPItem[] = [
{
name: "xkc-ds1603", port: 22, version: "0x87", dataType: "0x10", upPeriodIndex: 70,
quInfo: [
{
protocol: "modbus", addr: "0x01", code: "0x03", periodIndex: 70,
indexAPP: 150, indexCMD: 0, copySize: 1,
listVal: [
{ start: "0", end: "1" }
]
}
]
}
];
let otaConfig = getOtaConfig({
BaudRate: 9600,
StopBits: 1,
DataBits: 8,
Checkbit: CheckbitEnum.NONE,
Battery: true,
ConfirmDuty: 60,
BzType: 22109,
BzVersion: 1
});
const MODBUS_TT = (ebModel: EBModel) => {
for (let i = 0; i < eventInfo.length; i++) {
let event = new EventInfoItem(eventInfo[i]);
event.upEventSetup();
event.eventInstall();
}
return JSON.stringify(ebModel, null, 2);
};
buildOtaFile(__filename, otaConfig, MODBUS_TT);6.3 说明
当前 EB 逻辑说明:
- EdgeBus 通过 Port 22 上报业务数据。
- 读取寄存器 0x00(共 1 个寄存器),获取液位处理值。
- 上传周期与采集周期相同,均由 APP 参数
70管理。 - Modbus 地址由 APP 参数
150管理。
7. 物模型
7.1 物模型基本信息
数据物模型
- 名称:
[DS1603] - id Name:
ds1603_22109
参数物模型
- 名称:
[DS1603-PARA] - id Name:
ds1603_para_22109
7.2 上行帧结构
数据上行帧结构如下:
let frameInfo = {
port: 22, dataLen: 8, rssi: true, battery: 4,
tagList: [{index: 0, tag: 0x87}, {index: 1, tag: 0x10}]
}字段定义如下:
index 6:levelProcessed,uint16BE,液位处理值(mm)
说明:设备 Modbus 有处理值(0x00)和实时值(0x01)两个寄存器,但本集成 EB 仅读取 0x00 处理值,因此物模型只有 levelProcessed 一个遥测点,不采集 levelRealtime。
7.3 物模型脚本
7.3.1 数据物模型脚本
let port = msg?.userdata?.port || null;
if (port !== 22) return null
let frameInfo = {
port: 22, dataLen: 8, rssi: true, battery: 4,
tagList: [{index: 0, tag: 0x87}, {index: 1, tag: 0x10}]
}
let appInfo = [
{name: "levelProcessed", field_name: "levelProcessed", unit: "mm", index: 6, type: "uint16BE"},
]
let payParser = new PayloadParser({
device: device,
msg: msg,
frameInfo: frameInfo,
appInfo: appInfo,
})
let tdata = payParser.telemetry()
if ((tdata?.status & 0x02) === 0x02) {
const status = tdata.status
tdata = {...(device.telemetry_data?.[thingModelId] ?? {})}
tdata.status = status
}
return {
telemetry_data: tdata,
server_attrs: null,
shared_attrs: null
}7.3.2 参数物模型脚本
let port = msg?.userdata?.port || null;
const rpcName = "ds1603_set_22109"
let paraDef = {
app_70: {name: "period_up", field_name: "period_up", unit: "s", type: "uint32LE"},
app_150: {name: "modbus_addr", field_name: "modbus_addr", unit: "", type: "uint8"}
}
if (port !== 214) {
let checkData = Utils.paraCheck(rpcName, device.server_attrs, device.shared_attrs)
return {
server_attrs: checkData.sdata,
actions: checkData.actions,
}
}
let pdata = (new PayloadParser({
device: device,
msg: msg,
paraInfo: paraDef,
})).paras()
let checkData = Utils.paraCheck(rpcName, device.server_attrs, pdata)
return {
telemetry_data: pdata,
server_attrs: checkData.sdata,
shared_attrs: pdata,
actions: checkData.actions,
}8. 第三方平台数据订阅
8.1 MQTT Topic
/v32/{Organization Account}/tkl/up/telemetry/{eui}
8.2 上报示例数据
根据本模板的物模型字段,整理后的示例数据如下:
{
"eui": "6353012af10a9429",
"active_time": "2026-05-11T08:35:48.000Z",
"thingModelId": "22109",
"thingModelIdName": "ds1603_22109",
"telemetry_data": {
"snr": 11.8,
"rssi": -37,
"battery": 3.65,
"levelProcessed": 221
}
}说明:
thingModelId实际应以平台生成值为准,这里用业务代码22109作示例。thingModelIdName对应数据物模型ds1603_22109。levelProcessed为超声波传感器到液面的处理后液位值,单位 mm。
9. RPC
9.1 RPC 名称
配置参数 RPC
- 名称:
[DS1603 SET] 22109 - id Name:
ds1603_set_22109
读取参数 RPC
- 名称:
[DS1603 GET] 22109 - id Name:
ds1603_get_22109
测量介质 RPC(Action)
- 名称:
[DS1603 SET MEDIUM] 22109 - id Name:
ds1603_set_medium_22109
9.2 参数定义
| 参数地址 | 名称 | field_name | 单位 | 类型 | 说明 |
|---|---|---|---|---|---|
| app_70 | period_up | period_up | s | uint32LE | 上传/采集周期 |
| app_150 | modbus_addr | modbus_addr | uint8 | Modbus 地址 |
9.3 RPC 代码
配置参数 RPC
let classMode = (device && device.shared_attrs && device.shared_attrs.class_mode) || "ClassA";
let intervalms = classMode === "ClassA" ? 0 : 2000;
const rpcName = "ds1603_set_22109"
let paraDef = {
app_70: {name: "period_up", field_name: "period_up", unit: "s", type: "uint32LE"},
app_150: {name: "modbus_addr", field_name: "modbus_addr", unit: "", type: "uint8"}
}
let frames = RPCHelper.buildFrame({
paraDef: paraDef,
params: params
})
let redoBuffer = RPCHelper.redo()
let dnBuffer = Buffer.alloc(frames.writeBuffer.length + frames.readBuffer.length);
frames.writeBuffer.copy(dnBuffer, 0)
frames.readBuffer.copy(dnBuffer, frames.writeBuffer.length)
logger.info("set para")
let msgQue = Utils.makeParaSetMSG({
device: device,
classMode: classMode,
rpcName: rpcName,
params: params,
paraDownBuffer: dnBuffer,
extraAppBuffer: redoBuffer
})
if (msgQue.length == 0) return null
return msgQue读取参数 RPC
let classMode = (device && device.shared_attrs && device.shared_attrs.class_mode) || "ClassA";
let sleepMs = classMode === "ClassA" ? 500 : 5000;
let paraDef = {
app_70: {name: "period_up", field_name: "period_up", unit: "s", type: "uint32LE"},
app_150: {name: "modbus_addr", field_name: "modbus_addr", unit: "", type: "uint8"}
}
let frames = RPCHelper.buildFrame({
paraDef: paraDef,
params: params
})
let msg = RPCHelper.makeMSG({
msgType: Utils.msgType.paras,
device: device,
dnBuffer: frames.readBuffer,
sleepTime: sleepMs,
})
return [msg]9.4 测量介质 RPC(Action)
通过透明通道向设备寄存器 0x05 写测量介质(Modbus 功能码 06H),并校验设备回显、同步共享属性。
参数定义
| 参数 | field_name | 类型 | 取值 | 说明 |
|---|---|---|---|---|
| medium | medium | number | 1=水 / 2=油 | 测量介质(下拉选择),默认 1=水 |
读取路径:设置成功后
medium同步到共享属性,下次打开表单自动回填当前值(无独立 get RPC)。
RPC 代码
let classMode = (device?.shared_attrs?.class_mode) || "ClassA";
let addr_modbus = device.shared_attrs?.addr_modbus ?? device.shared_attrs?.addr ?? 1;
let rpcName = "ds1603_set_medium_22109";
// 测量介质:寄存器 0x05,FC06 写。1=水,2=油(其他值无效)
if (params.medium === undefined) return null;
let checkVal = Number(params.medium);
if (checkVal !== 1 && checkVal !== 2) return null;
let dnBuffer = RPCHelper.modbusAction(addr_modbus, 6, 0x0005, checkVal);
let checkInfo = {
frameInfo: {port: 51, dataLen: 8},
appInfo: [{field_name: "medium", index: 4, type: "uint16BE", val: checkVal}],
telemetry_data: {medium: checkVal},
server_attrs: null,
shared_attrs: {medium: checkVal}
};
let msgQue = Utils.makeParaSetMSG({
msgType: Utils.msgType.transParent,
checkInfo: checkInfo,
device: device,
classMode: classMode,
rpcName: rpcName,
params: params,
paraDownBuffer: dnBuffer,
timeout: 3000,
maxRetries: 3
});
if (msgQue.length === 0) return null;
return msgQue;Modbus 报文示例(写测量介质=油)
Request: 01 06 00 05 00 02 18 0A
Response: 01 06 00 05 00 02 18 0A (原帧回显 = 成功)10. 模板选择
在 ThinkLink 平台中搜索模板: DS1603
或按业务类型查找: 22109 / 超声波液位计 / RS485 Modbus 液位采集
补充说明
- 厂家默认 Modbus 参数为:
- 地址:1
- 波特率:9600
- 数据位:8
- 停止位:1
- 校验:无校验 这些参数可通过上位机工具修改。
- DS1603 采用非接触测量原理,传感器探头安装于容器外壁,穿透非金属壁进行液位检测,适用于强酸、强碱等腐蚀性液体的储罐监测。
- 设备支持 RS485 一主多从模式(最多 32 点),可通过单个 KC21 集中管理多个储罐液位。
- 厂家文档给出的 Modbus 报文示例:
- 读液位处理值:
01 03 00 00 00 01 84 0A - 写从机地址(改为 0x02):
01 06 00 04 00 02 49 CA - 写测量介质(改为油):
01 06 00 05 00 02 18 0A
- 读液位处理值: