java-modbus-读取-modbus4j

前言

这是一个数据采集的项目,属于XX数据消防的一个数据采集,前面通过 modbus poll 读取过了,现在用java 代码去读取,需要注意的是这种方法封装好的,我们后来根据netty 自己去解析数据,因为其本质就是 二进制数据的解析,了解完modbus 就了解了如何处理,但是呢这个笔记我之前很早就记录了,以后估计也用不上了...

留着给用到的人做一点参考吧

工具类

java 复制代码
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
 
/**
* Modbus TCP协议读取数据
*
*/
public class ModbusReadUtil {
 
 
    /**
     * 单列工厂。
     */
    static ModbusFactory modbusFactory;
 
    static {
        if (modbusFactory == null) {
            modbusFactory = new ModbusFactory();
        }
    }
 
    /**
     * 获取master
     *
     * @param host IP地址
     * @param port 端口号
     * @return
     * @throws ModbusInitException
     */
    public static ModbusMaster getMaster(String host, int port) throws ModbusInitException {
        try {
            IpParameters params = new IpParameters();
            params.setHost(host);
            params.setPort(port);
            ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
            master.init();  //master初始化
            return master;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    /**
     * 批量读取使用寄存器数据
     *
     * @param master    ModbusMaster对象
     * @param batchRead 批量读取集合
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public static BatchResults<Integer> batchRead(ModbusMaster master, BatchRead<Integer> batchRead) throws Exception {
        try {
            batchRead.setContiguousRequests(false);
            BatchResults<Integer> results = master.send(batchRead);
            return results;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
    //测试
    public static void main(String[] args) {
        try {
            ModbusMaster master = getMaster("192.168.1.88", 2001);
            BatchRead<Integer> batch = new BatchRead<>();
            batch.addLocator(0, BaseLocator.inputRegister(1, 0, DataType.FOUR_BYTE_FLOAT));
            batch.addLocator(1, BaseLocator.inputRegister(1, 2, DataType.FOUR_BYTE_FLOAT));
            batch.addLocator(2, BaseLocator.inputRegister(1, 4, DataType.FOUR_BYTE_FLOAT));
            batch.addLocator(3, BaseLocator.inputRegister(1, 6, DataType.FOUR_BYTE_FLOAT));
            batch.addLocator(4, BaseLocator.inputRegister(1, 8, DataType.FOUR_BYTE_FLOAT));
            batch.addLocator(5, BaseLocator.inputRegister(1, 10, DataType.FOUR_BYTE_FLOAT));
            BatchResults<Integer> batchRead = batchRead(master, batch);
            System.out.println(batchRead.getValue(0));
            System.out.println(batchRead.getValue(1));
            System.out.println(batchRead.getValue(2));
            System.out.println(batchRead.getValue(3));
            System.out.println(batchRead.getValue(4));
            System.out.println(batchRead.getValue(5));
 
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

工具类

java 复制代码
package com.zhuking.datacollection.common.utils;
 
import com.serotonin.modbus4j.BatchRead;
import com.serotonin.modbus4j.BatchResults;
import com.serotonin.modbus4j.ModbusFactory;
import com.serotonin.modbus4j.ModbusMaster;
import com.serotonin.modbus4j.code.DataType;
import com.serotonin.modbus4j.exception.ErrorResponseException;
import com.serotonin.modbus4j.exception.ModbusInitException;
import com.serotonin.modbus4j.exception.ModbusTransportException;
import com.serotonin.modbus4j.ip.IpParameters;
import com.serotonin.modbus4j.locator.BaseLocator;
import com.serotonin.modbus4j.msg.WriteCoilRequest;
import com.serotonin.modbus4j.msg.WriteCoilResponse;
import com.serotonin.modbus4j.msg.WriteCoilsRequest;
import com.serotonin.modbus4j.msg.WriteCoilsResponse;
 
/**
* modbus通讯工具类,采用modbus4j实现
*
* @website https://github.com/infiniteautomation/modbus4j
*/
public class Modbus4jUtils {
    /**
     * 工厂。
     */
    static ModbusFactory modbusFactory;
 
    static {
        if (modbusFactory == null) {
            modbusFactory = new ModbusFactory();
        }
    }
 
    /**
     * 获取master
     *
     * @return
     * @throws ModbusInitException
     */
    public static ModbusMaster getMaster() {
        IpParameters params = new IpParameters();
        params.setHost("192.168.1.88"); // 指定IP
        params.setPort(2001);//  指定端口
        // modbusFactory.createRtuMaster(wapper); //RTU 协议
        // modbusFactory.createUdpMaster(params);//UDP 协议
        // modbusFactory.createAsciiMaster(wrapper);//ASCII 协议
        ModbusMaster master = modbusFactory.createTcpMaster(params, false);// TCP 协议
        try {
            master.init();
        } catch (ModbusInitException e) {
            e.printStackTrace();
        }
        return master;
    }
 
    /**
     * 读取[01 Coil Status 0x]类型 开关数据
     *
     * @param slaveId slaveId
     * @param offset  位置
     * @return 读取值
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     */
    public static Boolean readCoilStatus(int slaveId,
                                         int offset) throws ModbusTransportException, ErrorResponseException {
        // 读取 功能码 01 Coil status(0x) 数据类型
        BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId, offset);
        return getMaster().getValue(loc);
    }
 
    /**
     * 往 功能码 01 Coil status(0x) 写数据
     *
     * @param slaveId
     * @param writeOffset 位置
     * @param writeValue  值
     * @return
     * @throws ModbusTransportException
     */
    public boolean writeCoil(int slaveId, int writeOffset, boolean writeValue) throws ModbusTransportException {
        ModbusMaster tcpMaster = getMaster();
        WriteCoilRequest request = new WriteCoilRequest(slaveId, writeOffset, writeValue);
        WriteCoilResponse response = (WriteCoilResponse) tcpMaster.send(request);
        return !response.isException();
    }
 
    /**
     * 往 功能码 01 Coil status(0x) 写数据
     *
     * @param slaveId
     * @param startOffset 开始位
     * @param data        数组,从开始位逐渐的将数组数据写入 例如:开始为是 5,传递的参数为 5 那就是从 5-10 的位置会被写入数据
     * @return
     * @throws ModbusTransportException
     */
    public static boolean writeCoils(int slaveId, int startOffset, boolean[] data) throws ModbusTransportException {
        ModbusMaster tcpMaster = getMaster();
        WriteCoilsRequest request = new WriteCoilsRequest(slaveId, startOffset, data);
        WriteCoilsResponse response = (WriteCoilsResponse) tcpMaster.send(request);
        return !response.isException();
 
    }
 
    /**
     * 读取[02 Input Status 1x]类型 开关数据
     *
     * @param slaveId
     * @param offset
     * @return
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     */
    public static Boolean readInputStatus(int slaveId,
                                          int offset) throws ModbusTransportException, ErrorResponseException {
        // 02 Input Status
        BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId, offset);
        Boolean value = getMaster().getValue(loc);
        return value;
    }
 
    /**
     * 读取[03 Holding Register类型 2x]模拟量数据
     *
     * @param slaveId  slave Id
     * @param offset   位置
     * @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType
     * @return
     * @throws ModbusTransportException 异常
     * @throws ErrorResponseException   异常
     */
    public static Number readHoldingRegister(int slaveId, int offset,
                                             int dataType) throws ModbusTransportException, ErrorResponseException {
        // 03 Holding Register类型数据读取
        BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId, offset, dataType);
        Number value = getMaster().getValue(loc);
        return value;
    }
 
