最近搜索

springboot整合modbus协议实现数据读取 plc PLC 单片机

浏览:1378
管理员 2022-10-29 03:28
```xml
<dependency>
            <groupId>com.intelligt.modbus</groupId>
            <artifactId>jlibmodbus</artifactId>
            <version>1.2.9.7</version>
        </dependency>
        <dependency>
            <groupId>com.digitalpetri.modbus</groupId>
            <artifactId>modbus-master-tcp</artifactId>
            <version>1.1.0</version>
        </dependency>
        <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.4.3</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>



public class ModbusMasterUtils {

    //获取连接
    public static ModbusMaster getModbusMaster(String ip,Integer port)  {
        try {
            TcpParameters tcpParameters = new TcpParameters();
            //ip
            InetAddress adress = InetAddress.getByName(ip);
            tcpParameters.setHost(adress);
            // TCP设置长连接
            tcpParameters.setKeepAlive(true);
            // TCP设置端口,这里设置是默认端口502
            tcpParameters.setPort(port);

            ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
            Modbus.setAutoIncrementTransactionId(true);
            return master;
        }catch (Exception e){
            e.printStackTrace();
        }

        return null;

    }

    /**
     * 读04
     * @param master 配置的mater主机
     * @param slaveId 从机id
     * @param offset 寄存器读取开始地址  0059的话则为58
     * @param quantity 读取的寄存器数量
     * @return float类型的值
     */
    public static List<Float> readInputRegisters(ModbusMaster master,int slaveId,int offset,int quantity){
        List<Float> floatList=new ArrayList<>();
        try {

            if (!master.isConnected()) {
                master.connect();// 开启连接
            }

            // 读取对应从机的数据,readInputRegisters读取的写寄存器,功能码04
            int[] registerValues = master.readInputRegisters(slaveId, offset, quantity);

            floatList = ByteArrayConveter.getFloatArray(registerValues);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return floatList;
    }

    /**
     * 读03
     * @param master 配置的mater主机
     * @param slaveId 从机id
     * @param offset 寄存器读取开始地址  0059的话则为58
     * @param quantity 读取的寄存器数量
     * @return float类型的值
     */
    public static List<Float> readHoldingRegisters(ModbusMaster master,int slaveId,int offset,int quantity){
        List<Float> floatList=new ArrayList<>();
        try {

            if (!master.isConnected()) {
                master.connect();// 开启连接
            }

            // 读取对应从机的数据,readInputRegisters读取的写寄存器,功能码04
            int[] registerValues = master.readHoldingRegisters(slaveId, offset, quantity);

            floatList = ByteArrayConveter.getFloatArray(registerValues);
        }catch (Exception e) {
            e.printStackTrace();
        }
        return floatList;
    }

    public static void close(ModbusMaster master){
        try {
            master.disconnect();

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




三、总结

目前只之前读03 04类型 测试需要的仿真软件是上网找的ModSim32




这个是能读的,在真实环境

image.png

image.png


package com.java.util;

import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;

import java.net.InetAddress;

public class MasterTCP {
    static public void main(String[] args) {
        try {
            TcpParameters tcpParameters = new TcpParameters();
            //tcp parameters have already set by default as in example
            //设置TCP的ip地址
            tcpParameters.setHost(InetAddress.getByName("192.168.1.88"));
            //设置TCP长连接
            tcpParameters.setKeepAlive(true);
            //设置端口,这里设置是默认端口502
            tcpParameters.setPort(Modbus.TCP_PORT);

            //创建一个主机
            ModbusMaster m = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
            Modbus.setAutoIncrementTransactionId(true);
            //从机地址
            int slaveId = 1;
            //寄存器读取的开始地址
            int offset = 200;
            //读取的寄存器数量
            int quantity = 1;

            try {
                // since 1.2.8,建立连接
                if (!m.isConnected()) {
                    m.connect();
                }
                // at next string we receive ten registers from a slave with id of 1 at offset of 0.
                //读取对应的从机的数据,readHoldingRegisters读取的保持寄存器,功能码03
                int[] registerValues = m.readHoldingRegisters(slaveId, offset, quantity);
                //遍历后控制台输出
                for (int value : registerValues) {
                    System.out.println("Address输出: " + offset++ + ", Value: " + value);
                }

            } catch (ModbusProtocolException e) {
                e.printStackTrace();
            } catch (ModbusNumberException e) {
                e.printStackTrace();
            } catch (ModbusIOException e) {
                e.printStackTrace();
            } finally {
                try {
                    m.disconnect();
                } catch (ModbusIOException e) {
                    e.printStackTrace();
                }
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}




这个能写真实环境


package com.java.util;

import com.digitalpetri.modbus.FunctionCode;
import com.digitalpetri.modbus.master.ModbusTcpMaster;
import com.digitalpetri.modbus.master.ModbusTcpMasterConfig;
import com.intelligt.modbus.jlibmodbus.Modbus;
import com.intelligt.modbus.jlibmodbus.exception.ModbusIOException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusNumberException;
import com.intelligt.modbus.jlibmodbus.exception.ModbusProtocolException;
import com.intelligt.modbus.jlibmodbus.master.ModbusMaster;
import com.intelligt.modbus.jlibmodbus.master.ModbusMasterFactory;
import com.intelligt.modbus.jlibmodbus.msg.base.ModbusResponse;
import com.intelligt.modbus.jlibmodbus.msg.request.WriteMultipleRegistersRequest;
import com.intelligt.modbus.jlibmodbus.msg.request.WriteSingleRegisterRequest;
import com.intelligt.modbus.jlibmodbus.tcp.TcpParameters;

import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class MasterTCP {
    static public void main(String[] args) {
        try {
            TcpParameters tcpParameters = new TcpParameters();
            //tcp parameters have already set by default as in example
            //设置TCP的ip地址
            tcpParameters.setHost(InetAddress.getByName("192.168.1.66"));
            //设置TCP长连接
            tcpParameters.setKeepAlive(true);
            //设置端口,这里设置是默认端口502
            tcpParameters.setPort(Modbus.TCP_PORT);

            //if you would like to set connection parameters separately,如果您想单独设置连接参数
            // you should use another method:你应该使用另一种方法: createModbusMasterTCP(String host, int port, boolean keepAlive);
            //创建一个主机
            ModbusMaster m = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
            Modbus.setAutoIncrementTransactionId(true);
            //从机地址
            int slaveId = 1;
            //寄存器读取的开始地址
            int offset = 200;
            //读取的寄存器数量
            int quantity = 1;

            try {
                // since 1.2.8,建立连接
                if (!m.isConnected()) {
                    m.connect();
                }
                // at next string we receive ten registers from a slave with id of 1 at offset of 0.
                //读取对应的从机的数据,readHoldingRegisters读取的保持寄存器,功能码03
                int[] registerValues = m.readHoldingRegisters(slaveId, offset, quantity);

                //遍历后控制台输出
                for (int value : registerValues) {
                    System.out.println("Address输出: " + offset++ + ", Value: " + value);
                }

                //这个可以写进去,但是应该要和读取分开
                m.writeMultipleRegisters(1,203,(new int[]{111,222}));


              //  m.writeSingleRegister(1,203,(长的尺寸的高16位浮点数,低16位浮点数));

                // also since 1.2.8.4 you can create your own request and process it with the master
//                int offset1 = 100;
//                ReadHoldingRegistersRequest request = new ReadHoldingRegistersRequest();
//                request.setServerAddress(1);
//                request.setStartAddress(offset1);
//                request.setTransactionId(0);
//                ReadHoldingRegistersResponse response = (ReadHoldingRegistersResponse) m.processRequest(request);
//                // you can get either int[] containing register values or byte[] containing raw bytes.
//                for (int value : response.getRegisters()) {
//                    System.out.println("Address: " + offset1++ + ", Value: " + value);
//                }
                float value = 4333.2f;
                int intBits = Float.floatToRawIntBits(value);
                m.writeMultipleRegisters(1,100,(new int[]{((intBits >> 16) & 0xFFFF),(intBits & 0xFFFF)}));
//                short[] send = new short[]{(short) ((intBits >> 16) & 0xFFFF), (short) (intBits & 0xFFFF)};


            } catch (ModbusProtocolException e) {
                e.printStackTrace();
            } catch (ModbusNumberException e) {
                e.printStackTrace();
            } catch (ModbusIOException e) {
                e.printStackTrace();
            } finally {
                try {
                    m.disconnect();
                } catch (ModbusIOException e) {
                    e.printStackTrace();
                }
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


}


联系站长

站长微信:xiaomao0055

站长QQ:14496453