1. 传感器简介
AQ3485 是奥青(AoQing)生产的一款双通道温度传感器,采用 Modbus-RTU / RS-485 接口,支持同时采集冷藏室温度和融霜温度两路数据,适用于冷链冷藏监控场景。本方案通过 KC21(电池版)DTU 将传感器数据接入 ThinkLink 平台,支持 COV 变化触发上报。
本次对接方案中,设备型号为 AQ3485,业务代码为 21306,模板名称为 AQ3485。
2. 产品特点
- 双通道温度采集:冷藏室温度 + 融霜温度
- RS-485 接口,Modbus-RTU 协议
- 默认地址
0x01,波特率 9600,8N1 - 支持温度 COV 变化触发上报(独立阈值)
- 低功耗设计,KC21 电池供电版接入
3. 适用范围
AQ3485 可应用于以下场景:
- 超市、便利店冷柜温度监控
- 冷藏库冷藏室与融霜温度监控
- 冷链运输温湿度管理
- 食品、医药行业冷藏设备状态监控
4. 采集器信息
4.1 硬件信息
本方案采集设备采用 KC21(电池版)。
- 设备型号:KC21
- 接口:RS-485
- 供电方式:电池供电
- LoRaWAN Class:A
4.2 接线信息
电源与通讯接口
KC21 电池版向传感器提供供电,RS-485 接线定义:
- A 端(KC21)→ RS-485A(传感器)
- B 端(KC21)→ RS-485B(传感器)
传感器接口
AQ3485 使用 RS-485 接口,默认波特率 9600,8N1,无校验。直接与 KC21 的 RS-485 接口相连,KC21 为传感器提供供电。
5. 数据采集
本方案中,通过 Modbus 读取以下寄存器:
0x0000:冷藏室温度(int16BE,×0.1℃)0x0001:融霜温度(int16BE,×0.1℃)
平台侧约定:
- 上传周期参数地址:70
- 采集周期参数地址:74
- 上电延时参数地址:38
5.1 寄存器定义
| 地址(十六进制) | 项目描述 | 数据类型 | 说明 |
|---|---|---|---|
0x0000 | 冷藏室温度 | Int16BE(有符号整型,大端) | 原始值 × 0.1 = 实际温度(℃) |
0x0001 | 融霜温度 | Int16BE(有符号整型,大端) | 原始值 × 0.1 = 实际温度(℃) |
6. EdgeBus 模型
6.1 EB 配置参数
| 配置项 | 值 |
|---|---|
name | "AQ3485" |
port | 21 |
version | "0x85" |
dataType | "0x03" |
upPeriodIndex | 70 |
periodIndex(采集) | 74 |
BaudRate | 9600 |
StopBits | 1 |
DataBits | 8 |
Checkbit | NONE |
Battery | true |
BzType | 21306 |
BzVersion | 12 |
SwVersion | 31 |
6.2 EB 代码
typescript
import {Buffer} from "buffer";
import {buildOtaFile} from "@EBSDK/run";
import {EBModel, EventInfoItem, LoraUpEvent, UserConfUPItem, CheckbitEnum, getOtaConfig, HwTypeEnum} from "@EBSDK/EBCompiler/all_variable";
////////////////////////////////////////////////////////////////////////////////////////
const eventInfo:UserConfUPItem[]=[
{
name:"AQ3485",port:21, version:"0x85",dataType:"0x03",upPeriodIndex:70,
quInfo:[
{
protocol:"modbus",code:"0x03", periodIndex:74,//addr:"0x01",
indexAPP:150, indexCMD:0, copySize:1,isLast:false,
listVal:[
{ start: "1", end: "1" ,covType:"Int16BE",covAppIndex:110}, //冷藏室温度,refrigerator_temp,coefficient=0.1
{ start: "2", end: "2" ,covType:"Int16BE",covAppIndex:112} //融霜温度,defrost_temp,coefficient=0.1
]
}
]
}
]
let otaConfig = getOtaConfig({
SwVersion:31,
BaudRate: 9600,
StopBits: 1,
DataBits: 8,
Checkbit: CheckbitEnum.NONE,
Battery: true,
ConfirmDuty: 60,
BzType: 21306,
BzVersion: 12
})
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 逻辑说明:
- EdgeBus 通过 Port 21 上报业务数据。
- 一次查询事件:单次 Modbus 读取寄存器 0x0000(冷藏室温度)和 0x0001(融霜温度),连续读 2 个寄存器,共 4 字节。
- 上传周期与采集周期分离:
- App 地址
70为上报周期 - App 地址
74为采集周期
- App 地址
- COV 触发:冷藏室温度(App 地址
110)和融霜温度(App 地址112)各自独立 COV 阈值,变化超过阈值时立即触发上报。 - Modbus 从机地址由 App 参数
150管理,支持运行时修改。 - 数据类型为 Int16BE(有符号大端),除以 10 得到实际温度(℃)。
7. 物模型
7.1 物模型基本信息
数据物模型
- 名称:
[AQ3485] - id Name:
aq3485_21306
7.2 上行帧结构
frameInfo: { port: 21, dataLen: -1, rssi: true, battery: 4 }
tagList: [{ index: 0, tag: 0x85 }, { index: 1, tag: 0x03 }]上行帧字段定义(从 byte 6 起为业务数据):
| 偏移(index) | 字段名 | 类型 | 单位 | 说明 |
|---|---|---|---|---|
| 0 | version | uint8 | — | 协议版本,固定 0x85 |
| 1 | dataType | uint8 | — | 业务类型,固定 0x03 |
| 2 | covStatus | uint8 | — | COV 触发状态 |
| 3 | status | uint8 | — | 查询事件状态 |
| 4 | battery | uint8 | — | 电池电量(4 字节编码) |
| 5 | addr | uint8 | — | 子设备 Modbus 地址 |
| 6–7 | humidity | Int16BE | ℃×0.1 | 冷藏室温度(field_name: humidity) |
| 8–9 | temperature | Int16BE | ℃×0.1 | 融霜温度(field_name: temperature) |
注:字段
humidity和temperature的命名源自平台注册时的命名约定,实际含义分别为冷藏室温度和融霜温度。
7.3 物模型脚本
7.3.1 数据物模型脚本
javascript
import {PayloadParser} from '#tklHelper';
function payload_parser({device, msg, thingModelId, noticeAttrs}) {
let port=msg?.userdata?.port || null;
let frameInfo={
port:21, dataLen:-1,rssi:true,battery:4,
tagList:[{ index:0, tag:0x85}, { index:1, tag:0x03}]
}
let appInfo = [
{ name: "humidity", field_name: "humidity", unit:"℃", index: 6, type: "int16BE",coefficient:0.1,decimal:1},
{ name: "temperature", field_name: "temperature", unit:"℃", index: 8, type: "int16BE",coefficient:0.1,decimal:1},
]
let paraInfo= {
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_temperature", field_name: "cov_temperature", unit: "℃", type: "int16BE",coefficient:0.1,decimal:1},
app_112: {name: "cov_humidity", field_name: "cov_humidity", unit: "℃", 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:paraInfo,
})
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
/v32/{Organization Account}/tkl/up/telemetry/{eui}
8.2 上报示例数据
json
{
"eui": "6353012af10a9331",
"active_time": "2026-02-05T08:35:48.000Z",
"thingModelId": "87554295540486149",
"thingModelIdName": "aq3485_21306",
"telemetry_data": {
"snr": 10.5,
"rssi": -65,
"battery": 3.21,
"humidity": -5.2,
"temperature": 18.3
}
}说明:
thingModelId以平台生成值为准(87554295540486149)。thingModelIdName对应数据物模型aq3485_21306。humidity字段含义为冷藏室温度(单位:℃),示例值-5.2℃为典型冷藏室温度。temperature字段含义为融霜温度(单位:℃),示例值18.3℃为融霜时环境温度。
9. RPC
9.1 RPC 名称
配置参数 RPC
- 名称:
[AQ3485 SET] para - id Name:
AQ3485_21306_set
读取参数 RPC
- 名称:
[AQ3485 GET] para - id Name:
aq3485_21306_get
9.2 参数定义
| App 地址 | 参数名 | field_name | 单位 | 类型 | 说明 |
|---|---|---|---|---|---|
| app_38 | pwron_delay | pwron_delay | ms | uint16le | 上电延时(传感器供电后等待稳定时间) |
| app_70 | periodUP | periodUP | s | uint32LE | 上传周期 |
| app_74 | periodRead | periodRead | s | uint32LE | 采集周期 |
| app_110 | cov_temperature | cov_temperature | ℃ | int16BE | 融霜温度 COV 变化阈值(×0.1℃) |
| app_112 | cov_humidity | cov_humidity | ℃ | int16BE | 冷藏室温度 COV 变化阈值(×0.1℃) |
| app_150 | addr | addr | — | uint8 | Modbus 从机地址(默认 1) |
9.3 RPC 代码
配置参数 RPC
javascript
import {RPCHelper, Utils} from '#tklHelper';
import {Buffer} from "buffer";
function rpc_script({device, params, alarms, logger}) {
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_temperature", field_name: "cov_temperature", unit: "℃", type: "int16BE",coefficient:0.1,decimal:1},
app_112: {name: "cov_humidity", field_name: "cov_humidity", unit: "℃", 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("set para")
let msg=RPCHelper.makeMSG({
msgType:Utils.msgType.paras,
device:device,
dnBuffer:dnBuffer,
sleepTime:0,
})
return [msg]
}读取参数 RPC
javascript
import {RPCHelper, Utils} from '#tklHelper';
function rpc_script({device, params, alarms, logger}) {
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_temperature", field_name: "cov_temperature", unit: "℃", type: "int16BE",coefficient:0.1,decimal:1},
app_112: {name: "cov_humidity", field_name: "cov_humidity", unit: "℃", 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 msg=RPCHelper.makeMSG({
msgType:Utils.msgType.paras,
device:device,
dnBuffer:frames.readBuffer,
sleepTime:0,
})
return [msg]
}10. 模板选择
在 ThinkLink 平台中搜索模板: AQ3485
或按业务类型查找: 21306 / 双通道温度传感器 / RS-485 Modbus 冷链采集
11. 补充说明
- 字段命名说明:物模型中
humidity字段实际含义为冷藏室温度,temperature字段实际含义为融霜温度,命名来自平台历史注册约定,不影响功能使用。 - 厂家默认通信参数:地址
1,波特率 9600,数据位 8,无校验,停止位 1。 - COV 阈值:
cov_temperature(app_110)对应融霜温度变化阈值,cov_humidity(app_112)对应冷藏室温度变化阈值;单位均为0.1℃,即阈值 10 = 1.0℃。 - 上电延时:
pwron_delay(app_38)为 KC21 上电后等待传感器稳定的时间,单位毫秒。