java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议

工具包引入

<dependency>
  <groupId>cn.allbs</groupId>
  <artifactId>allbs-model</artifactId>
  <version>0.8.1</version>
</dependency>

源码下载

https://github.com/chenqi92/allbs-model

解析&生成过程中自定义参数说明

应用场景 参数值 参数说明
指令生成 GeneratorEnum.ADDRESS.name 从站地址
指令生成 GeneratorEnum.FUNCTION.name 功能码
指令生成 GeneratorEnum.START_ADDRESS.name 起始寄存器地址
指令生成 GeneratorEnum.READ_ADDRESS.name 读寄存器地址
协议解析 data 数据信息
协议解析 circuit 回路
协议解析 point 点数
协议解析 gas_type 点位属性
协议解析 pre_gas_type 点位属性原始值
协议解析 gas_unit 气体单位
协议解析 pre_gas_unit 气体单位原始值
协议解析 gas_num 气体监测值
协议解析 detector_status 探测器状态
协议解析 pre_detector_status 探测器状态原始值
协议解析 detector_num 探测器浓度值
协议解析 extra_power 外控电源状态
协议解析 pre_extra_power 外控电源状态原始值
协议解析 address 地址
协议解析 function 功能
协议解析 controller_status 控制器状态
协议解析 pre_controller_status 控制器状态原始值

生成示例

代码

Map<String, Object> map = new HashMap<>(4);
// 地址
map.put(ADDRESS.getName(), 1);
// 功能码
map.put(FUNCTION.getName(), 3);
// 起始寄存器地址
map.put(START_ADDRESS.getName(), 0);
// 读寄存器数量
map.put(READ_ADDRESS.getName(), 2);
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
byte[] bytes = sfjk200Mapper.writeDataAsByteArray(map);

结果

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310143214803

解析示例

