java通过modbus协议的工具包读取并转换成float数据格式

背景

接到客户需求,需要将一个设备的数据读取出来并保存到数据库。改设备通过网络的话是使用modbus协议进行通信的,而且客户需求读取的数据是浮点数类型,一个浮点数占设备2个寄存器,使用工具包只能一个个的寄存器的值读取出来,本文代码,可以将2个寄存器的值一次都转换成一个一个的浮点数。创作不易,希望大家能够给关注或者点赞,本人技术也有很多的欠缺和不足,欢迎大家讨论并交流。

依赖

<dependency>
  <groupId>com.intelligt.modbus</groupId>
  <artifactId>jlibmodbus</artifactId>
  <version>1.2.9.7</version>
</dependency>

demo代码

package com.example.demo.hex;

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.math.BigInteger;
import java.net.InetAddress;
import java.text.DecimalFormat;

public class A1 {
    public static void main(String[] args) {
        /*int arry[] = new int[14];
        arry[0] = 58196;
        arry[1] = 16763;
        arry[2] = 2097;
        arry[3] = 15532;
        arry[4] = 524;
        arry[5] = 16611;
        arry[6] = 39846;
        arry[7] = 15300;
        arry[8] = 35127;
        arry[9] = 16621;
        arry[10] = 34079;
        arry[11] = 16907;
        arry[12] = 11633;
        arry[13] = 17435;*/
          //int数组转以两个为一组,一次转换成一个个的浮点数,并打印
               // convertFloat(registerValues);
        
        try {
            // 设置主机TCP参数
            TcpParameters tcpParameters = new TcpParameters();

            // 设置TCP的ip地址
            InetAddress adress = InetAddress.getByName("192.168.3.16");

            // TCP参数设置ip地址
            // tcpParameters.setHost(InetAddress.getLocalHost());
            tcpParameters.setHost(adress);

            // TCP设置长连接
            tcpParameters.setKeepAlive(true);
            // TCP设置端口,这里设置是默认端口502
            tcpParameters.setPort(6000);

            // 创建一个主机
            ModbusMaster master = ModbusMasterFactory.createModbusMasterTCP(tcpParameters);
            Modbus.setAutoIncrementTransactionId(true);

            int slaveId = 1;//从机地址
            int offset = 0;//寄存器读取开始地址
            int quantity = 10;//读取的寄存器数量


            try {
                if (!master.isConnected()) {
                    master.connect();// 开启连接
                }
                // 读取对应从机的数据,readInputRegisters读取的写寄存器,功能码04
                //int[] registerValues = master.readInputRegisters(slaveId, offset, quantity);
                //功能码03
                int[] registerValues = master.readHoldingRegisters(slaveId, offset, quantity);
                //int数组转以两个为一组,一次转换成一个个的浮点数,并打印
                convertFloat(registerValues);

                // 控制台输出
               // 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 {
                    master.disconnect();
                } catch (ModbusIOException e) {
                    e.printStackTrace();
                }
            }
        } catch (RuntimeException e) {
            throw e;
        } catch (Exception e) {
            e.printStackTrace();
        }
        


    }

    /**
     * int数组转以两个为一组,一次转换成一个个的浮点数,并打印
     * @param arry
     */
    public static void convertFloat(int arry[]){
        for (int i = 0; i < arry.length; i++) {
            if (i == 1) {
                byte bytes1[] = new byte[2];
                //bytes1 = int2Bytes(arry[0], 2);
                bytes1 = Int2Bytes_LE(arry[0]);

                byte bytes2[] = new byte[2];
                //bytes2 = int2Bytes(arry[1], 2);
                bytes2 = Int2Bytes_LE(arry[1]);

                byte bytes[] = new byte[4];
                bytes[0]=bytes1[0];
                bytes[1]=bytes1[1];
                bytes[2]=bytes2[0];
                bytes[3]=bytes2[1];
                System.out.println(hex(bytes));
                System.out.println(sfloat(hex(bytes)));
            } else {
                if ((i+1)%2==0) {
                    byte bytes1[] = new byte[2];
                    bytes1 = Int2Bytes_LE(arry[i-1]);
                    byte bytes2[] = new byte[2];
                    bytes2 = Int2Bytes_LE(arry[i]);

                    byte bytes[] = new byte[4];
                    bytes[0]=bytes1[0];
                    bytes[1]=bytes1[1];
                    bytes[2]=bytes2[0];
                    bytes[3]=bytes2[1];
                    System.out.println(hex(bytes));
                    System.out.println(sfloat(hex(bytes)));
                }
            }
        }
    }

    /**
     * 转小端,返回2个字节数组
     * @param iValue
     * @return
     */
    public static byte[] Int2Bytes_LE(int iValue){
        byte[] rst = new byte[2];
        // 先写int的最后一个字节
        rst[0] = (byte)(iValue & 0xFF);
        // int 倒数第二个字节
        rst[1] = (byte)((iValue & 0xFF00) >> 8 );
        return rst;
    }
    //转大端返回4个字节数组
    public static byte[] intToByteBig(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n >> 24 & 0xff);
        b[1] = (byte) (n >> 16 & 0xff);
        b[2] = (byte) (n >> 8 & 0xff);
        b[3] = (byte) (n & 0xff);
        return b;
    }
    //转小端返回4个字节数组
    public static byte[] intToByteLittle(int n) {
        byte[] b = new byte[4];
        b[0] = (byte) (n & 0xff);
        b[1] = (byte) (n >> 8 & 0xff);
        b[2] = (byte) (n >> 16 & 0xff);
        b[3] = (byte) (n >> 24 & 0xff);
        return b;
    }


    private static String sfloat(String str){
        int count = str.length()/2;
        String last = "";
        for(int i = count-1;i>=0;i--){
            String one = str.substring(i*2,(i+1)*2);
            last+=one;
        }
        if(!"".equals(last)) {
            Float f = Float.intBitsToFloat(new BigInteger(last, 16).intValue());
            //将科学计算值转可以看懂的数值
            DecimalFormat fnum = new DecimalFormat("##0.000");
            String dd = fnum.format(f);
            return dd;
        }
        return "--";
    }
	//将一个int数转换成几个字节数组
    public static byte[] int2Bytes(int value, int len) {
        byte b[] = new byte[len];
        for (int i = 0; i < len; i++) {
            b[len - i - 1] = (byte) ((value >> 8 * i) & 0xff);
        }
        return b;
    }

    public static String hex(byte[] bytes) {
        StringBuilder result = new StringBuilder();
        for (byte aByte : bytes) {
            result.append(String.format("%02x", aByte));
        }
        return result.toString();
    }



}

效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值