当前位置:网站首页>小程序蓝牙连接低功耗设备(BLE)记录
小程序蓝牙连接低功耗设备(BLE)记录
2022-04-22 05:57:00 【招来红月】
第一步 查询是否授权蓝牙 授权后初始化蓝牙 获取本机蓝牙状态 开启监听蓝牙开启关闭事件 若不调用openBluetoothAdapter方法 下面无法进行
代码中bluetooth 为封装的一些公共方法 会写在最下面
bluetooth.getBluetoothSetting().then(() => {
//已授权 初始化蓝牙模块
wx.openBluetoothAdapter({
success: () => {},
fail: err => bluetooth.errorCodeToStr(err),
complete: () => {
wx.hideLoading()
this.setData({
bluetoothInit: true
})
// 获取本机蓝牙适配器状态。
wx.getBluetoothAdapterState().then(res => {
this.setData({
bluetoothAvailable: res.available,
})
}).catch(err => bluetooth.errorCodeToStr(err))
// 监听蓝牙适配器状态变化事件 是否开启蓝牙
wx.onBluetoothAdapterStateChange((res) => {
let page = getCurrentPages()
if (page[page.length - 1].route != 'pages/index/index') return
wx.showToast({
title: '蓝牙已' + (res.available ? '开启' : '关闭'),
icon: 'none'
})
this.setData({
bluetoothAvailable: res.available,
})
})
}
})
}).catch(err => {
wx.showToast({
title: err,
icon: 'none'
})
})
第二步 搜索低功耗蓝牙设备 和停止搜索 搜索到的设备添加到列表 点击列表选择想要连接的蓝牙设备 (列表点击事件没写 自己写就行)
let timer=null
// 开始搜索蓝牙设备 10秒后自动停止 也可以手动停止搜索
starSearch() {
wx.hideLoading()
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: false
}).then(res => {
this.setData({
status: 1
})
// 定时结束搜索
timer = setTimeout(() => {
this.stopSearch()
}, 10000)
}).catch(err => bluetooth.errorCodeToStr(err))
// 监听搜索到新设备的事件 添加到列表
wx.onBluetoothDeviceFound((res) => {
var devices = res.devices[0];
if (devices.name) {
this.setData({
list: [...this.data.list, devices]
})
}
})
},
// 停止搜索(可手动调用)
stopSearch() {
wx.hideLoading()
//清除计时器
clearTimeout(timer)
//取消监听寻找到新设备的事件
wx.offBluetoothDeviceFound()
//停止搜寻附近的蓝牙外围设备 判断设备数量做出提示
wx.stopBluetoothDevicesDiscovery().then(res => {
let status = (this.data.list.length < 1 ? 2 : 3)
this.setData({
status: status
})
if (status == 2) {
wx.showModal({
title: '提示',
content: '未检测到设备,请打开设备重试~',
showCancel: false
})
}
}).catch(err => bluetooth.errorCodeToStr(err))
},
第三步 创建蓝牙连接获取所需要deviceId(搜索到设备时获取) serviceId(isPrimary=true的那个uuid),characteristicId(这个是需要characteristics中 write为true时 为写入时需要用到的uuid 若需要监听上报信息 需要选择notify为true的uuid)就是个概念 具体参考官方文档结合自己控制台打印的去判断
当蓝牙连接成功后可以把蓝牙设备的数据 存到缓存或者别的位置 方便下次直接试用
原文:
createBLEConnection 连接蓝牙低功耗设备。
若小程序在之前已有搜索过某个蓝牙设备,并成功建立连接,可直接传入之前搜索获取的 deviceId 直接尝试连接该设备,无需再次进行搜索操作。
// 创建蓝牙连接
createMachineLink() {
// 连接前 断开与其他蓝牙低功耗设备的连接
wx.showLoading({
title: '连接中...',
mask: true
})
// 监听断开连接
wx.onBLEConnectionStateChange((res) => {
if (!res.connected)
this.setData({
isLink: res.connected,
})
})
wx.createBLEConnection({
deviceId: this.data.deviceId,
timeout: 5000,
}).then(() => {
// 获取蓝牙低功耗设备所有服务 (service)
wx.getBLEDeviceServices({
deviceId: this.data.deviceId
}).then(servicesData => {
this.setData({
serviceId: servicesData.services[0].uuid
}, () => {
// 获取蓝牙低功耗设备某个服务中所有特征 (characteristic)
wx.getBLEDeviceCharacteristics({
deviceId: this.data.deviceId,
serviceId: this.data.serviceId,
}).then(res => {
wx.setStorageSync('leaveStatus', 'link')
wx.showToast({
title: '连接成功',
})
this.setData({
isLink: true,
writeCharacteristicId: res.characteristics.find(item => item.properties.write == true).uuid,
notifyCharacteristicId: res.characteristics.find(item => item.properties.notify == true).uuid
}, () => this.notifyBluetoothListener())
}).catch(err => bluetooth.errorCodeToStr(err))
})
}).catch(err => bluetooth.errorCodeToStr(err))
}).catch(err => bluetooth.errorCodeToStr(err))
},
第四步 写入数据 我这里直接封装的方法 可以参考(这个是需要传入10字节 的16进制字符串)我这个只是参考
bluetooth.writeData(this.data.deviceId, this.data.serviceId, this.data.writeCharacteristicId, '044000')
//封装
// 写入数据
writeData(deviceId, serviceId, characteristicId, value) {
wx.writeBLECharacteristicValue({
deviceId,
serviceId,
characteristicId,
value: this.createBuffer(value),
}).then(res => {
setTimeout(() => {
wx.hideLoading()
}, 700)
}).catch(err => this.errorCodeToStr(err))
},
// 创建10位 0x00 16进制数据
createBuffer(num) {
let buffer = new ArrayBuffer(10);
let dataView = new DataView(buffer);
// 固定头
dataView.setUint8(0, 0x0D);
dataView.setUint8(1, 0x02);
// 固定头尾
dataView.setUint8(8, 0x0D);
dataView.setUint8(9, 0x03);
for (let i in num) {
dataView.setUint8(parseInt(i) + 2, ('0x' + num[i].charCodeAt().toString(16)));
}
return dataView.buffer
},
第五步 监听蓝牙上报信息 解码并做出相应处理
// 监听 设备上报
notifyBluetoothListener() {
wx.showLoading({
title: '获取状态中...',
mask: true
})
// 启用蓝牙低功耗设备特征值变化时的 notify 功能
wx.notifyBLECharacteristicValueChange({
state: true,
deviceId: this.data.deviceId,
serviceId: this.data.serviceId,
characteristicId: this.data.notifyCharacteristicId,
}).then(res => {
// 启用成功 下发指令 获取 设备状态
bluetooth.writeData(this.data.deviceId, this.data.serviceId, this.data.writeCharacteristicId, '018000')
}).catch(err => bluetooth.errorCodeToStr(err))
// 必须先启用 wx.notifyBLECharacteristicValueChange 才能监听到设备 characteristicValueChange 事件
wx.onBLECharacteristicValueChange((res) => {
setTimeout(() => {
this.setData({
writeType: false
})
}, 1000)
if (res.value.length >= 11) {
bluetooth.closeBLEConnection(this.data.deviceId)
wx.showToast({
title: '未知错误',
})
return
}
this.handleValueChange(bluetooth.ab2hex(res.value))
})
},
// 上报结果处理
handleValueChange(str) {
// 去除固定头固定尾
let hex = str.substring(4,str.length-4)
hex = bluetooth.hexCharCodeToStr(hex)
if (!hex) {
wx.showToast({
title: '未知错误',
})
return
}
let status = Number('0x' + (hex.substring(0, 2)))
if (!status) {
bluetooth.closeBLEConnection(this.data.deviceId)
wx.showToast({
title: '未知错误',
})
return
}
this.setData({
isRun: (status >> 6) & 1, //是否运行中
isHot: (status & 1), //加热
speed: (status >> 2) & 3, //速度
mode: (status >> 4) & 3, //模式
})
},
这里 封装的上面代码中所用的的方法
module.exports = {
// 创建10位 0x00 16进制数据
createBuffer(num) {
let buffer = new ArrayBuffer(10);
let dataView = new DataView(buffer);
// 固定头
dataView.setUint8(0, 0x0D);
dataView.setUint8(1, 0x02);
// 固定头尾
dataView.setUint8(8, 0x0D);
dataView.setUint8(9, 0x03);
for (let i in num) {
dataView.setUint8(parseInt(i) + 2, ('0x' + num[i].charCodeAt().toString(16)));
}
return dataView.buffer
},
// 写入数据
writeData(deviceId, serviceId, characteristicId, value) {
wx.writeBLECharacteristicValue({
deviceId,
serviceId,
characteristicId,
value: this.createBuffer(value),
}).then(res => {
setTimeout(() => {
wx.hideLoading()
}, 700)
}).catch(err => this.errorCodeToStr(err))
},
// 断开蓝牙连接
closeBLEConnection(deviceId, type) {
wx.closeBLEConnection({
deviceId: deviceId,
success: () => {
if (type)
wx.showToast({
title: '断开连接',
icon: 'none'
})
},
fail: err => this.errorCodeToStr(err, type)
})
},
//蓝牙授权查询
getBluetoothSetting() {
return new Promise((resolve, reject) => {
wx.getSetting().then(res => {
if (!res.authSetting['scope.bluetooth']) {
this.scopeBluetooth().then(data => {
resolve(data)
}).catch(err => reject(err))
} else {
resolve(res.authSetting)
}
}).catch(err => reject('getSetting error'))
})
},
//申请蓝牙授权
scopeBluetooth() {
return new Promise((resolve, reject) => {
wx.authorize({
scope: 'scope.bluetooth',
success(res) {
resolve(res)
},
fail(err) {
wx.showModal({
title: '提示',
content: '请授权蓝牙,以便使用设备',
success(res) {
if (res.cancel) {
reject('未授权蓝牙')
return
}
wx.openSetting({
success(data) {
if (data.authSetting['scope.bluetooth']) {
resolve(data.authSetting)
} else {
reject('未授权蓝牙')
}
}
})
}
})
}
})
})
},
// 蓝牙错误统一处理
errorCodeToStr(err, type) {
console.log(err)
if (!err.errCode) {
console.log(err.errMsg)
return
}
if (type) return
wx.showToast({
title: this.codeToStr[err.errCode],
icon: 'none'
})
},
codeToStr: {
"0": "正常",
"-1": "已连接",
"10000": "未初始化蓝牙适配器",
"10001": "当前蓝牙适配器不可用",
"10002": "没有找到指定设备",
"10003": "连接失败",
"10004": "没有找到指定服务",
"10005": "没有找到指定特征",
"10006": "当前连接已断开",
"10007": "当前特征不支持此操作",
"10008": "其余所有系统上报的异常",
"10009": "Android 系统特有,系统版本低于 4.3 不支持 BLE",
"10012": "连接超时",
"10013": "连接 deviceId 为空或者是格式不正确",
},
// ArrayBuffer转16进制字符串
ab2hex(buffer) {
let hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
},
// ArrayBuffer转16进制字符串转16进制数字
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) {
alert("存在非法字符!");
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));
}
return resultStr.join("");
},
}
此文章 只是大概记录 以便再次遇到类似项目能有些经验 希望能给看到这篇文章的人提供一些帮助
版权声明
本文为[招来红月]所创,转载请带上原文链接,感谢
https://blog.csdn.net/divpoxiao/article/details/124303070
边栏推荐
- PostgreSQL中Oid和Relfilenode的映射
- The digital risk control summit of digital America 2022 was opened, and the five highlights were exposed in advance
- Pgbouncer最佳实践:系列四
- 总结一下我使用过的定时器:@Scheduled注解
- 数美科技CTO梁堃建议:技术+运营组合防控 “杀猪盘”
- 使用@Autowired出现Field injection is not recommended
- Digital beauty technology won the "top ten intelligent risk control management innovation award" of the banker
- mysql5.7.x 数据授权导致1141
- Great! Kyushu cloud edge computing management platform has been certified by the national authority
- 浅谈流量限制
猜你喜欢

