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

34 篇文章 0 订阅
4 篇文章 1 订阅

在这里插入图片描述


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

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

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符点型在线转换工具

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

在微信小程序中,可以使用以下代码将16进制字符串转换16进制的数据: ```javascript const hexStringToArrayBuffer = (byteLen, str) => { if (byteLen <= 0) { return new ArrayBuffer(0); } if (!str) { return new ArrayBuffer(0); } str = str.padStart(byteLen * 2, '0'); let tmpByte = byteConversion(); str = tmpByte.toString(16); var buffer = new ArrayBuffer(byteLen); let dataView = new DataView(buffer); let idx = 0; for (var i = 0, len = str.length; i < len; i += 2) { let subStr = str.substr(i, 2); let code = parseInt(subStr, 16); dataView.setUint8(idx, code); idx++; } return buffer; } ``` 以上代码中的`hexStringToArrayBuffer`函数接受两个参数,`byteLen`表示字节长度,`str`表示要转换16进制字符串。函数内部会将字符串转换成对应的16进制数据,并返回一个`ArrayBuffer`对象。 你可以在调用`writeData`函数时,将需要发送的16进制字符串作为参数传入`hexStringToArrayBuffer`函数,然后将返回的`ArrayBuffer`对象作为`value`参数传递给`wx.writeBLECharacteristicValue`函数,即可将16进制字符串转换16进制的数据并发送给设备。 #### 引用[.reference_title] - *1* *2* [微信小程序蓝牙BLE开发——写入一串16进制数据,低字节在前(五)](https://blog.csdn.net/Smile_ping/article/details/120934213)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

拉莫帅

你的鼓励将是我的创作动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值