产品功能描述:
X-SSG-A1101-RS485 十合一环境及空气质量传感器采用高速处理器, 集成 CO2、甲醛、TVOC、激光粉 尘 PM2.5 、PM10 、PM1.0 颗粒物、温度、湿度、气压、光照度及噪声检测于一体, 通过 RS485 总线 通信方式实现环境质量数据检测上报。采用旋转卡扣方式吸顶安装,操作简单。
产品技术指标
2.1 检测参数及分辨率 | |||
传感器数据 | 测量分辨率 | 测量范围 | 测量精度 |
二氧化碳 eCO2 | 1ppm | 400 ~ 60,000ppm | ±30ppm |
TVOC | 1ug/m3 | 0 ~ 60,000ug/m³ | ±50ug/m3 |
甲醛 CH2O | 1ug/m3 | 0 ~ 1,000ug/m³ | ±25% |
PM2.5 | 1ug/m3 | 0 ~ 1,000ug/m³ | ±10% |
PM10 | 1ug/m3 | 0 ~ 1,000ug/m³ | ±10% |
PM1.0 | 1ug/m3 | 0 ~ 1,000ug/m³ | ±10% |
温度 | 0.01℃ | -40 ~ 85℃ | ±0.2℃ |
湿度 | 0.01% | 0 ~ 100% | ±1%RH |
气压 | 1Pa | 30,000 ~ 110,000Pa | ±12Pa |
光照度 | 1Lux | 0 ~ 60,000Lux | ±5% |
噪声 | 1dB | 30 ~ 90dB | ±3dB |
注意:模块输出的 CH2O 值为 TVOC 的等效值,客户购买和使用时请注意。
2.2 工作电压: DC5V±0.2V @150mA
2.3 工作环境:工作温度- 10 ~ 60℃,工作湿度: 5 ~ 95%RH(无凝结)
2.4 通讯方式:Modbus-RTU 485 接口
2.5 预热时间:小于 3 分钟
半导体 VOC 传感器理论上来说通电时间越久越稳定
2.6 使用寿命: 3 年(空气中)
III.产品规格
3.1 外观尺寸图
I 、标准 4 线接口 II 、2 线 + USB 供电接口
如上图所示, 本产品⃞供“标准 4 线接口”和“2 线+USB 供电”两种物理接口,选购时请根 据实际需要注明。
本产品默认使用 5V 直流供电,如需特殊电压(6 – 36V),可联系我们定制。
3.2 接线定义
1) “标准 4 线”接口类型:
序号 | 名称 | 备注 |
RS485_A | 黄色 | RS485_A |
RS485_B | 绿色 | RS485_B |
DC+ | 红色 | 默认 5V 直流供电, 特殊电压需定制 |
GND | 黑色 | 接地线 |
2) “2 线+USB 供电”接口类型:
序号 | 名称 | ⃞述 |
A | 红色 (A) | RS485_A |
B | 黑色 (B) | RS485_B |
U | Micro USB | 直流 5V 供电 |
注意:上表中的颜色为常规说明,具体接线时请以产品上的标签为准。
IV.RS485 通讯协议
4.1 通信参数
ModBus-RTU 485 参数: 9600/8/N/1
出厂默认地址: 0x01
返回数据时间:小于 100ms
4.2 通信协议
1) 读取地址命令
方向:用户应用->传感器模块;需要应答:是
请求消息格式:
字节编号 | 数据 | 说明 |
0 | 0xFE | 广播地址 |
1 | 0x11 | 报告从机地址功能码 |
2 | 0x00 | 固定 |
3 | 0x00 | 固定 |
4 | 0x00 | 固定 |
5 | 0x01 | 固定 |
67 | CRC_LCRC_H | CRC 校验 |
响应消息格式:
字节编号 | 数据 | 说明 |
0 | 0x01 | 从机地址 |
1 | 0x11 | 报告从机地址功能码 |
2 | 0x02 | 字节数 |
3 | version | 固件版本 |
4 | address | 当前地址 |
56 | CRC_LCRC_H | CRC 校验 |
例如:发送命令: FE 11 00 00 00 01 28 06
返回数据: 01 11 02 12 01 70 5C
说明:返回数据中 0x12 表示版本号为 V1.2 ,0x01 表示设备地址为 01
2) 修改地址命令。模组出厂默认地址为 0x01,地址范围可更改为: 1~247
方向:用户应用->传感器模块;需要应答:是
请求消息格式:
字节编号 | 数据 | 说明 |
0 | address | 当前地址 |
1 | 0x06 | 功能码 |
2 | 0x00 | 固定 |
3 | 0x00 | 固定 |
4 | 0x00 | 预留 |
5 | new address | 新地址 |
67 | CRC_L CRC_H | CRC 校验 |
响应消息格式:
字节编号 | 数据 | 说明 |
0 | address | 修改前的地址 |
1 | 0x06 | 功能码 |
2 | 0x00 | 固定 |
3 | 0x00 | 固定 |
4 | 0x00 | 预留 |
5 | new address | 修改后的地址 |
67 | CRC_L CRC_H | CRC 校验 |
例如:当前地址为: 0x01 ,预设地址为: 0x02
发送命令: 01 06 00 00 00 02 08 0B
返回数据: 01 06 00 00 00 02 08 0B
当前地址再从: 0x02 ,改回: 0x01
发送命令: 02 06 00 00 00 01 48 39
返回数据: 02 06 00 00 00 01 48 39
3) 读取数据命令
方向:用户应用->传感器模块;需要应答:是
请求消息格式:
字节编号 | 数据 | 说明 |
0 | address | 当前地址 |
1 | 0x03 | 功能码 |
2 3 | 0x00 MM | 寄存器开始地址 |
4 5 | 0x00 NN | 需要读取的传感器个数 |
6 7 | CRC_L CRC_H | CRC 校验 |
应答消息格式:
字节编号 | 数据 | 说明 |
0 | address | 当前地址 |
1 | 0x03 | 功能码 |
2 | NN*2 | 数据长度 |
3 | xx xx…… | 传感器数据(气压占 4 字节, 既 2 个寄存器; 其他每个传感器数据占 2 字节, 既 1 个寄 存器) |
3+NN*2 4+NN*2 | CRC_L CRC_H | CRC 校验 |
注意:返回传感器数据可以根据寄存器地址和数据长度来改变。
寄存器地址(0x00MM)与对应的传感器数据说明如下, 气压占 4 字节(2 个寄存器),其余每个传 感器数据占 2 字节(1 个寄存器)。
寄存器地址 | 传感器数据 | 占用寄存器数量 |
0x0000 | eCO2 | 1 |
0x0001 | TVOC | 1 |
0x0002 | CH2O | 1 |
0x0003 | PM2.5 | 1 |
0x0004 | 湿度 | 1 |
0x0005 | 温度 | 1 |
0x0006 | PM10 | 1 |
0x0007 | PM1.0 | 1 |
0x0008 | 光照度(Lux) | 1 |
0x0009 | MCU 温度 | 1 |
0x000A | 噪声(dB) | 1 |
0x000B | 气压(Pa) | 2 |
说明:
① 传感器个数 00 NN 最小为 00 01,最大为 00 0B。MM 值为 00 时, NN 值最大可为 0B,此时能读 出所有传感器的值, NN 为 01 时只能单独读取 eCO2 的数据, NN 为 02 时可读取 eCO2 和 TVOC 的数
据,以此类推。
② 寄存器靠前的地址,在加大数据长度时,可读取后面传感器的数据,但寄存器靠后的地址,不 能读取在此地址前传感器的数据。
③ 一个寄存器容纳 2 个字节数据, 气压占 4 字节,既 2 个寄存器,因此,在读取气压时要把连续 两个寄存器都读出来,其他每个传感器数据占 2 字节,既 1 个寄存器。
详情如下:
00MM00NN | 可以读取到的数据 |
00000001 | 表示从起始地址 0000 读取 CO2 数据 |
00000002 | 表示从起始地址 0000 读取 CO2 ,TVOC 数据 |
…… | …… |
0000000D | 表示从起始地址 0000 读取 CO2,TVOC,CH2O,PM2.5,湿 度,温度,PM10,PM1.0,光照度,MCU 温度,噪声数据,气压 数据 |
00010001 | 表示从起始地址 0001 读取 TVOC 数据 |
00010002 | 表示从起始地址 0001 读取 TVOC,CH2O 数据 |
…… | …… |
00010007 | 表示从起始地址 0001 取 TVOC,CH2O,PM2.5,湿度,温 度,PM10,PM1.0 数据 |
0001000C | 表示从起始地址 0001 取 TVOC,CH2O,PM2.5,湿度,温 度,PM10,PM1.0,光照度,MCU 温度,噪声数据,气压数据 |
00020001 | 表示从起始地址 0002 读取 CH2O 数据 |
00020002 | 表示从起始地址 0002 读取 CH2O,PM2.5 数据 |
…… | …… |
000B0001 | 表示从起始地址 000B 读取气压数据(2 个寄存器) |
例如: 模组的地址为 0x01,
用户发送: 01 03 00 00 00 09 85 CC ,即可将 9 个传感器数据读出;
用户发送: 01 03 00 00 00 0B 04 0D ,即可将 11 个传感器数据(含 MCU 温度)读出;
用户发送: 01 03 00 00 00 0D 84 0F ,即可将 12 个传感器数据(气压占 2 个寄存器)读出;
用户发送: 01 03 00 0B 00 02 B5 C9 ,即仅读取气压数据(占 2 个寄存器)。
4) 读取一帧数据
5) 返回数据格式如下:
字节编号 | 数据 | 说明 |
0 | 0x01 | 报文头 |
1 | 0x03 | 功能码 |
2 | 0x1A | 数据长度 |
3 4 | CO2_H CO2_L | CO2 数据 |
5 6 | TVOC_H TVOC_L | TVOC 数据 |
7 8 | CH2O_H CH2O_L | CH2O 数据 |
9 10 | PM2.5_H PM2.5 L | PM2.5 数据 |
11 12 | Humi_H Humi_L | 湿度数据 |
13 14 | Temp_H Temp_L | 温度数据 |
15 16 | PM10_H PM10_L | PM10 数据 |
17 18 | PM01_H PM01_L | PM1.0 数据 |
19 20 | Lux_H Lux_L | 光照度(Lux)数据 |
21 22 | MCU_TEMP_H MCU_TEMP_L | MCU 温度数据 |
23 24 | dB_H dB_L | 噪声(dB)数据 |
25 26 27 28 | Pa_byte[3] Pa_byte[2] Pa_byte[1] Pa_byte[0] | 气压数据(Pa) |
29 30 | CRC16_L CRC16_H | CRC16 校验 |
6) 系统参数配置
7) 可以通过对下表寄存器地址的读、写,以获取或修改系统参数。
8) 注意: 此项为高级功能, 请小心使用, 以免造成系统参数错误, 影响传感器功能或数据准确性。
寄存器地址 | 长度(字节) | 系统参数 |
0x0100 | 4 | 传感器配置位图(Sensor Map) |
0x0110 | 2 | 字节 1(在前):是否为外置温湿度传感器 字节 2:传感器数据用户校准位图,参见“传感 器模块位图 ” |
0x0111 | 2 | 字节 1(在前):专用串口屏自定义指标项对应的传感器编号 字节 2:光照度传感器感光罩的透光率(0- 100), 0 表示没有感光罩, 100 表示无损耗 |
0x0118 | 2 | CO2 校准值, int16 |
0x0119 | 2 | TVOC 校准值, int16 |
0x011A | 2 | CH2O 校准值, int16 |
0x011B | 2 | PM2.5 校准值, int16 |
0x011C | 2 | 湿度校准值(100 倍), int16 |
0x011D | 2 | 温度校准值(100 倍), int16 |
0x011E | 2 | PM10 校准值, int16 |
0x011F | 2 | PM1.0 校准值, int16 |
0x0120 | 2 | 光照度(Lux)校准值, int16 |
0x0121 | 2 | MCU 温度校准值, int16 |
0x0122 | 2 | 噪声(dB)校准值, int16 |
0x0123 | 2 | 大气压校准值, int16 |
注意:
1.所有用户校准值都是有符号整数,负数表示负偏移,既要减去偏移量;
2.温/湿度用户校准值是按摄氏度放大 100 倍,如: 250 表示需要加 2.5 摄氏度; -110 表示需要 减去 1.1 摄氏度。
例如: 模组的地址为 0x01,
用户发送: 01 03 01 10 00 01 84 33 ,读出外置温湿度传感器标记和传感器数据用户校准位图; 用户发送: 01 06 01 10 00 02 04 0D ,打开温湿度用户校准开关;
用户发送: 01 03 01 1D 00 01 15 F0 ,读出温湿度校准值;
用户发送: 01 06 01 1D 00 FA 98 73 ,设置温度用户校准值 250,既+2.5 度; 用户发送: 01 06 01 1D 80 6E F8 1C ,设置温度用户校准值-110,既-1.1 度。
4.3 电脑读取 RS485 数据
通过“485 转串口”适配器,可以将传感器模组连接到电脑以检测通讯和查看数据。电脑端可以使 用 ModBus 测试工具(如: ShortBus Modbus Scanner,效果见下图)直接读取数据;也可以使用“串 口助手”等标准串口工具,通过发送查询消息获取数据。
V. 各种传感器数据计算方式
. CO2 (ppm) = CO2_H * 256 + CO2_L
. TVOC (ug/m3) = TVOC_H * 256 + TVOC_L
. CH2O (ug/m3) = CH2O_H * 256 + CH2O_L
. PM2.5 (ug/m3) = PM2.5_H * 256 + PM2.5_L
. PM10 (ug/m3) = PM10_H * 256 + PM10_L
. PM1.0 (ug/m3) = PM01_H * 256 + PM01_L
. 照度 (Lux) = Lux_H * 256 + Lux_L
. 噪声 (dB) = dB_H * 256 + dB_L
. 接口返回的温、湿度(真实数据的 100 倍):
. 正温度 (℃) = (Temperature_H * 256 + Temperature_L) / 100, 例如: T = (0x09d0) / 10 = 2512 / 100 = 25.12℃
. 负温度 (℃)
方法 1:直接转为有符号的 int 类型即可,例如: T = 0xfc83/10 = -893/100 = -8.93℃
方法 2:如果大于 0x7fff(32767)
则为负数 T = (0xfc83 – 65536) / 10 = (64643 – 65536) / 10 = -893 / 100 = -8.93℃
. 湿度 (%RH) = (Humidity_H * 256 + Humidity_L) / 100
. 气压 (Pa) = Pa_byte[3] * 224 + Pa_byte[2] * 216 + Pa_byte[1] * 28 + Pa_byte[0]
. 根据气压计算海拔高度
气压单位是 Pa,理论上,海拔每上升 9 米,大气压降低 100 Pa。而海平面标准大气压为 101,325 Pa, 因此,可以用下面的公式根据气压值(Pa)计算海拔高度(Altitude)的近似值:
1 、 简化版海拔高度公式 = (101325 – Pa) / 100 * 9
除了海拔高度, 影响气压的因素还有很多(例如温度),下面的公式相对更精确一些, 特别是在高海 拔位置:
2 、 校准版海拔高度公式 = 44330 * (1 – (Pa/101325)0.1903)
例如:如果测得的气压值为 99,882Pa,则两个公式计算得到的海拔高度(Altitude)分别为:
. 简化版海拔高度 = (101325 – 99882) / 100 * 9 = 129.8 米
. 校准版海拔高度 = 44330 * (1 – (99882/101325)0.1903) = 120.84 米
VI.注意事项
. 初次上电使用需预热 3 分钟以上
. 传感器安装位置应高于地面 15~20CM 以上, 否则可能有地面沙尘, 飘絮物等大尘埃颗粒甚至絮 状物污染导致风扇缠绕阻转,建议使用设备采取适当的预过滤处理。
. 本产品为精密仪器, 请不要打开外壳, 正常操作无需了解设备内部情况。如设备有损坏, 必须 由专业人员检修和维修,在检修和维修之前请确认外部连接电源已切断。。
. 传感器数据确保出厂个体之间的一致性, 不以第三方检测仪器或数据作为对比标准。如用户希 望最终测量结果和某第三方检测设备一致,可由用户根据实际采集结果进行数据拟合校准。
. 本传感器适用于普通室内环境,如用户设备在以下实际环境中使用,传感器有可能因过度积 尘、积油、进水导致数据一致性下降。例如:全年尘埃浓度大于 300 微克/立方米时间超过 50% ,或大于 500 微克/立方米时间超过 20%;油烟环境;高水雾环境;户外等。
VII. 传感器模块位图
位 | 传感器模块 |
0x01 | 光照度 |
0x02 | 温湿度气压 |
0x04 | 粉尘 |
0x08 | 空气质量 |
0x10 | 噪声 |
VIII. CRC 校验计算方法
CRC 代码和示例可参考: https://github.com/sunbaoshi1975/CRCTool
函数功能: CRC 校验函数,生成 CRC
参数说明:pushMsg:需要校验的数组集
usDataLen :需要校验数据的长度
返回参数: CRC 为 unsigned int16 类型,高位字节为高位在前、低位在后
/*CRC verify high position*/
const unsigned char auchCRCHi[] = {
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01,
0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81,
0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01,
0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40 };
/* CRC verify low position*/
const unsigned char auchCRCLo[] = {
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06, 0x07, 0xC7, 0x05, 0xC5, 0xC4,
0x04, 0xCC, 0x0C, 0x0D, 0xCD, 0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A, 0x1E, 0xDE, 0xDF, 0x1F, 0xDD,
0x1D, 0x1C, 0xDC, 0x14, 0xD4, 0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3, 0xF2, 0x32, 0x36, 0xF6, 0xF7,
0x37, 0xF5, 0x35, 0x34, 0xF4, 0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29, 0xEB, 0x2B, 0x2A, 0xEA, 0xEE,
0x2E, 0x2F, 0xEF, 0x2D, 0xED, 0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60, 0x61, 0xA1, 0x63, 0xA3, 0xA2,
0x62, 0x66, 0xA6, 0xA7, 0x67, 0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68, 0x78, 0xB8, 0xB9, 0x79, 0xBB,
0x7B, 0x7A, 0xBA, 0xBE, 0x7E, 0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71, 0x70, 0xB0, 0x50, 0x90, 0x91,
0x51, 0x93, 0x53, 0x52, 0x92, 0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B, 0x99, 0x59, 0x58, 0x98, 0x88,
0x48, 0x49, 0x89, 0x4B, 0x8B, 0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42, 0x43, 0x83, 0x41, 0x81, 0x80, 0x40 };
/*CRC check*/
uint16_t CRC16_Check(const uint8_t *pushMsg, uint8_t usDataLen)
{
uint8_t uchCRCHi = 0xff;//high CRC init
uint8_t uchCRCLo = 0xff;//low CRC init
uint8_t uIndex; //CRC index in loop
while(usDataLen--) {
uIndex = uchCRCLo^ *pushMsg++;//cal CRC
uchCRCLo = uchCRCHi^ auchCRCHi[uIndex];
uchCRCHi = auchCRCLo[uIndex];
}
return((uint16_t)uchCRCHi << 8 | uchCRCLo);
}