PostgreSQL中的MVCC 事务隔离

剑指offer:二叉树中和为某一值的路径(回溯)

COM in Wine(1)——COM基本概念

MySQL basics 2

开源数据库管理系统现在比商业产品更受欢迎

LeetCode 1547:切棍子的最小成本

从零开始学安卓(kotlin)五——UI

Copu helped Peking University Graduate open source public elective course - Open Source PostgreSQL R & D course successfully enter Peking University

Pgbouncer最佳实践:系列四

MySQL——索引
随机推荐
PostgreSQL中的MVCC 事务隔离
js对url进行编码和解码(三种方式区别)
PostgreSQL使用clickhousedb_fdw访问ClickHouse
logrus设置日志格式与输出函数名
js引擎的循环机制:同步,异步,事件循环
Escort · the future 𞓜 digital risk control summit of digital America 2022 officially set off
《信息系统项目管理师总结》第三章 项目进度管理
MySQL 实现行转列SQL
出海美利坚 不可忽视的未成年人法律红线
PostgreSQL 13.3, 12.7, 11.12, 10.17 and 9.6.22 have been released!
mysql5.7.x 数据授权导致1141
Solutions for minors protection in the social industry of digital beauty technology: guarding the "social circle" of minors
毕业设计碎碎念
kubectl命令自动补齐
Postgreshub中文资源网介绍
Open source database management systems are now more popular than commercial products
configmap
Multiple styles of scroll bars
MySQL Cluster Index
创新实训(五)中期检查