当前位置: 首页 > 工具软件 > slave4j > 使用案例 >

Java用Modbus4J进行Modbus协议通信学习,利用Modbus Slave和Modbus Poll模拟器

孟和怡
2023-12-01

Modbus协议比较简单,如果熟悉i/o操作的能很快上手。
基本点:

  • 字节、字、位基本单位换算
  • 大端小端差异
  • 异步事件模型

直接上代码:


```java
package com.bool.test;

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;

public class ModbusTest {
    static ModbusFactory modbusFactory;
    static {
        if(modbusFactory == null) {
            modbusFactory = new ModbusFactory();
        }
    }

    /**
     * 获取master
     * @return
     * @throws ModbusInitException
     */
    public static ModbusMaster getMaster() throws ModbusInitException {
        IpParameters parameters = new IpParameters();
        parameters.setHost("127.0.0.1");
        parameters.setPort(502);
        ModbusMaster master = modbusFactory.createTcpMaster(parameters,false);
        master.init();
        return master;
    }

    /**
     * 01 读取线圈状态 0x
     * @param slaveId
     * @param offset
     * @return
     * @throws ModbusInitException
     * @throws ErrorResponseException
     * @throws ModbusTransportException
     */
    public static Boolean readCoilStatus(int slaveId,int offset) throws ModbusInitException, ErrorResponseException, ModbusTransportException {
        BaseLocator<Boolean> loc = BaseLocator.coilStatus(slaveId,offset);
        return getMaster().getValue(loc);
    }

    /**
     * 02 读离散输入状态 1x
     * @param slaveId
     * @param offset
     * @return
     * @throws ModbusInitException
     * @throws ErrorResponseException
     * @throws ModbusTransportException
     */
    public static Boolean readInputStatus(int slaveId,int offset) throws ModbusInitException, ErrorResponseException, ModbusTransportException {
        BaseLocator<Boolean> loc = BaseLocator.inputStatus(slaveId,offset);
        return getMaster().getValue(loc);
    }

    /**
     * 03 读保持寄存器 4x
     * @param slaveId
     * @param offset
     * @param dataType
     * @return
     * @throws ModbusInitException
     * @throws ErrorResponseException
     * @throws ModbusTransportException
     */
    public static Number readHoldingRegister(int slaveId,int offset,int dataType) throws ModbusInitException, ErrorResponseException, ModbusTransportException {
        BaseLocator<Number> loc = BaseLocator.holdingRegister(slaveId,offset,dataType);
        return getMaster().getValue(loc);
    }

    /**
     * 04 读输入寄存器
     * @param slaveId
     * @param offset
     * @param dataType
     * @return
     * @throws ModbusInitException
     * @throws ErrorResponseException
     * @throws ModbusTransportException
     */
    public static Number readInputRegister(int slaveId,int offset,int dataType) throws ModbusInitException, ErrorResponseException, ModbusTransportException {
        BaseLocator<Number> loc = BaseLocator.inputRegister(slaveId,offset,dataType);
        return getMaster().getValue(loc);
    }

    /**
     * 批量读取数据的方法
     * @throws ModbusInitException
     * @throws ErrorResponseException
     * @throws ModbusTransportException
     */
    public static void batchRead() throws ModbusInitException, ErrorResponseException, ModbusTransportException {
        BatchRead<Integer> batchRead = new BatchRead<Integer>();
        batchRead.addLocator(0,BaseLocator.holdingRegister(1,1, DataType.FOUR_BYTE_FLOAT));
        batchRead.addLocator(1,BaseLocator.inputStatus(1,0));
        ModbusMaster master = getMaster();
        batchRead.setContiguousRequests(false);
        BatchResults<Integer> results = master.send(batchRead);
        System.out.println(results.getValue(0));
        System.out.println(results.getValue(1));
    }

    public static void main(String[] args){
        try{
//            Boolean v011 = readCoilStatus(1,0);
//            Boolean v012 = readCoilStatus(1,1);
//            Boolean v013 = readCoilStatus(1,6);
//            System.out.println(v011);
//            System.out.println(v012);
//            System.out.println(v013);

            Number number = readHoldingRegister(1, 0, DataType.FOUR_BYTE_FLOAT);
            System.out.println(number);

        }catch (Exception e){
            e.printStackTrace();
        }

    }
}

常见的四个功能码:
0x01:读线圈
0x02:读离散量输入
0x03:读保持寄存器
0x04:读输入寄存器

在编写过程中可以用Modbus Slave来模拟服务器,Modbus poll模拟设备。

 类似资料: