• modbus 四字节转成float


    package com.xxl.job.executor.sample.frameless;

    import java.io.IOException;
    import java.math.BigInteger;

    public class FinalTest {
    public static void main(String[] args) {
    //模拟向2号寄存器写入100
    ModbusDataFormationBean modbusDataFormationBean=new ModbusDataFormationBean();
    modbusDataFormationBean.setAddr(1);//地址1
    modbusDataFormationBean.setFuncode(3);//功能码5代表写入寄存器
    modbusDataFormationBean.setPortNumber(2);//2代表寄存器起始位为2
    modbusDataFormationBean.setValue(100);//向2号寄存器写入100
    modbusDataFormationBean.setDataType(1);//1代表写入的值是16位的
    byte[] modbusData=ModbusTools.data(modbusDataFormationBean);//对象转modbus数据


    //模拟读取返回的3个寄存器数据
    //01030443686edf0393
    byte[] data={(byte)0x01,(byte)0x03,(byte)0x06,(byte)0x01,(byte)0x67,(byte) 0xff,
    (byte) 0xb5,(byte)0x00,(byte)0x64,(byte)0xd7,(byte)0x5e};
    byte[] data2={(byte)0x01,(byte)0x03,(byte)0x04,(byte)0x43,(byte)0x68,(byte) 0x6e,
    (byte) 0xdf,(byte)0x03,(byte)0x93};
    //1. modbud存储小数 byte数组 将两个寄存器的值 转成两个十进制的整数 float
    ModbusDataAnalyzeBean modbusDataAnalyzeBean =ModbusTools.dataAnalyze(data,1);
    System.out.println("modbus数据解析为对象:"+modbusDataAnalyzeBean.toString());//modbus数据转对象
    ModbusDataAnalyzeBean modbusDataAnalyzeBean2 =ModbusTools.dataAnalyze(data2,1);
    System.out.println("modbus数据解析为对象:"+modbusDataAnalyzeBean2.toString());//modbus数据转对象
    float v = ParseUtil.toFloat(modbusDataAnalyzeBean2.getValues().get(0).intValue(), modbusDataAnalyzeBean2.getValues().get(1).intValue());
    System.out.println(v);


    String str="43686edf";
    int value = Integer.parseInt(str, 16);
    value = ((value & 0x8000) > 0) ? (value - 0x10000) : (value );
    float value1 = Float.intBitsToFloat(value);
    System.out.println(value1);
    //2. 十六进制 四个byte 4*8=32位 string转float
    float value2 = Float.intBitsToFloat(new BigInteger(str, 16).intValue());
    System.out.println(value2);

    //3. CRC校验
    //0103044368dddeb763
    byte[] data3={(byte)0x01,(byte)0x03,(byte)0x04,(byte)0x43,(byte)0x68,(byte) 0xdd,
    (byte) 0xde};
    Integer crc162Int = ModbusTools.getCRC162Int(data3, true);
    String result = Integer.toHexString(crc162Int);
    System.out.println(result);

    //4. 将十六进制的 字符串转成byte数组
    String str2="0103044368ddde";
    int length = str2.length()/2;
    byte[] bytes = ModbusTools.hexString2ByteArray(str2, length);
    System.out.println(bytes);

    //5. byte数组转成float
    try {
    byte[] vs = new byte[]{0x41, (byte)0xd2, (byte)0x66, (byte)0x66};
    System.out.println(ParseUtil.toFloat(vs));
    byte[] vs2 = new byte[]{(byte)0xC1, (byte)0xd2, (byte)0x66, (byte)0x66};
    System.out.println(ParseUtil.toFloat(vs2));
    float v1 = ParseUtil.toFloat(vs2);
    System.out.println(v1);
    } catch (IOException e) {
    e.printStackTrace();
    }

    }
    }






    package com.xxl.job.executor.sample.frameless


    public class ModbusTools {
    /**
    * modbus数据转对象
    * @param data 串口数据
    * @param dataType 1代表16位读取2个byte数据,2代表32位读取4个byte数据
    */
    public static ModbusDataAnalyzeBean dataAnalyze(byte []data, int dataType)
    {
    int readByteNum=0;//一次要读取多少个byte
    if (dataType==1)
    {
    readByteNum=2;
    }
    else if (dataType>1)
    {
    readByteNum=dataType*dataType;
    }

    ModbusDataAnalyzeBean modbusDataAnalyzeBean =new ModbusDataAnalyzeBean();
    modbusDataAnalyzeBean.setAddr(Integer.parseInt(getOctFromHexBytes(data,0)));//获取地址
    modbusDataAnalyzeBean.setFuncode(Integer.parseInt(getOctFromHexBytes(data,1)));//获取功能码
    modbusDataAnalyzeBean.setDataType(dataType);//数据类型
    int byteNum=Integer.parseInt(getOctFromHexBytes(data,2));//统计有效byte数据个数

    ArrayList<Double> arrayListVlaue=new ArrayList();
    for (int n=1;n<(byteNum/readByteNum)+1;n++)
    {
    arrayListVlaue.add(Double.parseDouble(getOctFromHexBytes(data,3+readByteNum*(n-1),3+readByteNum*n-1)));//获取值
    }
    modbusDataAnalyzeBean.setValues(arrayListVlaue);//将取到的值存进返回对象
    return modbusDataAnalyzeBean;
    }

    /**
    * 对象转modbus数据
    * @param modbusDataFormationBean
    * @return
    */

    public static byte[] data(ModbusDataFormationBean modbusDataFormationBean)
    {
    int readByteNum=0;//一次要读取多少个byte
    if (modbusDataFormationBean.getDataType()==1)
    {
    readByteNum=2;
    }
    else if (modbusDataFormationBean.getDataType()>1)
    {
    readByteNum=modbusDataFormationBean.getDataType()*modbusDataFormationBean.getDataType();
    }
    byte[] command=new byte[]{};
    command = append(command,octInt2ByteArray( modbusDataFormationBean.getAddr(), 1));//设置地址
    command = append(command,octInt2ByteArray( modbusDataFormationBean.getFuncode(), 1)); //设置功能码
    command = append(command,octInt2ByteArray( modbusDataFormationBean.getPortNumber(), 2));//设置寄存器起始地址
    command = append(command,octInt2ByteArray( modbusDataFormationBean.getValue(), readByteNum));//设置数据值
    command = append(command, octInt2ByteArray( getCRC162Int(command,true), 2) );// 设置CRC16校验

    return command;
    }


    /**
    * 取得十制数组的from~to位,并按照十六进制转化值
    *
    * @param data
    * @param from
    * @param to
    * @return
    */
    private static String getOctFromHexBytes(byte[] data, Object from, Object... to) {
    if (data != null && data.length > 0 && from != null) {
    try {
    byte[] value;
    int fromIndex = Integer.parseInt(from.toString());
    if (to != null && to.length > 0) {
    int toIndex = Integer.parseInt(to[0].toString());
    if (fromIndex >= toIndex || toIndex <= 0) {
    value = Arrays.copyOfRange(data, fromIndex, fromIndex + 1);
    } else {
    value = Arrays.copyOfRange(data, fromIndex, toIndex + 1);
    }
    } else {
    value = Arrays.copyOfRange(data, fromIndex, fromIndex + 1);
    }
    if (value != null && value.length > 0) {
    long octValue = 0L;
    int j = -1;
    for (int i = value.length - 1; i >= 0; i--, j++) {
    int d = value[i];
    if (d < 0) {
    d += 256;
    }
    octValue += Math.round(d * Math.pow(16, 2 * j + 2));
    }
    return new Long(octValue).toString();
    }
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    return null;
    }

    /**
    * 十进制的字符串表示转成字节数组
    *
    * @param octString
    * 十进制格式的字符串
    * @param capacity
    * 需要填充的容量(可选)
    * @return 转换后的字节数组
    **/
    private static byte[] octInt2ByteArray(Integer oct, int... capacity) {
    return hexString2ByteArray(Integer.toHexString(oct), capacity);
    }
    /**
    * 16进制的字符串表示转成字节数组
    *
    * @param hexString
    * 16进制格式的字符串
    * @param capacity
    * 需要填充的容量(可选)
    * @return 转换后的字节数组
    **/
    public static byte[] hexString2ByteArray(String hexString, int... capacity) {
    hexString = hexString.toLowerCase();
    if (hexString.length() % 2 != 0) {
    hexString = "0" + hexString;
    }
    int length = hexString.length() / 2;
    if (length < 1) {
    length = 1;
    }
    int size = length;
    if (capacity != null && capacity.length > 0 && capacity[0] >= length) {
    size = capacity[0];
    }
    final byte[] byteArray = new byte[size];
    int k = 0;
    for (int i = 0; i < size; i++) {
    if (i < size - length) {
    byteArray[i] = 0;
    } else {
    byte high = (byte) (Character.digit(hexString.charAt(k), 16) & 0xff);
    if (k + 1 < hexString.length()) {
    byte low = (byte) (Character.digit(hexString.charAt(k + 1), 16) & 0xff);
    byteArray[i] = (byte) (high << 4 | low);
    } else {
    byteArray[i] = (byte) (high);
    }
    k += 2;
    }
    }
    return byteArray;

    }

    /**
    * 连接字节流
    *
    * @return
    */
    private static byte[] append(byte[] datas, byte[] data) {
    if (datas == null) {
    return data;
    }
    if (data == null) {
    return datas;
    } else {
    return concat(datas, data);
    }
    }

    /**
    * 字节流拼接
    *
    * @param data
    * 字节流
    * @return 拼接后的字节数组
    **/
    private static byte[] concat(byte[]... data) {
    if (data != null && data.length > 0) {
    int size = 0;
    for (int i = 0; i < data.length; i++) {
    size += data[i].length;
    }
    byte[] byteArray = new byte[size];
    int pos = 0;
    for (int i = 0; i < data.length; i++) {
    byte[] b = data[i];
    for (int j = 0; j < b.length; j++) {
    byteArray[pos++] = b[j];
    }
    }
    return byteArray;
    }
    return null;
    }
    public static Integer getCRC162Int(byte[] bytes,Boolean flag) {
    int CRC = 0x0000ffff;
    int POLYNOMIAL = 0x0000a001;

    int i, j;
    for (i = 0; i < bytes.length; i++) {
    // CRC ^= (int) bytes[i];

    if(bytes[i] <0 ){
    CRC ^= (int) (bytes[i]+256) ;
    }else{
    CRC ^= (int) bytes[i] ;
    }


    for (j = 0; j < 8; j++) {
    if ((CRC & 0x00000001) == 1) {
    CRC >>= 1;
    CRC ^= POLYNOMIAL;
    } else {
    CRC >>= 1;
    }
    }
    }
    //高低位转换,看情况使用(譬如本人这次对led彩屏的通讯开发就规定校验码高位在前低位在后,也就不需要转换高低位)
    if(flag){
    CRC = ( (CRC & 0x0000FF00) >> 8) | ( (CRC & 0x000000FF ) << 8);
    }
    return CRC;
    }
    }


  • 相关阅读:
    Uboot命令使用
    git删除某次提交
    chrome随意改变主题
    C++11——处理日期和时间的chrono库
    C++11——多线程异步操作
    C++11——原子变量
    C++11——C++线程同步之条件变量
    C++11——C++线程同步之互斥锁
    C++11——call_once
    C++11——命名空间
  • 原文地址:https://www.cnblogs.com/jishumonkey/p/15766968.html
Copyright © 2020-2023  润新知