Android 蓝牙BLE串口通信之高低位转换、16进制字符串转换float浮点型

在这里插入图片描述


       蓝牙技术的普及与发展,为传统设备提供了一种低成本无线通信的方式。串口作为一种使用广泛的通信接口,通过串口转蓝牙,进行无线通信传输的需求逐渐展现出来。

       蓝牙串口模块是嵌入式设备上的常用模块,它可以方便地和手机建立连接,实时传输数据。
在这里插入图片描述

Android蓝牙客户端的流程图

大家从以上图,也能知道Android 蓝牙客户端的具体流程!
而本文具体讲解蓝牙BLE串口通信之高低位转换、16进制字符串转换float浮点型

       最近在对接我司其他硬件设备,在做数据处理的时候,硬件写c的工程师,对于返回数据并没有做相应的处理,还得我们自己去拿原始数据去做相应的处理。最后把处理完的数据,展示给用户!

这里该说不说,写c的同事,还把他的代码发给我看,让我照着搬砖,这可能吗?那是绝对不可能的。

在这里插入图片描述

当时真的是无语子>_<。。。。下面请大家看一下数据处理流程。

数据处理

当时拿到byte原始数据之后,做了16进制处理,总共18个字节。
而展示给用户的血糖数据值总共是4个字节,数据是66663641,当拿到这个数据以为就完了吗?
那你就错了,心里:“好几个艹尼玛飘过”。

在这里得区分两部分来做处理:

  1. 高低位转换
  2. 16进制字符串转换为float浮点型

(1)高低位转换

高八位和低八位:内存里,一个单元是一个字节,也就是8位。e69da5e6ba903231313335323631343130323136353331333366306438如果是16位的指令,就是同时操作连续的2个内存地址,将这连续的2个内存地址当成一个单位,所以就有高8位和低8位之分。
由于计算机仅识别二进制描述的数字,所以对一个内存地址,也就是8位二进制,如:0000 0001,0000就是高四位,0001就是低四位。

当然2个内存地址,就是16位二进制,也就是:0000 0001 0000 0002。0000 0001 就是高八位,0000 0002就是低八位。

每个八位中又分成高低四位。如:1010 0001 1111 0101,换算成16进制就是:1010–10(10进制)—A(16进制),0001–1(10进制)—1(16进制)所以他的高八位就是A1,同样它的低八位就是F5。

       对于如上内容,通俗易懂,我自己的理解就是:在16进制的基础上,做数据处理时,只要大于1个字节,就需要做高低位转换。当只有1个字节的时候,肯定是不变的。比如是0x01,这是一个字节,最终还是01

代码处理:

    /**
     * 十六进制字符串 高低位转换
     *
     * @param hex
     * @return
     */
    public static String reverseHex(String hex) {
        char[] charArray = hex.toCharArray();
        int length = charArray.length;
        int times = length / 2;
        for (int c1i = 0; c1i < times; c1i += 2) {
            int c2i = c1i + 1;
            char c1 = charArray[c1i];
            char c2 = charArray[c2i];
            int c3i = length - c1i - 2;
            int c4i = length - c1i - 1;
            charArray[c1i] = charArray[c3i];
            charArray[c2i] = charArray[c4i];
            charArray[c3i] = c1;
            charArray[c4i] = c2;
        }
        return new String(charArray);
    }

如上所知,血糖值原始数据是4个字节:66663641;高低转换为结果:41366666

(2)16进制字符串转换为float浮点型

    try {
         String math = DealNum.substring(hexStr, 20, 28);
         String userMath = HexUtil.reverseHex(math);
         //十六进制字符串转换为float符点型
         long l = HexUtil.parseLong(userMath, 16);
         float bits = Float.intBitsToFloat((int) l);
         Log.e("血糖数据 >>", "notifyData: " + math + "---" + userMath + "---" + l + "---" + bits);
        mNearNum.setText(bits + "");
    } catch (HexUtil.NumberFormatException e) {
        e.printStackTrace();
    }

通过以上代码执行,得出血糖值为11.4。

intBitsToFloat() 方法遵循 IEEE 754 浮点标准,根据标准,它返回与表示整数位表示的给定参数相对应的浮点值。

具体调用parseLong()方法:

    /**
     * 16进制字符串转换为float符点型
     *
     * @param s
     * @param radix
     * @return
     * @throws NumberFormatException
     */
    public static long parseLong(String s, int radix) throws NumberFormatException {
        if (s == null) {
            throw new NumberFormatException("null");
        }
        if (radix < Character.MIN_RADIX) {
            throw new NumberFormatException("radix" + radix + "less than Character.MIN_RADIX");
        }
        if (radix > Character.MAX_RADIX) {
            throw new NumberFormatException("radix" + radix + "greater than Character.MAX_RADIX");
        }
        long result = 0;
        boolean negative = false;
        int i = 0, len = s.length();
        long limit = -Long.MAX_VALUE;
        long multmin;
        int digit;
        if (len > 0) {
            char firstChar = s.charAt(0);
            if (firstChar < '0') {// Possible leading "+" or "-"
                if (firstChar == '-') {
                    negative = true;
                    limit = Long.MIN_VALUE;
                } else if (firstChar != '+')
                    throw NumberFormatException.forlnputString(s);
                if (len == 1) // Cannot have lone "+" or "-"
                    throw NumberFormatException.forlnputString(s);
                i++;
            }
            multmin = limit / radix;
            while (i < len) {
                // Accumulating negatively avoids surprises near MAX_VALUE
                digit = Character.digit(s.charAt(i++), radix);
                if (digit < 0) {
                    throw NumberFormatException.forlnputString(s);
                }
                if (result < multmin) {
                    throw NumberFormatException.forlnputString(s);
                }
                result *= radix;
                if (result < limit + digit) {
                    throw NumberFormatException.forlnputString(s);
                }
                result -= digit;
            }
        } else {
            throw NumberFormatException.forlnputString(s);
        }
        return negative ? result : -result;
    }

    /**
     * NuberFormatException
     */
    public static class NumberFormatException extends IllegalAccessException {
        /**
         *
         */
        private static final long serialVersionUID = 1L;

        public NumberFormatException(String s) {
            super(s);
        }

        static NumberFormatException forlnputString(String s) {
            return new NumberFormatException("For input string: \"" + s + "\"");
        }
    }

float符点型转换为16进制字符串

    /**
     * float符点型转换为16进制字符串
     * @param changeData
     * @return
     */
    public static String fToHex(float changeData){
        return Integer.toHexString(Float.floatToIntBits(changeData));
    }
  Log.e("血糖数据 >>", "notifyData: " + "-0.154678" );
  String fToHex = HexUtil.fToHex((float) -0.154678);
  Log.e("血糖数据 >>", "notifyData: " + "-0.154678" + "---" + fToHex);

在这里插入图片描述

结尾

16进制字符串转换为float符点型在线转换工具

如果这份博客对铁们有所帮助,或能够使你产生共鸣的,请不要吝啬你的点赞关注哟,谢谢!!!
如果有什么疑问或不同的见解,欢迎评论区留言欧>_<…


版权声明:本文为chen_md原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。