Java中实现modbustcp的接收

此处讲一讲modbustcp在Java中的实现。

modbustcp的格式内容

Modbus由MODICON公司于1979年开发,是一种工业现场总线协议标准。1996年施耐德公司推出基于以太网TCP/IP的Modbus协议:ModbusTCP

modbustcp 主要是用于工业上的通讯,像是作者现在和PLC进行连接就是使用modbustcp协议。

modbustcp协议格式内容分为两个部分,其一是MBAP,其二是PDU

MBAP是表示modbustcp协议中的报文头部分,长度为7个字节

事务处理标识 协议表示 长度 单元标识符
2个字节 2个字节 2个字节 1个字节
名称 解释
事务处理标识 是本次通讯中在发送通讯的第几次,一般按照每发送一次后+1
协议表示 默认00 00 是表示此次通讯是modbustcp协议
长度 表示此次PDU中携带数据长度
单元标识符 表示此次协议发送的端口中设备所处的地址

PDU是表示modbustcp协议中的数据内容,主要由功能码和数据组成

其中功能吗所占用的字节为1,表示此次的所要实现的操作,数据长度根据MBAP中的长度数值来判断。

功能码中主要是对四类操作对象进行操作(此处可以理解为Java中的对象)

对象 含义
线圈 PLC的输出位,开关量,在Modbus中可读可写
离散量 PLC的输入位,开关量,在Modbus中只读
输入寄存器 PLC中只能从模拟量输入端改变的寄存器,在Modbus中只读
保持寄存器 PLC中用于输出模拟量信号的寄存器,在Modbus中可读可写

功能码就是展示此次通讯的操作,具体功能码的识别在下方展示

代码 中文名称 英文名 位操作/字操作 操作数量
01 读线圈状态 READ COIL STATUS 位操作 单个或多个
02 读离散输入状态 READ INPUT STATUS 位操作 单个或多个
03 读保持寄存器 READ HOLDING REGISTER 字操作 单个或多个
04 读输入寄存器 READ INPUT REGISTER 字操作 单个或多个
05 写线圈状态 WRITE SINGLE COIL 位操作 单个
06 写单个保持寄存器 WRITE SINGLE REGISTER 字操作 单个
15 写多个线圈 WRITE MULTIPLE COIL 位操作 多个
16 写多个保持寄存器 WRITE MULTIPLE REGISTER 字操作 多个

Java中的实现

此次实现采用的modbus4j的jar包进行调用的,以下是modbustcp的pom引入

<dependency>
    <groupId>com.infiniteautomation</groupId>
    <artifactId>modbus4j</artifactId>
    <version>3.0.3</version>
</dependency>

由于本人引入的时候,出现无法引入的情况,可以推荐大家直接去github上下载modbus4j

GitHub - MangoAutomation/modbus4j: A high-performance and ease-of-use implementation of the Modbus protocol written in Java. Supports ASCII, RTU, TCP, and UDP transports as slave or master, automatic request partitioning and response data type parsing.icon-default.png?t=N3I4https://github.com/MangoAutomation/modbus4j下面是在java中创建modbustcp从机

public class SlaverTest {
    public static void main(String[] args) {
        //创建modbus工厂类
        ModbusFactory modbusFactory = new ModbusFactory();
        //创建TCP服务端
        // final ModbusSlaveSet salve = modbusFactory.createTcpSlave(false);
        final ModbusSlaveSet salve = new TcpSlave(502, false);
        Register register =new Register();
        //向502端口添加从机并且赋予不同的地址
        salve.addProcessImage(register.getModscanProcessImage(5));
        salve.addProcessImage(register.getModscanProcessImage(4));
        salve.addProcessImage(register.getModscanProcessImage(3));
        salve.addProcessImage(register.getModscanProcessImage(2));
        salve.addProcessImage(register.getModscanProcessImage(1));

        try {
            salve.start();
            System.out.println("salve.start();");

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

    }
}

 初始化从机中的四个对象,一般来讲在通讯中可读写开关量是10000到19999,只读开关量是20000到29999,只读寄存器是30000到39999,保持寄存器是40000到49999,工业上的定义是这样子的,但是在modbustcp中的实现已经提前确定了每个对象的位置,所以创建的时候是从0开始创建的,否则就会出现非法地址值的错误,这是本人亲自体会过的。

public class Register {
    public  BasicProcessImage getModscanProcessImage(int slaveId){
        /**
         * 初始化从机
         */
        BasicProcessImage processImage =new BasicProcessImage(slaveId);
        //processImage.setInvalidAddressValue(Short.MIN_VALUE);

        for (int i=0;i<47999;i++){
            //创建可读写开关量
            //processImage.setCoil(i,true);
            //创建只读开关量
            //processImage.setInput(i,true);
            //创建保持寄存器
            processImage.setHoldingRegister(i,(short) 0);
            //创建只读寄存器
            //processImage.setInputRegister(i,(short) 1);

        }
        processImage.addListener(new BasicProcessImageListener());

        return processImage;
    }
}

关于地址值变化的监听器,由于modbustcp中只有可读写开关量和保持寄存器中存在了关于写的变化,所以modbus4j自己只有两个监听器监听写的变化。

public class BasicProcessImageListener implements ProcessImageListener {
    @Override
    public void coilWrite(int address, boolean oldvalue, boolean newValue) {
        System.out.println("Coil at "+address+" chang:"+oldvalue+" to"+newValue);
    }