读取 SFJK-200 控制器配置点数( 未配置点数时,返回回路 x 的值为 0x00 )所有请求数据 及响应数据均以 16 进制数据进行交换

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230309162532082
byte[] bytes = new byte[9];
bytes[0] = 0x01;
bytes[1] = 0x03;
bytes[2] = 0x04;
bytes[3] = 0x3F;
bytes[4] = 0x00;
bytes[5] = 0x00;
bytes[6] = 0x00;
bytes[7] = (byte0xf6;
bytes[8] = 0x27;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
System.out.println(sfjk200Mapper.readValue(bytes, 0x0000, Map.class));
java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230309162610293

读取探测器属性及单位 ( 读取 1 回路 1 号点探测的浓度及属性,根据寄存器地址映射表查 到,1 号探测器对应寄存器地址为 0002H )数据高字节代表单位,低字节代表属性。

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230309162641484
byte[] bytes = new byte[9];
bytes[0] = 0x01;
bytes[1] = 0x03;
bytes[2] = 0x02;
bytes[3] = 0x01;
bytes[4] = 0x0A;
bytes[5] = (byte0x39;
bytes[6] = (byte0xD3;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
System.out.println(sfjk200Mapper.readValue(bytes, 0x0002, Map.class));
java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230309164119135

连续读取 1 回路 3、4、5、6 号探测器属性及单位。(根据寄存器地址映射表查到 3 号探测 器从 0004H 地址开始 )

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310094326283
byte[] bytes = new byte[13];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;
bytes[2] = (byte0x08;
bytes[3] = (byte0x01;
bytes[4] = (byte0x0A;
bytes[5] = (byte0x01;
bytes[6] = (byte0x0D;
bytes[7] = (byte0x00;
bytes[8] = (byte0x81;

bytes[9] = (byte0x02;
bytes[10] = (byte0x82;
bytes[11] = (byte0x03;
bytes[12] = (byte0x22;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x0004, Map.class);
map.forEach((k, v) -> {
    if (k.equals("data")) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});
java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310100156371

读取 1 回路 1 号探测器的低限报警值( 假设 1 号探测器属性为甲烷,单位为%LEL.根据寄存 器地址映射表查到,1 号探测器对应寄存器地址为 03E2H)

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310100226131
byte[] bytes = new byte[7];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;

bytes[2] = (byte0x02;
bytes[3] = (byte0x00;
bytes[4] = (byte0xFA;
bytes[5] = (byte0x38;
bytes[6] = (byte0x07;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x03E2, Map.class);
map.forEach((k, v) -> {
    if (k.equals("data")) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});

** 注意:当前数据为全部除以10后的数据,因为解析和指令是分开的,所以需要根据指定中指定气体单位判断返回结果需不需要乘以10 **

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310100553993

读取 1 回路 3、4、5、6 号探测器的低限报警值(3 号点属性为天然气,单位为%LEL .4 号 点为甲烷,单位为%LEL .5 号点属性为一氧化碳,单位为 μmol/mol,6 号点为氧气,单位为%V/V) 根据寄存器地址映射表查到,3 号探测器对应寄存器地址为 03E4H

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310100818315
byte[] bytes = new byte[13];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;
bytes[2] = (byte0x08;

bytes[3] = (byte0x00;
bytes[4] = (byte0x64;
bytes[5] = (byte0x00;
bytes[6] = (byte0x96;
bytes[7] = (byte0x00;
bytes[8] = (byte0x78;

bytes[9] = (byte0x00;
bytes[10] = (byte0xBD;
bytes[11] = (byte0xB8;
bytes[12] = (byte0x64;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x03E4, Map.class);
map.forEach((k, v) -> {
    if (k.equals("data")) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});

** 注意:当前数据为全部除以10后的数据,因为解析和指令是分开的,所以需要根据指定中指定气体单位判断返回结果需不需要乘以10 **

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310102142906

读取单个探测器状态(状态参考探测器状态定义)根据寄存器地址映射表查到,1 号探测器 对应寄存器地址为 07C2H

示例

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310102213104

代码

byte[] bytes = new byte[7];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;
bytes[2] = (byte0x02;

bytes[3] = (byte0x00;
bytes[4] = (byte0x01;
bytes[5] = (byte0x79;
bytes[6] = (byte0x8E;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x07C2, Map.class);
map.forEach((k, v) -> {
if (k.equals("data")) {
    List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});

输出

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310103101955

** 示例CRC存在问题 **

读取 1 回路 3、4、5、6 号探测器的状态(根据寄存器地址映射表查到,3 号探测器对应寄 存器地址为 07C4H)

示例

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310103158191

代码

byte[] bytes = new byte[13];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;
bytes[2] = (byte0x08;

bytes[3] = (byte0x00;
bytes[4] = (byte0x01;
bytes[5] = (byte0x00;
bytes[6] = (byte0x03;

bytes[7] = (byte0x00;
bytes[8] = (byte0x04;
bytes[9] = (byte0x00;
bytes[10] = (byte0x08;
bytes[11] = (byte0x81;
bytes[12] = (byte0x10;
SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x07C4, Map.class);
map.forEach((k, v) -> {
    if (k.equals("data")) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});

输出

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310103618530

读取 1 回路 1 号点探测器的当前浓度值(根据寄存器地址映射表查到,1 号探测器对应寄存 器地址为 0BA2H )

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310103646541
byte[] bytes = new byte[7];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;
bytes[2] = (byte0x02;

bytes[3] = (byte0x01;
bytes[4] = (byte0x5A;
bytes[5] = (byte0x39;
bytes[6] = (byte0xEF;

SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x0BA2, Map.class);
map.forEach((k, v) -> {
    if (k.equals("data")) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});

** 注意:当前数据为全部除以10后的数据,因为解析和指令是分开的,所以需要根据指定中指定气体单位判断返回结果需不需要乘以10 **

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310103831090

读取 1 回路 3、4、5、6 号探测器的低限报警值(3 号点属性为天然气,单位为%LEL .4 号 点为甲烷,单位为%LEL .5 号点属性为一氧化碳,单位为 μmol/mol,6 号点为氧气,单位为%V/V) 根据寄存器地址映射表查到,3 号探测器对应寄存器地址为 0BA4H

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310103906086
java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310103915347
byte[] bytes = new byte[13];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;
bytes[2] = (byte0x08;

bytes[3] = (byte0x00;
bytes[4] = (byte0x64;
bytes[5] = (byte0x00;
bytes[6] = (byte0x96;

bytes[7] = (byte0x01;
bytes[8] = (byte0x40;
bytes[9] = (byte0x00;
bytes[10] = (byte0xD1;
bytes[11] = (byte0x38;
bytes[12] = (byte0x78;

SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x03E4, Map.class);
map.forEach((k, v) -> {
    if (k.equals("data")) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});
java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310104125705

读取 SFJK-200 外控电源状态( 外控电源状态请参考外控电压状态定义表 ) 1 回路外控电源 对应寄存器地址为 0f82H )

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310104144513
byte[] bytes = new byte[9];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;
bytes[2] = (byte0x04;

bytes[3] = (byte0x30;
bytes[4] = (byte0x30;
bytes[5] = (byte0x30;
bytes[6] = (byte0x30;

bytes[7] = (byte0xE1;
bytes[8] = (byte0x28;

SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x0F82, Map.class);
map.forEach((k, v) -> {
    if (k.equals("data")) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});
java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310104319682

读取 SFJK-200 控制器状态(SFJK-200 控制器状态参考控制器状态定义表 ) 根据寄存器地 址映射表查到,对应寄存器地址为 0F8AH

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310104331648
byte[] bytes = new byte[7];
bytes[0] = (byte0x01;
bytes[1] = (byte0x03;
bytes[2] = (byte0x02;

bytes[3] = (byte0x00;
bytes[4] = (byte0x01;
bytes[5] = (byte0x79;
bytes[6] = (byte0x8E;

SFJK200Mapper sfjk200Mapper = new SFJK200Mapper();
Map<String, Object> map = sfjk200Mapper.readValue(bytes, 0x0F8A, Map.class);
map.forEach((k, v) -> {
    if (k.equals("data")) {
        List<Map<String, Object>> list = (List<Map<String, Object>>) v;
        list.forEach(System.out::println);
    } else {
        System.out.println(k + ":" + v);
    }
});
java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230310104459414

** 示例中的CRC校验错误 **

模拟读写

使用工具modbus slave工具

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230314161609552

保存至influxdb结果

java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议
image-20230315102432432

下载modbus slave测试内容

http://gofile.me/5lHRJ/EDKdtMoBt http://gofile.me/5lHRJ/9G7nQvaup http://gofile.me/5lHRJ/R5Q3Qrfs3 http://gofile.me/5lHRJ/Vcgy8UA1B http://gofile.me/5lHRJ/Q2Siba4uL http://gofile.me/5lHRJ/u20bhudBe http://gofile.me/5lHRJ/ennnRl3zh

最后是使用的java开发的示例demo

github,https://github.com/chenqi92/sfjk-200


原文始发于微信公众号(询于刍荛):java解析SFJK-200 可燃气体控制器 MODBUS 通讯协议

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/280932.html

(0)
Java朝阳的头像Java朝阳

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!