欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

微信小程序蓝牙BLE开发——关于进制转换(四)

程序员文章站 2024-02-05 12:56:34
...

微信小程序蓝牙BLE开发——进制转换

这段时间开发共享设备,对接蓝牙BLE设备通信协议,过程中用到一些进制转换, 记录下方便使用。

有些参考大神们,感谢分享。

关于字节理解

字节(Byte):计算机信息技术用于计量存储容量的一种计量单位,作为一个单位来处理的一个二进制数字串。

其中下发指令或处理数据时都可以应用到

  • 1B(byte,字节)= 8 bit(比特), 相当于一个字符
  • 一个字节能表示的最大的整数就是255
  • 例如: 数据为5d000001be5d理解为6个字节(6B)

ArrayBuffer转16进度字符串

// ArrayBuffer转16进度字符串示例
function ab2hex(buffer) {
    var hexArr = Array.prototype.map.call(
        new Uint8Array(buffer),
        function(bit) {
            return ('00' + bit.toString(16)).slice(-2)
        }
    )
    return hexArr.join('');
}

Demo

这里以使用微信小程序 蓝牙BLE获取广播数据为例。这里说明下: advertisData是硬件另外返回的数据,有些供应商设备是没有返回的

var hexStr = ab2hex(device.advertisData);
console.log("广播数据中转换后:advertisData---->" + hexStr);  //0000365544332211

16进制转10进制 相加 取低字节

/**
 * 16进制转10进制 相加
 * 取低字节
 */
function hexToDec(hex) {
    let plusNum = 0;
    for (var i = 0; i < hex.length; i++) {
        let tempVal = parseInt(hex[i], 10); //注: 如字符串数组需写16
        // console.log('tempVal---->', tempVal)
        plusNum += tempVal;
    }
    console.log('相加的值是====>', plusNum);
    var hexStr = plusNum.toString(16);
    console.log("hexStr:" + hexStr);
    var s = "00" + hexStr;
    s = s.substr(s.length - 2, s.length); // 截取最后2位字符
    console.log('====截取低为数为:======>', s);
    return s;
}

Demo 根据传入不同的编号转换16进制, 再转10进制,计算和取低字节

ps: 不知道理解最低字节数是否正确, 有误请指点,谢谢

  • 假设 计算和: 483 转16进制 ===》1e3, 低字节为: e3
let nums = Number(currentSerialVal);
console.log('获取到编号:', nums); //nums = 10
nums = nums.toString(16); //转16进制 ==》a
nums = parseInt(nums, 16); //字符串转整数

// 16进制转10进制
let hex = [0xf7, 0x62, 0x03, 0x45, 0x38, nums];
// console.log(hex.map(String));
let toDec = utils.hexToDec(hex); //[247, 98, 3, 69, 56, 10]
toDec = parseInt(toDec, 16); //取最低字节转16进制   //得f6
hex.push(toDec); //[247, 98, 3, 88, 56, 10, 246]
console.log('=====发送数据为:=====》', hex);
writeData(hex); //写入数据

10进制转16进制不足位数补零

发送字节大于255, 当不足位数时前面补0

注意: 一个字节表示的最大的整数是255

例:控制时间指令为: [0xa1, 0x30, 0x00, 自定义时间n]

​ a. 发送时间30秒,即[0x0a, 0x30, 0x00, 0x1e]

​ b. 假设: 900秒,如何发送指令呢?

​ 【难道是这样发送数据:[0x0a, 0x30, 0x00, 0x384]正常是不可以的。】

大于255字节如何处理?

  • 假设: 900 转16进制后为 384, 那么我们把他拆分为两个字节发送就可以了。 即 【0x03, 0x84
let n = 900;	
n = n.toString(16);  // 将900转化为16进制数(以字符串显示)
var s = "00000000" + n;
s = s.substr(n.length, s.length); // 截取最后8位字符
let str1 = s.substring(4, 6);
str1 = '0x' + str1; //同等: str1 = str1.toString(16); 无需拼0x
let str2 = s.substring(6, 8);
str2 = str2.toString(16);;