    @Override
    public void holdingRegisterWrite(int address, short oldvalue, short newValue) {
        System.out.println("HoldingRegister at "+address+" chang:"+oldvalue+" to"+newValue);
    }
}

modbustcp主机的实现

public class MasterTest {
    public static void main(String[] args) throws Exception {
       
        IpParameters parameters=new IpParameters();
        parameters.setHost("127.0.0.1");
        parameters.setPort(502);
        parameters.setEncapsulated(false);

        ModbusFactory modbusFactory =new ModbusFactory();
        ModbusMaster master =modbusFactory.createTcpMaster(parameters,true);
        //master.setTimeout(5000);
        try {
            master.init();
            int slaveId =5;

            //    writeRegistersTest(master, slaveId, 400, new short[]{0, 1, 0, 100, 10000, (short) 65535});
            //    writeCoilsTest(master,slaveId,200,new boolean[]{true,true,false,false});
            //writeCoilTest(master,slaveId,250,true);
            //Random random=new Random();
            //writeRegistersTest(master,1,42000,new short[] {(short) 1,(short) 0,(short) 1000,(short) 1,(short) 1,(short) 1});
            //writeRegistersTest(master,slaveId,42000,new short[] {(short) 1,(short) 0});


            //writeMaskRegisterTest(master,slaveId,1,0xf2,0xa5);
            //readCoilTest(master,slaveId,41000,20);
            //readDiscreteInputTest(master,slaveId,40200,7);
            //readExceptionStatusTest(master,slaveId);
            readHoldingRegistersTest(master, 1, 1000, 2);
            //readInputRegistersTest(master,slaveId,40300,10);
            //readCoilStatus(master,slaveId,40000,1);
        }finally {
            master.destroy();
        }

    }
    public static void readCoilStatus(ModbusMaster master,int slaveId, int offset, int numberOfBits)
            throws ModbusTransportException {

        ReadCoilsRequest request = new ReadCoilsRequest(slaveId, offset, numberOfBits);
        ReadCoilsResponse response = (ReadCoilsResponse) master.send(request);
        boolean[] booleans = response.getBooleanData();
        boolean[] valueRegroup = valueRegroup(numberOfBits, booleans);
        System.out.println(Arrays.toString(valueRegroup));
    }
    public static void readCoilTest(ModbusMaster master, int slaveId, int start, int len) {
        try {
            ReadCoilsRequest request = new ReadCoilsRequest(slaveId, start, len);
            ReadCoilsResponse response = (ReadCoilsResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getBooleanData()));
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void readDiscreteInputTest(ModbusMaster master, int slaveId, int start, int len) {
        try {
            ReadDiscreteInputsRequest request = new ReadDiscreteInputsRequest(slaveId, start, len);
            ReadDiscreteInputsResponse response = (ReadDiscreteInputsResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getBooleanData()));
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void readHoldingRegistersTest(ModbusMaster master, int slaveId, int start, int len) {
        try {
            ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest(slaveId, start, len);
            ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getShortData()));
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void readInputRegistersTest(ModbusMaster master, int slaveId, int start, int len) {
        try {
            ReadInputRegistersRequest request = new ReadInputRegistersRequest(slaveId, start, len);
            ReadInputRegistersResponse response = (ReadInputRegistersResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getShortData()));
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void writeCoilTest(ModbusMaster master, int slaveId, int offset, boolean value) {
        try {
            WriteCoilRequest request = new WriteCoilRequest(slaveId, offset, value);
            WriteCoilResponse response = (WriteCoilResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println("Success");
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void writeRegisterTest(ModbusMaster master, int slaveId, int address, int value) {
        try {
            WriteRegisterRequest request = new WriteRegisterRequest(slaveId, address, value);
            WriteRegisterResponse response = (WriteRegisterResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println("Success");
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void readExceptionStatusTest(ModbusMaster master, int slaveId) {
        try {
            ReadExceptionStatusRequest request = new ReadExceptionStatusRequest(slaveId);
            ReadExceptionStatusResponse response = (ReadExceptionStatusResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(response.getExceptionStatus());
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void reportSlaveIdTest(ModbusMaster master, int slaveId) {
        try {
            ReportSlaveIdRequest request = new ReportSlaveIdRequest(slaveId);
            ReportSlaveIdResponse response = (ReportSlaveIdResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println(Arrays.toString(response.getData()));
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void writeCoilsTest(ModbusMaster master, int slaveId, int start, boolean[] values) {
        try {
            WriteCoilsRequest request = new WriteCoilsRequest(slaveId, start, values);
            WriteCoilsResponse response = (WriteCoilsResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println("Success");
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void writeRegistersTest(ModbusMaster master, int slaveId, int start, short[] values) {
        try {
            WriteRegistersRequest request = new WriteRegistersRequest(slaveId, start, values);
            WriteRegistersResponse response = (WriteRegistersResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println("Success");
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }

    public static void writeMaskRegisterTest(ModbusMaster master, int slaveId, int offset, int and, int or) {
        try {
            WriteMaskRegisterRequest request = new WriteMaskRegisterRequest(slaveId, offset, and, or);
            WriteMaskRegisterResponse response = (WriteMaskRegisterResponse) master.send(request);

            if (response.isException())
                System.out.println("Exception response: message=" + response.getExceptionMessage());
            else
                System.out.println("Success");
        }
        catch (ModbusTransportException e) {
            e.printStackTrace();
        }
    }
    private static boolean[] valueRegroup(int numberOfBits, boolean[] values) {
        boolean[] bs = new boolean[numberOfBits];
        int temp = 1;
        for (boolean b : values) {
            bs[temp - 1] = b;
            temp++;
            if (temp > numberOfBits)
                break;
        }
        return bs;
    }


}

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
THE END
分享
二维码

)">
< <上一篇
下一篇>>