目前是蓝牙已经连接上了,
传输数据和notify都是成功了,
发送指令给设备,设备开始执行但是收不到返回数据,我用蓝牙宝测试设备应该是没问题的
<template>
<view class="content">
<view class="">
<button type="primary" @click="getlylist">搜索蓝牙设备</button>
</view>
<view class="fxitem">
<view class="box" v-for="(item,i) in list" :key="i">
<view class="">
MAC地址:{{item.deviceId}}
</view>
<view class="">
设备名称:{{item.name}}
</view>
<view class="textr">
<text style="color: #007aff;" @click="createBLEConnection(item.deviceId)">链接蓝牙设备</text>
</view>
</view>
</view>
<view class="">
返回:{{resdata}}
</view>
<view class="flex">
<button @click="wrtie"> 发送连接 </button>
<button @click="readBLECharacteristicValue"> 读取数据 </button>
</view>
</view>
</template>
<script>
export default {
data() {
return {
isOpenBle: false, //蓝牙状态
list: [], //设备列表
deviceId: "", //设备ID
serviceId: "", //服务ID
tzId: {
//支持写入操作的特征值
writeId: "",
//支持notify操作的特征值
notifyId: "",
//支持readId
readId: ""
},
//写入操作
write: {
//终端向血压计发送连接指令
ljzl: "cc80020301010001",
//终端向血压计发送启动指令
qdzl: "cc80020301020002",
//停止测量
tzzl: "cc80020301030003",
//查询电量
dlzl: "cc80020304040001"
},
resdata: "未获取到返回数据"
}
},
onLoad() {
//初始化蓝牙
this.init();
this.onBLEConnectionStateChange();
},
methods: {
wrtie() {
this.writeStr(this.write.ljzl).then(() => {
console.log("2S后启动")
setTimeout(() => {
this.writeStr(this.write.qdzl).then(() => {
console.log("10S后停止")
setTimeout(() => {
this.writeStr(this.write.tzzl).then(() => {
console.log("2s后查询电量")
setTimeout(() => {
this.writeStr(this.write.dlzl)
}, 2000)
})
}, 10000)
})
}, 2000)
})
},
init() {
//初始化蓝牙
uni.openBluetoothAdapter({
success: e => {
//在页面显示的时候判断是都已经初始化完成蓝牙适配器若成功,则开始查找设备
this.isOpenBle = true;
},
fail: e => {
uni.showModal({
title: "提示",
content: "蓝牙初始化失败,请打开手机蓝牙功能" + (e.errCode || e.errMsg),
confirmText: "重新启动",
success: res => {
if (res.confirm) {
this.init();
}
}
})
}
});
},
//获取蓝牙设备
getlylist() {
var _this = this;
uni.startBluetoothDevicesDiscovery({
success: res => {
console.log("蓝牙开启成功,搜索蓝牙设备!")
_this.onBluetoothDeviceFound();
},
fail: res => {
uni.showToast({
icon: "none",
title: "查找设备失败!",
duration: 2000
})
}
});
},
onBluetoothDeviceFound() {
//发现外围设备
uni.onBluetoothDeviceFound(devices => {
this.getBluetoothDevices();
});
},
stopBluetoothDevicesDiscovery() {
// 关闭蓝牙搜索
uni.stopBluetoothDevicesDiscovery({
success: e => {
console.log('停止搜索蓝牙设备:' + e.errMsg);
},
fail: e => {
console.log('停止搜索蓝牙设备失败,错误码:' + e.errCode);
}
});
},
getBluetoothDevices() {
//获取在蓝牙模块生效期间所有已发现的蓝牙设备
uni.getBluetoothDevices({
success: res => {
res = res.devices;
var bluelist = [];
//去除没有名字的蓝牙设备
res.forEach(item => {
item.data = this.ab2hex(item.advertisData);
if (item.name) {
bluelist.push(item)
}
})
this.list = bluelist;
}
});
},
ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
},
//断开蓝牙连接
closeBLEConnection(deviceId) {
uni.closeBLEConnection({
deviceId: deviceId,
success: res => {}
})
},
// 连接蓝牙设备
createBLEConnection(deviceId) {
this.deviceId = deviceId;
uni.createBLEConnection({
deviceId: this.deviceId,
success: res => {
this.stopBluetoothDevicesDiscovery();
this.getBLEDeviceServices(this.deviceId);
},
fail: res => {
uni.showToast({
icon: "none",
title: "链接蓝牙失败!",
duration: 3000
})
}
})
},
//获取蓝牙设备所有服务(service)。
getBLEDeviceServices(deviceId) {
setTimeout(() => {
uni.getBLEDeviceServices({
deviceId: deviceId,
success: (res) => {
console.log('服务', res)
//链接主服务ID
res.services.forEach((item, index) => {
// if (index == 2) {
// this.serviceId = item.uuid;
// this.getBLEDeviceCharacteristics(this.deviceId)
// }
if (item.uuid.indexOf("FFF0") != -1) {
this.serviceId = item.uuid;
this.onBLECharacteristicValueChange();
this.getBLEDeviceCharacteristics(this.deviceId)
}
})
},
fail: (res) => {
console.log("蓝牙服务获取失败:", res)
}
})
}, 1000)
},
// 获取蓝牙特征值
getBLEDeviceCharacteristics(deviceId) {
setTimeout(() => {
uni.getBLEDeviceCharacteristics({
deviceId: deviceId,
serviceId: this.serviceId,
success: (res) => {
console.log("特征", res)
res.characteristics.forEach((item) => {
// 获取notifyId权限
if (item.properties.notify || item.properties.indicate) {
this.tzId.notifyId = item.uuid;
this.notifyBLECharacteristicValueChange(this.deviceId)
}
// 获取notifyId发送权限
if (item.properties.write) {
this.tzId.writeId = item.uuid;
}
// 获取read发送权限
if (item.properties.read) {
this.tzId.readId = item.uuid;
}
})
},
fail: (res) => {
console.log(res)
}
})
}, 1000)
},
// 启用 notify 功能
notifyBLECharacteristicValueChange(deviceId) {
var _this = this;
setTimeout(() => {
uni.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
deviceId: deviceId,
serviceId: this.serviceId,
characteristicId: this.tzId.notifyId,
success: (res) => {
console.log("notify链接成功!");
uni.showToast({
title: "链接成功",
icon: "success"
})
this.onBLECharacteristicValueChange();
},
fail: (res) => {
console.log('notify监听失败', res.errMsg)
}
})
}, 1000)
},
onBLECharacteristicValueChange() {
console.log("开始监听")
uni.onBLECharacteristicValueChange((res) => {
console.log("特征变化", res);
console.log(this.ab2hex(res.value))
this.resdata = this.ab2hex(res.value);
})
},
ab2hex(buffer) {
const hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function(bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('')
},
// 读取设备二进制数据
readBLECharacteristicValue() {
uni.readBLECharacteristicValue({
deviceId: this.deviceId,
serviceId: this.serviceId,
characteristicId: this.tzId.readId,
success: (res) => {
console.log('读取数据成功:', res)
},
fail: (res) => {
console.log('读取数据失败:', res)
}
})
},
// 发送二进制数据
writeStr(value) {
var _this = this;
return new Promise(resolve => {
let codeLength = value.length / 2;
let buffer = new ArrayBuffer(codeLength)
const dataView = new DataView(buffer)
let data = [];
//在这里解析将要写入的值
for (let i = 0; i < codeLength; i++) {
dataView.setUint8(i, '0X' + value.substring(i * 2, i * 2 + 2));
data.push(value.substring(2 * i, 2 * i + 2))
}
uni.writeBLECharacteristicValue({
deviceId: this.deviceId,
serviceId: this.serviceId,
characteristicId: this.tzId.writeId,
value: buffer,
success: (res) => {
console.log('发送成功', data.join(','))
resolve(res);
},
fail: (res) => {
console.log('发送失败', res)
}
})
})
},
onBLEConnectionStateChange() {
uni.onBLEConnectionStateChange(res => {
console.log("断开蓝牙", res);
// 该方法回调中可以用于处理连接意外断开等异常情况
uni.showToast({
icon: "none",
title: "蓝牙已经断开!",
mask: false,
duration: 3000
});
});
}
}
}
</script>
<style lang="scss" scoped>
.flex {
display: flex;
}
.content {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
z-index: 66;
display: flex;
flex-direction: column;
.fxitem {
flex: 1;
overflow-y: auto;
}
.box {
border: 1px solid #ccc;
padding: 20upx;
margin: 20upx;
overflow-y: auto;
}
}
</style>