1. 传感器简介
模型清单
可使用下列名称或 ID 在 ThinkLink 中搜索对应模型。
| 模型类型 | 名称 | id_name | 平台模型 ID |
|---|---|---|---|
| RPC | [SJ101CX GET] para | sj101cx_21307_get | 88308771574517765 |
| RPC | [SJ101CX SET] para | sj101cx_21307_set | 88308422692311045 |
| Template | SJ101CX | 88309182834413573 | |
| Thing Model | [SJ101CX] | sj101cx_21307 | 88304368717139973 |
| Thing Model | [SJ-21307-SJ101CX资产] 区域聚合 | sj101cx_asset_21307 | 119677174411063302 |
SJ-101CX 是一款三江衡器开发的数字称重变送模块,用于将称重传感器输出的模拟信号进行放大、处理并转换为数字重量数据,通过 RS485 接口输出,适合对接称重平台、料斗秤、工业称重系统等场景。
本文档面向 ThinkLink + EdgeBus 对接场景,整理了 SJ101CX 的硬件信息、寄存器信息、EdgeBus 配置、ThinkLink 物模型及 RPC 配置,可直接用于平台接入与发布。
2. 产品特点
- RS485 接口,支持远距离通信
- 支持标准 Modbus-RTU 协议
- 默认串口参数:9600,8N1
- 支持重量、精度、状态读取
- 支持地址、波特率等参数配置
- 支持 EdgeBus 快速接入 ThinkLink 平台
3. 适用范围
- 工业称重采集
- 平台秤、料斗秤数据采集
- 无线称重采集系统
- LoRaWAN 边缘采集与云平台接入
4. 对接信息
4.1 硬件信息
- 产品资料:SJ101CX_V1.02.pdf
- 设备型号:SJ-101CX
- 通信接口:RS485
- 通信协议:Modbus-RTU
- 默认 RS485 地址:
0x01(可通过拨码开关进行设置) - 默认波特率:
9600 - 串口格式:
8N1 - 供电方式:DC
12~24V,通过KC21 给设备供电 - 使用温度:
0~40℃ - 储运温度:
-25~55℃
4.2 接线信息
电源与通讯接口
V+:电源正V-:电源负A+:RS485 AB-:RS485 B
传感器接口
E+:传感器电源正E-:传感器电源负S+:传感器信号正S-:传感器信号负SH:屏蔽线
5. 数据采集
本方案中,通过 Modbus 读取以下寄存器:
0x0000 ~ 0x0001:重量值0x0002 ~ 0x0003:精度与状态
5.1 寄存器定义
| 状态 | 寄存器地址 | 寄存器功能 | 数据类型 | 说明 |
|---|---|---|---|---|
| 只读 | 0x0000~0x0001 | 当前重量值 | 32 位有符号整型 | 当前重量原始值 |
| 只读 | 0x0002 | 精度 | 16 位无符号整型 | 精度位,0/1/2/3 分别表示 1、0.1、0.01、0.001 |
| 只读 | 0x0003 | 状态 | 16 位无符号整型 | 状态位 bit0~bit5 |
| 写 | 0x0004 | 清零 | 16 位无符号整型 | 写 1 执行清零 |
| 读写 | 0x0009 | 波特率 | 16 位无符号整型 | 0:9600,1:14400,2:19200,3:38400,4:115200 |
| 读写 | 0x000B | 从机地址 | 16 位无符号整型 | 范围 1~99,默认 1 |
| 写 | 0x000C | 通讯参数生效 | 16 位无符号整型 | 写 1 生效 |
| 读写 | 0x001B | AD 采样速率 | 16 位无符号整型 | 0:10Hz,1:40Hz |
| 读写 | 0x003A | 保存用户数据 | 16 位无符号整型 | 保存配置 |
| 只读 | 0x003B | 当前版本 | 16 位无符号整型 | 固件版本号 |
5.2 状态位定义
| Bit 位 | 含义 | 0 | 1 |
|---|---|---|---|
| bit0 | 称重稳定性 | unstable | stable |
| bit1 | 零点状态 | non-zero | zero |
| bit2 | 超重状态 | normal | overload |
| bit3 | 按键触发 | no key | key triggered |
| bit4 | 开机零点 | has zero | no zero |
| bit5 | 称重有效性 | invalid | valid |
6. EdgeBus 模型
6.1 EB 配置参数
| 配置项 | 值 |
|---|---|
| bzType | 21307 |
| Battery | true |
| 上行端口 | 22 |
| version | 0x83 |
| dataType | 0x39 |
| 默认 Modbus 地址 | 0x01 |
| Modbus 功能码 | 0x03 |
| 上报周期 | app 地址 70 |
| 采集周期 | app 地址 74 |
| 重量 COV | app 地址 110 |
| 从机地址 | app 地址 150 |
6.2 EB 代码
typescript
import { Buffer } from "buffer";
import { buildOtaFile } from "@EBSDK/run";
import {
ActionAfertExpr, CalcData,
CrcMode,
CvtRule,
EBBuffer,
EBModel,
ExprCondition,
LoraUpEvent,
QueryEvent, SetUpCovDataType,
UserConfUPItem,EventInfoItem
} from "@EBSDK/EBCompiler/all_variable";
import { CheckbitEnum, getOtaConfig, HwTypeEnum, UpgrdTypeEnum } from "@EBSDK/otaConfig";
////////////////////////////////////////////////////////////////////////////////////////
const eventInfo:UserConfUPItem[]=[
{
name:"sj101cx",port:21,version:"0x85",dataType:"0x04",upPeriodIndex:70,
quInfo:[
{
protocol:"modbus",addr:"0x02",code:"0x03", periodIndex:74,
indexAPP:150, indexCMD:0, copySize:1,isLast:false,//period:"900s",payIndex:3,ackAddrIndex:0,
listVal:[
{ start: "0", end: "1" ,covType:"Uint32BE",covAppIndex:110}, //cov:true,covAppIndex:
{ start: "2", end: "3" } //cov:false,covAppIndex:0
]
}
]
}
]
let otaConfig = getOtaConfig({
SwVersion:31,
BaudRate: 9600,
StopBits: 1,
DataBits: 8,
Checkbit: CheckbitEnum.NONE,
Battery: true,
ConfirmDuty: 60,
BzType: 21307,
BzVersion: 11
})
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(import.meta.url, otaConfig, MODBUS_TT)6.3 说明
当前 EB 逻辑说明:
- 使用默认从机地址
0x01 - 读取寄存器
0x0000 ~ 0x0003 0x0000 ~ 0x0001解析为 32 位重量值0x0002 ~ 0x0003解析为精度与状态- 重量值支持 COV,上报阈值使用
app_110 - 上报周期使用
app_70 - 采集周期使用
app_74 - 从机地址参数映射到
app_150
7. 物模型
7.1 物模型基本信息
- 物模型名称:
sj101cx_21307 - 物模型 ID:
88304368717139973
7.2 上行帧结构
- 端口号:
22 - version:
0x83 - dataType:
0x39
| 字段名 | 偏移 | 长度(Bytes) | 类型 | 含义说明 |
|---|---|---|---|---|
| version | 0 | 1 | Uint8 | 协议版本,固定为 0x85 |
| dataType | 1 | 1 | Uint8 | 固定为 0x04 |
| covStatus | 2 | 1 | Uint8 | 保留字节 |
| status | 3 | 1 | Uint8 | 查询事件状态 |
| battery | 4 | 1 | Uint8 | 电池值 |
| addr | 5 | 1 | Uint8 | 子设备地址 |
| weight | 6 | 4 | Int32BE | 重量值 |
| precision | 10 | 2 | Uint16BE | 精度倍率 |
| statusBits | 12 | 2 | Uint16BE | 状态位 |
7.3 修正后的物模型脚本
javascript
let port = msg?.userdata?.port || null;
let frameInfo = {
port: 22,
dataLen: -1,
rssi: true,
battery: 4,
tagList: [
{ index: 0, tag: 0x85 },
{ index: 1, tag: 0x04 }
]
};
let appInfo = [
{
name: "weight",
field_name: "weight",
unit: "kg",
index: 6,
dataType: "int32BE",
coefficient: "precision",
decimal: 2,
illegal: "=00000000"
},
{
name: "precision",
field_name: "precision",
unit: "",
index: 10,
coefficient: 1,
dataType: "uint16BE",
optionList: {
0: 1,
1: 0.1,
2: 0.01,
3: 0.001
}
},
{
name: "status1",
field_name: "status1",
unit: "",
index: 12,
coefficient: 1,
dataType: "bitBE0-0",
optionList: {
0: "unstable",
1: "stable"
}
},
{
name: "status2",
field_name: "status2",
unit: "",
index: 12,
coefficient: 1,
dataType: "bitBE5-5",
optionList: {
0: "invalid",
1: "valid"
}
}
];
let paraDef = {
app_38: {
name: "pwron_delay",
field_name: "pwron_delay",
unit: "ms",
index: 38,
type: "uint16LE"
},
app_70: {
name: "periodUP",
field_name: "periodUP",
unit: "s",
type: "uint32LE"
},
app_74: {
name: "periodRead",
field_name: "periodRead",
unit: "s",
type: "uint32LE"
},
app_110: {
name: "cov_weight",
field_name: "cov_weight",
unit: "kg",
type: "int16BE",
coefficient: 0.1,
decimal: 1
},
app_150: {
name: "addr",
field_name: "addr",
unit: "",
type: "uint8"
}
};
let pdata = {};
let tdata = {};
let payParser = new PayloadParser({
device: device,
msg: msg,
frameInfo: frameInfo,
appInfo: appInfo,
paraInfo: paraDef,
});
if (port === 214) {
pdata = payParser.paras();
tdata = null;
} else {
tdata = payParser.telemetry();
pdata = null;
}
return {
telemetry_data: tdata,
server_attrs: null,
shared_attrs: pdata
};8. 第三方平台数据订阅
8.1 MQTT Topic
latex
/v32/{Organization Account}/tkl/up/telemetry/{eui}8.2 上报示例数据
json
{
"eui": "6353012af10a9331",
"active_time": "2026-02-05T08:35:48.000Z",
"thingModelId": "88304368717139973",
"thingModelIdName": "sj101cx_21307",
"telemetry_data": {
"snr": 13.5,
"rssi": -51,
"battery": 3.37,
"weight": 12.34,
"precision": 0.01,
"status1": "stable",
"status2": "valid"
}
}9. RPC
9.1 RPC 名称
sj101cx_21307_get
9.2 参数定义
| 参数名 | App 地址 | 单位 | 说明 |
|---|---|---|---|
| pwron_delay | 38 | ms | 上电延时,默认1000ms |
| periodUP | 70 | s | 上报周期 |
| periodRead | 74 | s | 读取周期 |
| cov_weight | 110 | kg | 重量 COV 阈值 |
| addr | 150 | - | Modbus 从机地址 |
9.3 修正后的 RPC 代码
javascript
let paraDef = {
app_38: {
name: "pwron_delay",
field_name: "pwron_delay",
unit: "ms",
index: 38,
type: "uint16LE"
},
app_70: {
name: "periodUP",
field_name: "periodUP",
unit: "s",
type: "uint32LE"
},
app_74: {
name: "periodRead",
field_name: "periodRead",
unit: "s",
type: "uint32LE"
},
app_110: {
name: "cov_weight",
field_name: "cov_weight",
unit: "kg",
type: "int16BE",
coefficient: 0.1,
decimal: 1
},
app_150: {
name: "addr",
field_name: "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 + redoBuffer.length
);
frames.writeBuffer.copy(dnBuffer, 0);
frames.readBuffer.copy(dnBuffer, frames.writeBuffer.length);
redoBuffer.copy(dnBuffer, frames.writeBuffer.length + frames.readBuffer.length);
logger.info("get/set sj101cx para");
let msg = RPCHelper.makeMSG({
msgType: Utils.msgType.paras,
device: device,
dnBuffer: dnBuffer,
sleepTime: 0,
});
return [msg];10. 模板选择
在 ThinkLink 平台中搜索模板:
SJ101CX
或按业务类型查找:
21307