当前位置:网站首页>微信小程序蓝牙连接硬件设备并进行通讯,小程序蓝牙因距离异常断开自动重连,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]联系笔者删除。
笔者:苦海
边栏推荐
- 高级程序员必知必会,一文详解MySQL主从同步原理,推荐收藏
- Preliminary practice of niuke.com (9)
- Jhok-zbl1 leakage relay
- "Multimodal" concept
- 拼多多新店如何获取免费流量,需要从哪些环节去优化,才能有效提升店内免费流量
- 基于 hugging face 预训练模型的实体识别智能标注方案:生成doccano要求json格式
- 分布式事务介绍
- 论文阅读【MM21 Pre-training for Video Understanding Challenge:Video Captioning with Pretraining Techniqu】
- Sorry, I've learned a lesson
- nodejs获取客户端ip
猜你喜欢
How Alibaba cloud's DPCA architecture works | popular science diagram
实现网页内容可编辑
Egr-20uscm ground fault relay
Leakage relay jd1-100
Lombok plug-in
一条 update 语句的生命经历
Zhang Ping'an: accelerate cloud digital innovation and jointly build an industrial smart ecosystem
随机生成session_id
Intelligent annotation scheme of entity recognition based on hugging Face Pre training model: generate doccano request JSON format
Life experience of an update statement
随机推荐
Jhok-zbl1 leakage relay
Mapbox Chinese map address
Batch size setting skills
AIDL 与Service
When deleting a file, the prompt "the length of the source file name is greater than the length supported by the system" cannot be deleted. Solution
淘宝店铺发布API接口(新),淘宝oAuth2.0店铺商品API接口,淘宝商品发布API接口,淘宝商品上架API接口,一整套发布上架店铺接口对接分享
删除文件时提示‘源文件名长度大于系统支持的长度’无法删除解决办法
Phenomenon analysis when Autowired annotation is used for list
"Multimodal" concept
【Shell】清理nohup.out文件
Photo selector collectionview
Cve-2021-3156 vulnerability recurrence notes
Egr-20uscm ground fault relay
利用OPNET进行网络指定源组播(SSM)仿真的设计、配置及注意点
Paper reading [MM21 pre training for video understanding challenge:video captioning with pre training techniqu]
论文阅读【Semantic Tag Augmented XlanV Model for Video Captioning】
《4》 Form
随机生成session_id
MySQL数据库学习(7) -- pymysql简单介绍
4. Object mapping Mapster