1. Introduction to the Sensor
Model catalog
Search for these models in ThinkLink by name or ID.
| Model type | Name | id_name | Platform model 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 |
The SJ-101CX is a digital weighing transmitter module developed by Sanjiang Weighing Instruments. It amplifies, processes, and converts analog signals from load cells into digital weight data, which is then output via an RS485 interface. It is suitable for integration with weighing platforms, hopper scales, industrial weighing systems, and similar applications.
This document targets integration scenarios involving ThinkLink + EdgeBus. It consolidates hardware specifications, register definitions, EdgeBus configuration, ThinkLink Thing Model , and RPC configurations—enabling direct platform onboarding and device provisioning.
2. Key Features
- RS485 interface
- Compliant with standard Modbus-RTU protocol
- Default serial port parameters: 9600 baud, 8 data bits, no parity, 1 stop bit (8N1)
- Supports reading weight value, precision level, and device status
- Supports configuration of parameters such as slave address and baud rate
- Enables rapid onboarding to the ThinkLink platform via EdgeBus
3. Applicable Scenarios
- Industrial weighing data acquisition
- Platform scale and hopper scale data collection
- Wireless weighing data acquisition systems
- LoRaWAN-based edge data acquisition and cloud platform integration
4. Integration Specifications
4.1 Hardware Information
- Product Documentation:
SJ101CX_V1.02.pdf - Device Model:
SJ-101CX - Communication Interface: RS485
- Communication Protocol: Modbus-RTU
- Default RS485 Slave Address:
0x01(configurable via DIP switches) - Default Baud Rate:
9600 - Serial Format:
8N1 - Power Supply: DC
12–24 Vcan supplied by KC21 - Operating Temperature:
0–40 °C - Storage & Transportation Temperature:
−25–55 °C
4.2 Wiring Diagram
Power & Communication Interface
V+: Positive power supplyV−: Negative power supplyA+: RS485 A (non-inverting signal line)B−: RS485 B (inverting signal line)
Load Cell Interface
E+: Load cell excitation voltage positiveE−: Load cell excitation voltage negativeS+: Load cell signal positiveS−: Load cell signal negativeSH: Shield ground wire
5. Data Acquisition
In this solution, the following Modbus registers are read:
0x0000–0x0001: Weight value0x0002–0x0003: Precision and status
5.1 Register Definitions
| Access | Register Address | Function | Data Type | Description |
|---|---|---|---|---|
| Read-only | 0x0000–0x0001 | Current weight value | 32-bit signed integer | Raw weight value |
| Read-only | 0x0002 | Precision setting | 16-bit unsigned integer | Precision level: 0=1, 1=0.1, 2=0.01, 3=0.001 |
| Read-only | 0x0003 | Status word | 16-bit unsigned integer | Status bits bit0–bit5 |
| Write-only | 0x0004 | Zero calibration trigger | 16-bit unsigned integer | Write 1 to execute zeroing |
| Read/Write | 0x0009 | Baud rate | 16-bit unsigned integer | 0:9600, 1:14400, 2:19200, 3:38400, 4:115200 |
| Read/Write | 0x000B | Slave address | 16-bit unsigned integer | Range: 1–99; default: 1 |
| Write-only | 0x000C | Apply communication settings | 16-bit unsigned integer | Write 1 to activate new settings |
| Read/Write | 0x001B | ADC sampling rate | 16-bit unsigned integer | 0:10 Hz, 1:40 Hz |
| Write-only | 0x003A | Save user configuration | 16-bit unsigned integer | Write 1 to persist current settings |
| Read-only | 0x003B | Firmware version | 16-bit unsigned integer | Firmware version number |
5.2 Status Bit Definitions
| Bit | Meaning | Value 0 | Value 1 |
|---|---|---|---|
bit0 | Weighing stability | unstable | stable |
bit1 | Zero-point status | non-zero | zero |
bit2 | Overload status | normal | overload |
bit3 | Keypress event | no key pressed | key triggered |
bit4 | Power-on zero calibration | has zero point | no zero point |
bit5 | Weighing validity | invalid | valid |
6. EdgeBus Model
6.1 EdgeBus Configuration Parameters
| Parameter | Value |
|---|---|
bzType | 21307 |
Battery | true |
| Uplink Port | 22 |
version | 0x85 |
dataType | 0x04 |
| Default Modbus Slave Address | 0x01 |
| Modbus Function Code | 0x03 |
| Reporting Interval | Application address 70 |
| Sampling Interval | Application address 74 |
| Weight COV Threshold | Application address 110 |
| Slave Address Parameter | Application address 150 |
6.2 EdgeBus Configuration Code
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 Explanation
Current EdgeBus logic summary:
- Uses default slave address
0x01 - Reads registers
0x0000–0x0003 - Interprets
0x0000–0x0001as a 32-bit big-endian signed integer (weight) - Interprets
0x0002–0x0003as separate 16-bit fields (precision and status) - Weight supports Change-of-Value (COV); reporting threshold uses
app_110 - Reporting interval uses
app_70 - Sampling interval uses
app_74 - Slave address parameter maps to
app_150
7. Thing Model
7.1 Basic Thing Model Information
- Thing Model Name:
sj101cx_21307 - Thing Model ID:
88304368717139973
7.2 Uplink Frame Structure
- Port Number:
22 version:0x85dataType:0x04
| Field Name | Offset (bytes) | Length (bytes) | Data Type | Description |
|---|---|---|---|---|
version | 0 | 1 | Uint8 | Protocol version; fixed value 0x85 |
dataType | 1 | 1 | Uint8 | Fixed value 0x04 |
covStatus | 2 | 1 | Uint8 | Reserved byte |
status | 3 | 1 | Uint8 | Query event status |
battery | 4 | 1 | Uint8 | Battery voltage (V) |
addr | 5 | 1 | Uint8 | Sub-device Modbus slave address |
weight | 6 | 4 | Int32BE | Weight value (raw, scaled later) |
precision | 10 | 2 | Uint16BE | Precision multiplier |
statusBits | 12 | 2 | Uint16BE | Status bitfield |
7.3 Refined Thing Model Script
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. Third-Party Platform Data Subscription
8.1 MQTT Topic
/v32/{Organization Account}/tkl/up/telemetry/{eui}8.2 Sample Uplink Payload
{
"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 Interface
9.1 RPC Method Name
sj101cx_21307_get
9.2 Parameter Definitions
| Parameter Name | App Address | Unit | Description |
|---|---|---|---|
pwron_delay | 38 | ms | Power-on delay time; default: 1000 ms |
periodUP | 70 | s | Telemetry reporting interval |
periodRead | 74 | s | Register polling interval |
cov_weight | 110 | kg | Weight change-of-value (COV) threshold |
addr | 150 | — | Modbus slave address |
9.3 Refined RPC Code
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. Template Selection
In the ThinkLink platform, search for the device template using either:
SJ101CX
or, by business type:
21307