var nS = parseInt(str1, 16) //字符串转16进制
var nE = parseInt(str2, 16)

var hex = [0xa1, 0x30, nS, nE];
writeData(hex);	 //写入数据

十六进制 转 十进制

/**
 * 十六进制 转 十进制
 */
const hexToDecimalism = (hexToDecimalism) => {
    var trimedStr = hexToDecimalism.trim();
    var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
    var len = rawStr.length;
    if (len % 2 !== 0) {
        console.log("存在非法字符!");
        return "";
    }
    var curCharCode;
    var resultStr = [];
    for (var i = 0; i < len; i = i + 2) {
        curCharCode = parseInt(rawStr.substr(i, 2), 16);
        resultStr.push(parseInt(curCharCode));
    }
    // console.log('转换后十进制:', resultStr);
    return resultStr;
}

Demo

let tempStr = 'f75838';
let tempResult = utils.hexToDecimalism(tempStr.substring(0, 6));
console.log('tempResult--->', tempResult);   //[247, 88, 56]

let tempStr = '0x58';
let tempResult = utils.hexToDecimalism(tempStr);
console.log('tempResult--->', tempResult);   //[88]

16进制转 ASCII

ASCII码对照表

单个值 转 ASCII

/**
 * 16进制转 ASCII
 */
const hexCharCodeToStr = (hexCharCodeStr) => {
    var trimedStr = hexCharCodeStr.trim();
    var rawStr = trimedStr.substr(0, 2).toLowerCase() === "0x" ? trimedStr.substr(2) : trimedStr;
    var len = rawStr.length;
    if (len % 2 !== 0) {
        console.log("存在非法字符!");
        return "";
    }
    var curCharCode;
    var resultStr = [];
    for (var i = 0; i < len; i = i + 2) {
        curCharCode = parseInt(rawStr.substr(i, 2), 16);
        resultStr.push(String.fromCharCode(curCharCode));
    }
    console.log('转换后ASCII:', resultStr);
    return resultStr.join("");
}

Demo

console.log(utils.hexCharCodeToStr('0x41')); // A
console.log(utils.hexCharCodeToStr('41')); // A

数组 转 ASCII

/**
 * 16进制数组转ASCII
 */
const hexArrToCharCode = (hexArr) => {
    var resultStr = [];
    for (var i = 0; i < hexArr.length; i++) {
        let toHex = hexArr[i].toString();
        resultStr.push(String.fromCharCode(toHex));
    }
    let toStr = resultStr.join().replace(/,/g, "");
    console.log('转ASCII值后----》', toStr);
    return toStr;
}

Demo

这里以0123456789ABCDEF字符进行转换

var hex1 = [0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46];
let toCharCode = utils.hexArrToCharCode(hex1);
console.log('转换后的值为', toCharCode); //0123456789ABCDEF

ASCII码转16进制

//ASCII码转16进制
function strToHexCharCode(str) {
    if (str === "") {
        return "";
    } else {
        var hexCharCode = [];
        hexCharCode.push("0x");
        for (var i = 0; i < str.length; i++) {
            hexCharCode.push((str.charCodeAt(i)).toString(16));
        }
        return hexCharCode.join("");
    }
}

前面自动补零

/**
 * 前面自动补零
 *  num传入的数字,n需要的字符长度
 */
function prefixZero(num, n) {
    return (Array(n).join(0) + num).slice(-n);
}


//方法二
const formatNumber = n => {
    n = n.toString()
    return n[1] ? n : '0' + n
}

demo

//方法一:
let result = utils.prefixZero(5, 2);
console.log('result-->', result);  //05


//方法二:
console.log(utils.formatNumber(6)) //06

数组值相加

/**
 * 数组 值相加
 */
function arrSum(arr) {
    var sum = 0;
    arr.forEach(function(val, i) {
        sum += val;
    });
    return sum;
}

三种数据之间转换案例

这是在开发蓝牙功能监听设备返回数据API获取的数据

微信小程序蓝牙BLE开发——关于进制转换(四)