• 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);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    如上所知,血糖值原始数据是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();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    通过以上代码执行,得出血糖值为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 + "\"");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

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

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

    在这里插入图片描述

    结尾

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

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

  • 相关阅读:
    回归预测 | MATLAB实现PCA-BP主成分降维结合BP神经网络多输入单输出回归预测
    测试用的文章标题
    客户收到报价后突然安静了,怎么办?
    REDIS00_详解redis.conf配置文件
    ESlint配合Prettier完成代码风格配置
    Linux驱动中断与时间篇——低分辨率定时器
    Endpoint Central的IT资产管理(ITAM)
    设计模式之命令模式
    四旋翼无人机学习第12节--跨页连接符的标号设置、DRC、PDF导出
    Java 开发从零开始,java 基础入门传智播客网页版,Java 后端路线图
  • 原文地址:https://blog.csdn.net/chen_md/article/details/127423191