当前位置:网站首页>微信小程序蓝牙连接硬件设备并进行通讯,小程序蓝牙因距离异常断开自动重连,js实现crc校验位
微信小程序蓝牙连接硬件设备并进行通讯,小程序蓝牙因距离异常断开自动重连,js实现crc校验位
2022-07-06 23:55:00 【苦海123】
一、小程序实现搜索蓝牙:
注意:comtl是我封装的工具函数,无关紧要,实际项目中可能用不到:
const comtl = require('../../utils/commontool')
const app = getApp() // 拿到全局定义的变量,需要在app.js中:App({globalData: { params: ''}}),params为全局变量名
let timerid = 0 // 定时器id
Page({
data: {
datas:[], // 所有蓝牙数据
deviceId:'', // 蓝牙设备 id
bluename:'', // 蓝牙设备 name
serviceuuid:'', // 选中蓝牙设备的服务uuid截取字符串
serviceId:'', // 服务id ,uuid
characteristicNotifyId:'', // 读数据的特征值id
characteristicWriteId:'', // 写数据的特征值id
timerStat:true
},
searchDevice: function() {
// 蓝牙初始化
clearInterval(timerid)
wx.vibrateShort()
let _this = this
let arr = []
this.setData({
datas:arr
})
wx.openBluetoothAdapter({
success: function(res) {
_this.getBluetoothState()
},
fail: function(res) {
comtl.toast('蓝牙初始化失败','error',2000)
}
})
},
getBluetoothState: function() {
// 获取本地蓝牙适配器状态
let _this = this
wx.getBluetoothAdapterState({
success: function(res) {
_this.findBleDevices()
},
fail: function(e) {
comtl.toast('获取本机蓝牙适配器状态失败','error',2000)
}
})
},
findBleDevices: function() {
// 搜索蓝牙
comtl.openloading('搜索蓝牙...',false)
let _this = this
wx.startBluetoothDevicesDiscovery({
success: function(res) {
_this.onBluetoothDeviceFound()
},
fail: function(res) {
comtl.toast('搜索蓝牙失败','error',2000)
}
})
},
onBluetoothDeviceFound: function() {
// 监听搜索到新设备的事件
let _this = this
wx.onBluetoothDeviceFound(function(res) {
_this.getBluetoothDevices()
})
},
getBluetoothDevices: function() {
let _this = this
wx.getBluetoothDevices({
//获取在蓝牙模块生效期间所有搜索到的蓝牙设备,包括已经和本机处于连接状态的设备
success: function(res) {
_this.setData({
datas:res.devices
})
},
fail: function(res) {
comtl.toast('获取蓝牙设备失败','error',2000)
}
})
},
clickBlueToolHandle: function(e) {
wx.vibrateShort()
let _this = this
wx.closeBLEConnection({
// 断开与蓝牙低功耗设备的连接
deviceId:_this.data.deviceId
})
wx.stopBluetoothDevicesDiscovery() //停止搜寻附近的蓝牙外围设备
if(e){
let deviceId = e.currentTarget.dataset.deid;
let bluename = e.currentTarget.dataset.bluename;
let serviceuuid = e.currentTarget.dataset.serviceuuid;
this.setData({
deviceId:deviceId,
bluename:bluename,
serviceuuid:serviceuuid
})
}
//蓝牙连接
wx.createBLEConnection({
// 连接与蓝牙低功耗设备的连接
deviceId: _this.data.deviceId,
timeout:5000,
success: function(res) {
clearInterval(timerid)
_this.stopBluetooth() //停止搜索
_this.monitorIsBreak();
_this.getBLEDeviceServices(); //获取服务
},
fail: function(res) {
wx.hideLoading()
comtl.toast('连接低功耗蓝牙失败','error',2000)
},
complete: function (){
comtl.toast('不支持','error',2000)
}
})
},
monitorIsBreak(){
// 监听异常断开
let _this = this
wx.onBLEConnectionStateChange(function(res) {
if(!res.connected) {
// 判断是否为断开连接
_this.timerConnect()// 开启定时器
wx.vibrateLong()
comtl.toast('蓝牙已断开','error',5000)
_this.setData({
timerStat:false
})
}else{
_this.setData({
timerStat:true
})
}
})
},
stopBluetooth() {
//停止蓝牙搜索
wx.stopBluetoothDevicesDiscovery({
success: function(res) {
comtl.closeloading() // 关闭停止搜索遮挡层
comtl.toast('停止蓝牙搜索','success',2000)
},
fail: function(res) {
comtl.toast('停止蓝牙搜索失败','error',2000)
}
})
},
getBLEDeviceServices: function() {
//获取蓝牙低功耗设备所有服务uuid
let services = [];
let _this = this;
wx.getBLEDeviceServices({
deviceId: _this.data.deviceId,
success: function(res) {
services = res.services
if (services.length <= 0) {
comtl.toast('没有服务','error',2000)
return
}
//循环获取serviceId
for (let x in services) {
//x = index
if (services[x].uuid.indexOf(_this.data.serviceuuid) >= 0) {
//找到有效的UUID
_this.setData({
serviceId:services[x].uuid
})
_this.getBLEDeviceCharacteristics()
break
}
}
},
fail: function(res) {
comtl.toast('获取设备服务失败','error',2000)
}
})
},
getBLEDeviceCharacteristics: function() {
//获取蓝牙低功耗设备某个服务中所有特征
let charactArray = [];
let _this = this;
wx.getBLEDeviceCharacteristics({
deviceId: this.data.deviceId,
serviceId: this.data.serviceId, // 这个是上面那个UUID
success: function(res) {
charactArray = res.characteristics;
if (charactArray.length <= 0) {
comtl.toast('获取特征值失败','error',2000)
return
}
//charactArray 也就是 res.characteristics 这个里面有能读数据的 能写数据的 要分着用
for (var x in charactArray) {
//写数据
if (charactArray[x].properties.write) {
_this.setData({
characteristicWriteId:charactArray[x].uuid
})
}
//读数据
if (charactArray[x].properties.notify) {
_this.setData({
characteristicNotifyId:charactArray[x].uuid
})
}
}
app.params = _this.data
wx.switchTab({
url: '../home/home'
})
},
fail: function(res) {
comtl.toast('蓝牙不支持','error',2000)
}
})
},
onShareAppMessage: function(res) {
return {
title: 'F3000X',
path: 'pages/searchbuletool/searchbuletool',
success: function(res) {
}
}
},
onShow(){
clearInterval(timerid)
},
timerConnect(){
//定时器自动重新连接(因距离导致断开重新连接)
let _this = this
if (_this.data.timerStat) {
timerid = setInterval(()=>{
_this.clickBlueToolHandle()
},5000)
}
}
})
二、连接某蓝牙设备
将datas:[]中的蓝牙数据遍历渲染到某个wxml页面上,点击某个设备的数据即可连接,需要注意的是,你自己的小程序需要支持某蓝牙设备,不然即使连接上蓝牙也无法操作设备,如:
const comtl = require('../../utils/commontool')
const app = getApp()
let dataString = ''
Page({
data: {
datas:[], // 所有蓝牙数据
deviceId:'', // 蓝牙设备 id
bluename:'', // 蓝牙设备 name
serviceuuid:'', // 选中蓝牙设备的服务uuid截取字符串
serviceId:'', // 服务id ,uuid
characteristicNotifyId:'', // 读数据的特征值id
characteristicWriteId:'', // 写数据的特征值id
domdatas:{
}, // 页面数值数据
domunit:{
}, // 页面单位数据
transdat:'', //转换后的值
transdat1:'', //转换后的值
transdat2:'', //转换后的值
timerId:0, // 定时器id
isGoRest:false
},
onLoad() {
let isExist = wx.getStorageSync('history')
if(isExist === '' || isExist === undefined){
wx.setStorageSync('history',[])
}
},
redatat: function(dt) {
// 读数据开始
if(dt.BtchFlowCount){
this.setData({
domdatas:dt,
transdat: this.filter(this.data.domdatas.ReadyConst,this.data.domunit.dotted),
transdat1: this.filter(this.data.domdatas.MinutFlowCount,this.data.domunit.dotted),
transdat2: this.filter(this.data.domdatas.BtchFlowCount,this.data.domunit.dotted)
})
}else if(dt.dotted){
this.setData({
domunit:dt
})
}
let _this = this
wx.notifyBLECharacteristicValueChange({
deviceId: this.data.deviceId,
serviceId: this.data.serviceId,
characteristicId: this.data.characteristicNotifyId,
state: true,
success: function(res) {
_this.onBLECharacteristicValueChange();
}
})
dataString = ''
},
onBLECharacteristicValueChange: function() {
// 监听蓝牙特征值变化
wx.onBLECharacteristicValueChange(function(res) {
dataString += comtl.ab2hex(res.value)
})
},
writedata: function(hex) {
// 写数据
wx.writeBLECharacteristicValue({
deviceId: this.data.deviceId,
serviceId: this.data.serviceId,
characteristicId: this.data.characteristicWriteId,
value: comtl.str2ab(hex),
success: function(res) {
},
fail: function(res) {
}
})
},
startTimer(){
// 定时获取数据:
let ids = setInterval(()=>{
this.readUnit()
},100)
setTimeout(()=>{
clearInterval(ids)
},800)
let timerid = setInterval(()=>{
this.readData()
},1000)
this.setData({
timerId:timerid
})
},
readData(){
// 读数值数据:
let domdat = comtl.transformData(dataString)
this.redatat(domdat)
this.writedata('01030001001E9402')
},
readUnit(){
// 读单位:
let domdat = comtl.transformUnit(dataString)
this.redatat(domdat)
this.writedata('01035003000624C8')
},
starttap(){
wx.vibrateShort()
this.writedata('011020070001020014862A')
setTimeout(()=>{
if(this.data.domdatas.OperatStat == '运行中'){
comtl.toast('运行成功','success',200)
}
},1000)
this.setData({
isGoRest:false
})
},
stoptap(){
wx.vibrateShort()
this.writedata('01102007000102001547EA')
setTimeout(()=>{
if(this.data.domdatas.OperatStat == '暂停'){
comtl.toast('暂停成功','success',2000)
}
},1000)
this.setData({
isGoRest:false
})
},
resettap(){
wx.vibrateShort()
this.writedata('01102007000102001E062D')
setTimeout(()=>{
if(this.data.domdatas.OperatStat == '结束'){
comtl.toast('结束成功','success',2000)
}
},1000)
this.setData({
isGoRest:true
})
},
gosetvaluepage() {
// 跳转到修改定量值页面
wx.vibrateShort()
if (this.data.isGoRest) {
wx.navigateTo({
url: '../setvalue/setvalue?showvalue='+this.data.transdat+'&dotte='+this.data.domunit.dotted
})
}else{
comtl.toast('请先结束','error',2000)
}
},
filter(num,d){
// 处理小数点
let nums = num + ''
let ds = Number(d)
let indexdot = nums.indexOf('.')
if(indexdot == -1){
nums += '.000000000'
indexdot = nums.indexOf('.')
}else{
nums += '000000000'
}
let lastnum = parseInt(nums.slice((indexdot + ds +1),(indexdot + ds + 2)))
let secondlast = parseInt(nums.slice((indexdot + ds),(indexdot + ds + 1)))
if (!secondlast && secondlast != 0){
return nums.slice(0,indexdot)
}else {
if (lastnum >= 5){
return nums.slice(0,(indexdot + ds)) + (secondlast + 1)
} else {
return nums.slice(0,indexdot + ds +1)
}
}
},
onShow(){
if (app.params) {
this.setData({
deviceId:app.params.deviceId,
bluename:app.params.bluename,
serviceuuid:app.params.serviceuuid,
serviceId:app.params.serviceId,
characteristicNotifyId:app.params.characteristicNotifyId,
characteristicWriteId:app.params.characteristicWriteId
})
}
this.startTimer()
},
onHide(){
clearInterval(this.data.timerId)
}
})
三、数据读写
蓝牙读写数据和tcp等都类似,都需要先发送东西给设备(服务),而小程序中则称为订阅,每次读写数据都需要发送指令,可能指令中还会包含计算校验位等等,不明白的可以百度一下,这里我不做过多解释,如下:
const app = getApp()
const crc = require('../../utils/crc.js')
const comtl = require('../../utils/commontool')
Page({
data: {
keybordshow:true,
showvalue:'',
inputvale:'',
deviceId:'',
bluename:'',
serviceuuid:'',
serviceId:'',
characteristicNotifyId:'',
characteristicWriteId:'',
dotte:'',
historys:[]
},
onLoad(options) {
let history = wx.getStorageSync('history')
this.setData({
historys:history,
showvalue:options.showvalue,
dotte:options.dotte
})
if (app.params) {
this.setData({
deviceId:app.params.deviceId,
bluename:app.params.bluename,
serviceuuid:app.params.serviceuuid,
serviceId:app.params.serviceId,
characteristicNotifyId:app.params.characteristicNotifyId,
characteristicWriteId:app.params.characteristicWriteId
})
}
},
transforminputvalue(num,d){
let e = Number(num)
switch(d){
case '0':
e = e*1 + '';
break;
case '1':
e = e*10 + '';
break;
case '2':
e = e*100 + '';
break;
case '3':
e = e*1000 + '';
break;
default:
e = e + '';
break;
}
let nd = e.indexOf('.')
if (nd >=0){
let str = e.slice(0,e.indexOf('.'))
return parseInt(str)
} else {
return e
}
},
inputChangeHalder(e){
this.setData({
inputvale:e.detail.value
})
},
writein(){
wx.vibrateShort()
let _this = this
this.setData({
keybordshow:true,
})
wx.writeBLECharacteristicValue({
deviceId: this.data.deviceId,
serviceId: this.data.serviceId,
characteristicId: this.data.characteristicWriteId,
value: crc(_this.transforminputvalue(_this.data.inputvale,_this.data.dotte),'01102005000204'),
success: function(res) {
comtl.toast('成功','success',2000)
let newhistarr = _this.data.historys.concat(_this.data.inputvale)
newhistarr = [...new Set(newhistarr.map(it => it))]
if(newhistarr.length >= 8){
newhistarr = newhistarr.splice(1, 9)
}
wx.setStorageSync('history',newhistarr)
_this.setData({
historys:newhistarr
})
console.log(_this.data.historys)
wx.switchTab({
url: '../home/home'
})
},
fail: function(res) {
console.log("发送指令失败:")
}
})
},
gobackhome(){
wx.vibrateShort()
wx.switchTab({
url: '../home/home'
})
},
restInputvalue(el){
wx.vibrateShort()
var newvalue = el.currentTarget.dataset.newvalue;
this.setData({
inputvale:newvalue
})
}
})
计算校验位:
// crc校验输出:
module.exports = (inputNumber,joinTempStr)=>{
// let inputNumber = 0103011215,要输入的值:(需要转换的值)
// let joinTempStr = 011001030002,需要拼接的值
// 将用户输入字符转:单精度浮点数:
let flownum = parseFloat(inputNumber)
// 浮点转16进制:
let hexstr = flownum.toString(16)
let count = 8 - hexstr.length
if (count > 0) {
let zeronum = ''
for(let i = 0;i < count;i++){
zeronum += '0'
}
hexstr = zeronum + hexstr
}
// 进行拼接:
let temphex = joinTempStr + hexstr
// 算crc校验位的方法:
function returnCRC(parapms){
var CRC = {
};
CRC._auchCRCHi = [
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40, 0x00, 0xC1, 0x81, 0x40,
0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0, 0x80, 0x41, 0x00, 0xC1,
0x81, 0x40, 0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41,
0x00, 0xC1, 0x81, 0x40, 0x01, 0xC0, 0x80, 0x41, 0x01, 0xC0,
0x80, 0x41, 0x00, 0xC1, 0x81, 0x40
];
CRC._auchCRCLo = [
0x00, 0xC0, 0xC1, 0x01, 0xC3, 0x03, 0x02, 0xC2, 0xC6, 0x06,
0x07, 0xC7, 0x05, 0xC5, 0xC4, 0x04, 0xCC, 0x0C, 0x0D, 0xCD,
0x0F, 0xCF, 0xCE, 0x0E, 0x0A, 0xCA, 0xCB, 0x0B, 0xC9, 0x09,
0x08, 0xC8, 0xD8, 0x18, 0x19, 0xD9, 0x1B, 0xDB, 0xDA, 0x1A,
0x1E, 0xDE, 0xDF, 0x1F, 0xDD, 0x1D, 0x1C, 0xDC, 0x14, 0xD4,
0xD5, 0x15, 0xD7, 0x17, 0x16, 0xD6, 0xD2, 0x12, 0x13, 0xD3,
0x11, 0xD1, 0xD0, 0x10, 0xF0, 0x30, 0x31, 0xF1, 0x33, 0xF3,
0xF2, 0x32, 0x36, 0xF6, 0xF7, 0x37, 0xF5, 0x35, 0x34, 0xF4,
0x3C, 0xFC, 0xFD, 0x3D, 0xFF, 0x3F, 0x3E, 0xFE, 0xFA, 0x3A,
0x3B, 0xFB, 0x39, 0xF9, 0xF8, 0x38, 0x28, 0xE8, 0xE9, 0x29,
0xEB, 0x2B, 0x2A, 0xEA, 0xEE, 0x2E, 0x2F, 0xEF, 0x2D, 0xED,
0xEC, 0x2C, 0xE4, 0x24, 0x25, 0xE5, 0x27, 0xE7, 0xE6, 0x26,
0x22, 0xE2, 0xE3, 0x23, 0xE1, 0x21, 0x20, 0xE0, 0xA0, 0x60,
0x61, 0xA1, 0x63, 0xA3, 0xA2, 0x62, 0x66, 0xA6, 0xA7, 0x67,
0xA5, 0x65, 0x64, 0xA4, 0x6C, 0xAC, 0xAD, 0x6D, 0xAF, 0x6F,
0x6E, 0xAE, 0xAA, 0x6A, 0x6B, 0xAB, 0x69, 0xA9, 0xA8, 0x68,
0x78, 0xB8, 0xB9, 0x79, 0xBB, 0x7B, 0x7A, 0xBA, 0xBE, 0x7E,
0x7F, 0xBF, 0x7D, 0xBD, 0xBC, 0x7C, 0xB4, 0x74, 0x75, 0xB5,
0x77, 0xB7, 0xB6, 0x76, 0x72, 0xB2, 0xB3, 0x73, 0xB1, 0x71,
0x70, 0xB0, 0x50, 0x90, 0x91, 0x51, 0x93, 0x53, 0x52, 0x92,
0x96, 0x56, 0x57, 0x97, 0x55, 0x95, 0x94, 0x54, 0x9C, 0x5C,
0x5D, 0x9D, 0x5F, 0x9F, 0x9E, 0x5E, 0x5A, 0x9A, 0x9B, 0x5B,
0x99, 0x59, 0x58, 0x98, 0x88, 0x48, 0x49, 0x89, 0x4B, 0x8B,
0x8A, 0x4A, 0x4E, 0x8E, 0x8F, 0x4F, 0x8D, 0x4D, 0x4C, 0x8C,
0x44, 0x84, 0x85, 0x45, 0x87, 0x47, 0x46, 0x86, 0x82, 0x42,
0x43, 0x83, 0x41, 0x81, 0x80, 0x40
];
CRC.CRC16 = function (buffer) {
var hi = 0xff;
var lo = 0xff;
for (var i = 0; i < buffer.length; i++) {
var idx = hi ^ buffer[i];
hi = (lo ^ CRC._auchCRCHi[idx]);
lo = CRC._auchCRCLo[idx];
}
return CRC.padLeft((hi << 8 | lo ).toString(16).toUpperCase(), 4, '0');
};
CRC.isArray = function (arr) {
return Object.prototype.toString.call(arr) === '[object Array]';
};
CRC.ToCRC16 = function (str) {
return CRC.CRC16(CRC.isArray(str) ? str : CRC.strToByte(str));
};
CRC.ToModbusCRC16 = function (str) {
return CRC.CRC16(CRC.isArray(str) ? str : CRC.strToHex(str));
};
CRC.strToByte = function (str) {
var tmp = str.split(''), arr = [];
for (var i = 0, c = tmp.length; i < c; i++) {
var j = encodeURI(tmp[i]);
if (j.length == 1) {
arr.push(j.charCodeAt());
} else {
var b = j.split('%');
for (var m = 1; m < b.length; m++) {
arr.push(parseInt('0x' + b[m]));
}
}
}
return arr;
};
CRC.convertChinese = function (str) {
var tmp = str.split(''), arr = [];
for (var i = 0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s <= 0 || s >= 127) {
arr.push(s.toString(16));
}
else {
arr.push(tmp[i]);
}
}
return arr;
};
CRC.filterChinese = function (str) {
var tmp = str.split(''), arr = [];
for (var i = 0, c = tmp.length; i < c; i++) {
var s = tmp[i].charCodeAt();
if (s > 0 && s < 127) {
arr.push(tmp[i]);
}
}
return arr;
};
CRC.strToHex = function (hex, isFilterChinese) {
hex = isFilterChinese ? CRC.filterChinese(hex).join('') : CRC.convertChinese(hex).join('');
//清除所有空格
hex = hex.replace(/\s/g, "");
//若字符个数为奇数,补一个空格
hex += hex.length % 2 != 0 ? " " : "";
var c = hex.length / 2, arr = [];
for (var i = 0; i < c; i++) {
arr.push(parseInt(hex.substr(i * 2, 2), 16));
}
return arr;
};
CRC.padLeft = function (s, w, pc) {
if (pc == undefined) {
pc = '0';
}
for (var i = 0, c = w - s.length; i < c; i++) {
s = pc + s;
}
return s;
};
return CRC.ToModbusCRC16(parapms)
}
// 调用crc校验方法进行校验计算:
let crcResult = returnCRC(temphex)
// 二次拼接:
let twoJoinStr = temphex + crcResult
// 转Buffer:
function strToBuffer(str) {
var buf = new ArrayBuffer(str.length / 2);
var bufView = new Uint8Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = parseInt(str.slice(i * 2, i * 2 + 2),16);
}
return buf;
}
return strToBuffer(twoJoinStr);
}
封装的comtl工具:
// 存放公共的方法:
module.exports = {
// 消息提示框:
"toast": (title,icon,duration) => {
wx.showToast({
title,
icon,
duration
})
},
// 开启loading:
"openloading": (title,mask) => {
wx.showLoading({
title,
mask
})
},
// 关闭loading:
"closeloading": () => {
wx.hideLoading()
},
transformData(totalstr){
// 转换数值类型(解析数值类型)
let datatobj = {
}
// console.log("温度值:"+this.hexToSingle(totalstr.slice(30,38)))
// console.log("流量批累计:"+this.hexToSingle(totalstr.slice(86,94)))
// console.log("流量分累计:"+this.hexToSingle(totalstr.slice(94,102)))
// console.log("预发定量值:"+this.hexToSingle(totalstr.slice(102,110)))
// console.log("运行状态:"+parseInt(totalstr.slice(118,122),16))
// console.log("分量数:"+this.hex2dex(totalstr.slice(110,114)))
// console.log("批量数:"+this.hex2dex(totalstr.slice(114,118)))
datatobj.MinutFlowCount = this.hexToSingle(totalstr.slice(94,102))
datatobj.BtchFlowCount = this.hexToSingle(totalstr.slice(86,94))
datatobj.PiCount = this.hex2dex(totalstr.slice(114,118))
datatobj.MinutCount = this.hex2dex(totalstr.slice(110,114))
datatobj.ReadyConst = this.hexToSingle(totalstr.slice(102,110))
switch(parseInt(totalstr.slice(118,122),16)){
case 0:
datatobj.OperatStat='结束';
break;
case 1:
datatobj.OperatStat='暂停';
break;
case 2:
datatobj.OperatStat='本次已完成';
break;
case 3:
datatobj.OperatStat='运行中';
break;
}
return datatobj
},
transformUnit(totalstr){
// 转换单位(解析单位)
let dtunit = {
}
dtunit.dotted = this.hex2dex(totalstr.slice(26,30))
switch(this.hex2dex(totalstr.slice(6,10))){
case '2':
dtunit.unit='m³';
break;
case '5':
dtunit.unit='kg';
break;
case '8':
dtunit.unit='L';
break;
case '11':
dtunit.unit='t';
break;
case '41':
dtunit.unit='mL';
break;
}
return dtunit
},
ab2hex(buffer){
// ArrayBuffer转16进度字符串
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
},
str2ab(str){
// 字符串转为ArrayBuffer对象
let buf = new ArrayBuffer(str.length / 2);
let bufView = new Uint8Array(buf);
for (var i = 0, strLen = str.length; i < strLen; i++) {
bufView[i] = parseInt(str.slice(i * 2, i * 2 + 2),16);
}
return buf;
},
hexToSingle(t) {
// 十六进制转浮点
let start = t.slice(0,4)
let end = t.slice(4,8)
t = end + start
t = t.replace(/\s+/g, "");
if (t == "") {
return "";
}
if (t == "00000000") {
return "0";
}
if ((t.length > 8) || (isNaN(parseInt(t, 16)))) {
return "Error";
}
if (t.length < 8) {
t = this.FillString(t, "0", 8, true);
}
t = parseInt(t, 16).toString(2);
t = this.FillString(t, "0", 32, true);
var s = t.substring(0, 1);
var e = t.substring(1, 9);
var m = t.substring(9);
e = parseInt(e, 2) - 127;
m = "1" + m;
if (e >= 0) {
m = m.substr(0, e + 1) + "." + m.substring(e + 1)
} else {
m = "0." + this.FillString(m, "0", m.length - e - 1, true)
}
if (m.indexOf(".") == -1) {
m = m + ".0";
}
var a = m.split(".");
var mi = parseInt(a[0], 2);
var mf = 0;
for (var i = 0; i < a[1].length; i++) {
mf += parseFloat(a[1].charAt(i)) * Math.pow(2, -(i + 1));
}
m = parseInt(mi) + parseFloat(mf);
if (s == 1) {
m = 0 - m;
}
return m;
},
FillString(t, c, n, b) {
if ((t == "") || (c.length != 1) || (n <= t.length)) {
return t;
}
var l = t.length;
for (var i = 0; i < n - l; i++) {
if (b == true) {
t = c + t;
}
else {
t += c;
}
}
return t;
},
hex2dex (str) {
// 调用:16进制转10进制
return parseInt(str, 16).toString(10)
}
}
提示:本文图片等素材来源于网络,若有侵权,请发邮件至邮箱:[email protected]联系笔者删除。
笔者:苦海
边栏推荐
- Mybaits multi table query (joint query, nested query)
- Most commonly used high number formula
- Taobao commodity details page API interface, Taobao commodity list API interface, Taobao commodity sales API interface, Taobao app details API interface, Taobao details API interface
- 论文阅读【Semantic Tag Augmented XlanV Model for Video Captioning】
- SQL query: subtract the previous row from the next row and make corresponding calculations
- 淘宝店铺发布API接口(新),淘宝oAuth2.0店铺商品API接口,淘宝商品发布API接口,淘宝商品上架API接口,一整套发布上架店铺接口对接分享
- In memory, I moved from CSDN to blog park!
- 论文阅读【Sensor-Augmented Egocentric-Video Captioning with Dynamic Modal Attention】
- Talk about mvcc multi version concurrency controller?
- 实现网页内容可编辑
猜你喜欢
What is dependency injection (DI)
Mysql database learning (8) -- MySQL content supplement
《4》 Form
[binary tree] binary tree path finding
消息队列:消息积压如何处理?
【js组件】自定义select
JVM (19) -- bytecode and class loading (4) -- talk about class loader again
[论文阅读] A Multi-branch Hybrid Transformer Network for Corneal Endothelial Cell Segmentation
SQL query: subtract the previous row from the next row and make corresponding calculations
高级程序员必知必会,一文详解MySQL主从同步原理,推荐收藏
随机推荐
Reading the paper [sensor enlarged egocentric video captioning with dynamic modal attention]
拼多多商品详情接口、拼多多商品基本信息、拼多多商品属性接口
Leetcode: maximum number of "balloons"
How can project managers counter attack with NPDP certificates? Look here
Codeforces Round #416 (Div. 2) D. Vladik and Favorite Game
Web Authentication API兼容版本信息
LabVIEW is opening a new reference, indicating that the memory is full
C#可空类型
阿里云的神龙架构是怎么工作的 | 科普图解
Mysql database learning (7) -- a brief introduction to pymysql
The 2022 China low / no code Market Research and model selection evaluation report was released
[JS component] date display.
Photo selector collectionview
【js组件】date日期显示。
AI face editor makes Lena smile
Taobao Commodity details page API interface, Taobao Commodity List API interface, Taobao Commodity sales API interface, Taobao app details API interface, Taobao details API interface
TabLayout修改自定义的Tab标题不生效问题
Annotation初体验
Vector and class copy constructors
消息队列:重复消息如何处理?