zoukankan      html  css  js  c++  java
  • 【Modbus】Java使用 modbus-master-tcp 读取和写入Modbus服务器数据

    参考了云逸的 Java实现ModbusTCP通信

    1、前言

    在井下综采面需要用到工业级控制协议,采用了Modbus主站从站通讯方式,直接操作寄存器数据,实现读取和控制。

    2、引用pom

            <dependency>
                <groupId>com.digitalpetri.modbus</groupId>
                <artifactId>modbus-master-tcp</artifactId>
                <version>1.1.0</version>
            </dependency>
    

    3、上代码

    package com;
    
    import java.util.Arrays;
    import java.util.Random;
    import java.util.concurrent.CompletableFuture;
    import java.util.concurrent.ExecutionException;
    
    import com.digitalpetri.modbus.FunctionCode;
    import com.digitalpetri.modbus.codec.Modbus;
    import com.digitalpetri.modbus.master.ModbusTcpMaster;
    import com.digitalpetri.modbus.master.ModbusTcpMasterConfig;
    import com.digitalpetri.modbus.requests.*;
    import com.digitalpetri.modbus.responses.*;
    
    import io.netty.buffer.ByteBuf;
    import io.netty.util.ReferenceCountUtil;
    
    /***
     * modbus TCP协议Java通讯读取例子
     */
    public class ModbusMasterTCP {
    
        static ModbusTcpMaster master;
    
        /**
         * 获取TCP协议的Master
         *
         * @return
         */
        public static void initModbusTcpMaster() {
            if (master == null) {
                // 创建配置
                ModbusTcpMasterConfig config = new ModbusTcpMasterConfig.Builder("localhost").setPort(502).build();
                master = new ModbusTcpMaster(config);
            }
        }
    
        /***
         * 释放资源
         */
        public static void release() {
            if (master != null) {
                master.disconnect();
            }
            Modbus.releaseSharedResources();
        }
    
        /**
         * 读取Coils开关量
         *
         * @param address  寄存器开始地址
         * @param quantity 数量
         * @param unitId   ID
         * @return 读取值
         * @throws InterruptedException 异常
         * @throws ExecutionException   异常
         */
        public static Boolean readCoils(int address, int quantity, int unitId)
                throws InterruptedException, ExecutionException {
            Boolean result = null;
            CompletableFuture<ReadCoilsResponse> future = master.sendRequest(new ReadCoilsRequest(address, quantity),
                    unitId);
            ReadCoilsResponse readCoilsResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理
            if (readCoilsResponse != null) {
                ByteBuf buf = readCoilsResponse.getCoilStatus();
                result = buf.readBoolean();
                ReferenceCountUtil.release(readCoilsResponse);
            }
            return result;
        }
    
        /**
         * 读取readDiscreteInputs开关量
         *
         * @param address  寄存器开始地址
         * @param quantity 数量
         * @param unitId   ID
         * @return 读取值
         * @throws InterruptedException 异常
         * @throws ExecutionException   异常
         */
        public static Boolean readDiscreteInputs(int address, int quantity, int unitId)
                throws InterruptedException, ExecutionException {
            Boolean result = null;
            CompletableFuture<ReadDiscreteInputsResponse> future = master
                    .sendRequest(new ReadDiscreteInputsRequest(address, quantity), unitId);
            ReadDiscreteInputsResponse discreteInputsResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理
            if (discreteInputsResponse != null) {
                ByteBuf buf = discreteInputsResponse.getInputStatus();
                result = buf.readBoolean();
                ReferenceCountUtil.release(discreteInputsResponse);
            }
            return result;
        }
    
        /**
         * 读取HoldingRegister数据
         *
         * @param address  寄存器地址
         * @param quantity 寄存器数量
         * @param unitId   id
         * @return 读取结果
         * @throws InterruptedException 异常
         * @throws ExecutionException   异常
         */
        public static Number readHoldingRegisters(int address, int quantity, int unitId)
                throws InterruptedException, ExecutionException {
            Number result = null;
            CompletableFuture<ReadHoldingRegistersResponse> future = master
                    .sendRequest(new ReadHoldingRegistersRequest(address, quantity), unitId);
            ReadHoldingRegistersResponse readHoldingRegistersResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理
            if (readHoldingRegistersResponse != null) {
                ByteBuf buf = readHoldingRegistersResponse.getRegisters();
                byte[] bytes = new byte[buf.capacity()];
                buf.readBytes(bytes, 0, buf.capacity());
                System.out.println("bytes=" + Arrays.toString(bytes));//bytes=[0, 21]
                result = bytes[1];
                ReferenceCountUtil.release(readHoldingRegistersResponse);
            }
            return result;
        }
    
        /**
         * 读取InputRegisters模拟量数据
         *
         * @param address  寄存器开始地址
         * @param quantity 数量
         * @param unitId   ID
         * @return 读取值
         * @throws InterruptedException 异常
         * @throws ExecutionException   异常
         */
        public static Number readInputRegisters(int address, int quantity, int unitId)
                throws InterruptedException, ExecutionException {
            Number result = null;
            CompletableFuture<ReadInputRegistersResponse> future = master
                    .sendRequest(new ReadInputRegistersRequest(address, quantity), unitId);
            ReadInputRegistersResponse readInputRegistersResponse = future.get();// 工具类做的同步返回.实际使用推荐结合业务进行异步处理
            if (readInputRegistersResponse != null) {
                ByteBuf buf = readInputRegistersResponse.getRegisters();
                result = buf.readDouble();
                ReferenceCountUtil.release(readInputRegistersResponse);
            }
            return result;
        }
    
    
        /**
         * 写HoldingRegister数据
         *
         * @param address 寄存器地址
         * @param value   写入值
         * @param unitId  id
         * @return 写入结果
         * @throws InterruptedException 异常
         * @throws ExecutionException   异常
         */
        public static void writeHoldingRegisters(int address, int value, int unitId) throws InterruptedException, ExecutionException {
            // 发送单个寄存器数据,一般是无符号16位值:比如10
            CompletableFuture<ModbusResponse> future = master.sendRequest(new WriteSingleRegisterRequest(address, value), unitId);
            ModbusResponse modbusResponse = future.get();
            if (modbusResponse != null) {
                FunctionCode functionCode = modbusResponse.getFunctionCode();
                System.out.println("functionCode.getCode()=" + functionCode.getCode());
            } else {
                System.out.println("WriteHoldingRegisters return empty ");
            }
        }
    
        public static void writeDemo() {
            // 初始化资源
            initModbusTcpMaster();
    
            Random random = new Random();
            int value = random.nextInt(100) + 1;
            System.out.println("write value=" + value);
            try {
                writeHoldingRegisters(222, value, 1);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } catch (ExecutionException e) {
                e.printStackTrace();
            }
    
            // 释放资源
            release();
        }
    
        public static void readDemo() {
            try {
                // 初始化资源
                initModbusTcpMaster();
    
                // 执行操作
    
                // 读取开关量
                // System.out.println(readCoils(0, 1, 1));
                // System.out.println(readDiscreteInputs(0, 1, 1));
                // System.out.println(readDiscreteInputs(1, 1, 1));
    
                // 读取模拟量
                // System.out.println(readHoldingRegisters(0, 2, 1));
                // System.out.println(readHoldingRegisters(2, 2, 1));
                // System.out.println(readHoldingRegisters(4, 2, 1));
                // System.out.println(readInputRegisters(2, 4, 1));
                // System.out.println(readInputRegisters(6, 4, 1));
    
                System.out.println("readHoldingRegisters=" + readHoldingRegisters(222, 1, 1));
    
                // 释放资源
                release();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static void main(String[] args) {
            // writeDemo();
            readDemo();
        }
    }
    
  • 相关阅读:
    sgu175pascal
    poj3659pascal
    poj3411
    传球游戏pascal
    ubuntu 9.04 wubi安装的问题 2009511 13:58:00 (21ic)
    任何道理都是有局限的 20081020 11:07:00 (21ic)
    浓浓的亲情 2008106 8:53:00 (21ic)
    卖买房所得
    黑色的一周 20081018 3:23:00 (21ic)
    度的把握 2008929 20:59:00
  • 原文地址:https://www.cnblogs.com/kikyoqiang/p/14238436.html
Copyright © 2011-2022 走看看