    /**
     * 读取[04 Input Registers 3x]类型 模拟量数据
     *
     * @param slaveId  slaveId
     * @param offset   位置
     * @param dataType 数据类型,来自com.serotonin.modbus4j.code.DataType
     * @return 返回结果
     * @throws ModbusTransportException 异常
     * @throws ErrorResponseException   异常
     */
    public static Number readInputRegisters(int slaveId, int offset,
                                            int dataType) throws ModbusTransportException, ErrorResponseException {
        // 04 Input Registers类型数据读取
        BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId, offset, dataType);
        Number value = getMaster().getValue(loc);
        return value;
    }
 
    /**
     * 批量读取使用方法
     *
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     */
    public static void batchRead() throws ModbusTransportException, ErrorResponseException {
 
        BatchRead<Integer> batch = new BatchRead<>();
        batch.addLocator(0, BaseLocator.holdingRegister(1, 1, DataType.FOUR_BYTE_FLOAT));
        batch.addLocator(1, BaseLocator.inputStatus(1, 0));
        ModbusMaster master = getMaster();
        batch.setContiguousRequests(false);
        BatchResults<Integer> results = master.send(batch);
        System.out.println(results.getValue(0));
        System.out.println(results.getValue(1));
    }
 
    public static void main(String[] args) throws ModbusTransportException, ErrorResponseException {
        // 0 代表了 寄存器的位 1和2 的值
        // 2 代表了 寄存器位 2和2 的值
        Number number = readInputRegisters(1, 0, DataType.FOUR_BYTE_FLOAT);
        System.out.println(number.doubleValue());
    }
 
 
    /**
     * 批量读取使用寄存器数据
     *
     * @param master    ModbusMaster对象
     * @param batchRead 批量读取集合
     * @throws ModbusTransportException
     * @throws ErrorResponseException
     * @throws ModbusInitException
     */
    public static BatchResults<Integer> batchRead(ModbusMaster master, BatchRead<Integer> batchRead) throws Exception {
        try {
            batchRead.setContiguousRequests(false);
            BatchResults<Integer> results = master.send(batchRead);
            return results;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
 
}
 
相关推荐
刀法如飞1 小时前
Java数组去重的20种实现方式——指导AI解决不同问题的思路
java·算法·面试
Empty-Filled1 小时前
Claude Gateway 排查教程
网络·数据库·人工智能
byoass1 小时前
企业云盘高可用架构:主备切换、负载均衡与健康检查实战
运维·网络·安全·架构·云计算·负载均衡
篮子里的玫瑰1 小时前
Python与网络爬虫——字典与集合
开发语言·python
薪火铺子1 小时前
SpringMVC请求处理流程源码解析(第1篇):请求入口与处理器映射
java·后端·spring
ch.ju1 小时前
Java程序设计(第3版)第二章——参数(实参 形参)
java
椰猫子1 小时前
SpringMVC(SpringMVC简介、请求与响应(请求映射路径、请求参数、日期类型参数传递、响应json数据))
java·前端·数据库
海兰1 小时前
【开篇】Spring AI、OpenClaw 和Hermes
java·人工智能·spring·spring ai
skilllite作者1 小时前
Zed 1.0 编辑器深度评测与实战指南
开发语言·人工智能·windows·python·编辑器·agi
2401_882273721 小时前
pattern属性在旧版Android浏览器无效怎么办_手动验证补充【操作】
jvm·数据库·python