蓝牙通信步骤
1、**wx.openBluetoothAdapter()**打开蓝牙模块
2、**wx.startBluetoothDevicesDiscovery()**搜索蓝牙设备
3、**wx.getBluetoothDevices()**获取所有已发现的蓝牙设备,并取得deviceId,连接蓝牙时要传的参数
4、wx.closeBluetoothAdapter()关闭蓝牙
5、wx.createBLEConnection({})连接蓝牙设备
6、wx.getBLEDeviceServices()取蓝牙锁的服务,获得 serviceId 服务id
7、wx.getBLEDeviceCharacteristics()取蓝牙设备服务下的的所有特征值uuid即characteristicId
8、wx.writeBLECharacteristicValue()向蓝牙设备传输数据
9、wx.notifyBLECharacteristicValueChange()启用低功耗蓝牙设备特征值变化时的 notify 功能,订阅特征值。注意:必须设备的特征值支持 notify 或者 indicate 才可以成功调用
10、wx.onBLECharacteristicValueChange()监听低功耗蓝牙设备的特征值变化事件。必须先启用 notifyBLECharacteristicValueChange 接口才能接收到设备推送的 notification。
案例
wxml
<view class="container">
<view class="usermotto">
<text class="user-motto">{{motto}}</text>
</view>
<view class="flex-wrp" style="flex-direction:row;">
<button type="default" bindtap="openblue"> 打开蓝牙模块 </button>
<button type="default" bindtap="shaomiao"> 搜索附近蓝牙设备 </button>
<button type="default" bindtap="getallblue"> 获取所有已发现的蓝牙设备 </button>
<button type="default" bindtap="connectblue"> 连接蓝牙设备</button>
<button type="default" bindtap="getservice"> 取蓝牙设备的所有服务</button>
<button type="default" bindtap="getchara"> 取蓝牙设备服务下的的所有特征值</button>
<button type="default" bindtap="writedata"> 向蓝牙设备写入数据(降)</button>
<button type="default" bindtap="writedata2"> 向蓝牙设备写入数据(升)</button>
<button type="default" bindtap="closeblue" > 关闭蓝牙模块 </button>
<button type="primary" bindtap="shao1shao">扫一扫</button>
<button type="button" bindtap="getdata">解密</button>
</view>
</view>
wxss
.userinfo {
display: flex;
flex-direction: column;
align-items: center;
}
.userinfo-avatar {
width: 128rpx;
height: 128rpx;
margin: 20rpx;
border-radius: 50%;
}
.userinfo-nickname {
color: #aaa;
}
.usermotto {
margin-top: 0.3rem;
}
.flex-wrp button{
margin:1rem;
}
js
//index.js
//获取应用实例
const app = getApp();
Page({
data: {
motto: 'Hello World',
userInfo: {},
hasUserInfo: false,
canIUse: wx.canIUse('button.open-type.getUserInfo'),
jiamidata: '',
jiemidata: '',
deviceId:'',//设备ID
serviceId: '',//服务ID,一个设备下能有多个服务
characteristicId: '',//特征值ID,一个服务下能有多个特征值,其中某个才是可写的(可发送二进制数据给设备)
readcharacteristicId: '',//支持read的特征值
notifycharacteristicsId: '',//支持监听特征值变化的特征值
},
string2buffer: function (str) {
// 首先将字符串转为16进制
let val = ""
for (let i = 0; i < str.length; i++) {
if (val === '') {
val = str.charCodeAt(i).toString(16)
} else {
val += ',' + str.charCodeAt(i).toString(16)
}
}
// 将16进制转化为ArrayBuffer
return new Uint8Array(val.match(/[\da-f]{2}/gi).map(function (h) {
return parseInt(h, 16)
})).buffer
},
ab2hex(buffer) { //转16进制
let hexArr = Array.prototype.map.call(
new Uint8Array(buffer),
function (bit) {
return ('00' + bit.toString(16)).slice(-2)
}
)
return hexArr.join('');
},
//打开蓝牙
openblue: function () {
var that = this;
wx.openBluetoothAdapter({
success: function (res) {
console.log(res);
that.setData({
motto: "开启蓝牙:" + res.errMsg
});
},
fail: function (res) {
console.log("蓝牙打开失败:" + JSON.stringify(res));
that.setData({
motto: "蓝牙开启失败:" + res
});
}
})
},
//获取蓝牙设备
getallblue: function () {
var that = this;
wx.getBluetoothDevices({
success: function (res) {
console.log(res)
for (var i = 0; i < res.devices.length; i++) {
if (res.devices[i].name == 'ASDDloc1') { //这个是我调试的蓝牙锁的名称
that.setData({
motto: "第一个蓝牙设备:\n name: " + res.devices[i].name + "\n deviceId:" + res.devices[i].deviceId,
deviceId: res.devices[i].deviceId
})
console.log(res.devices[i].deviceId)
}
}
}
})
},
connectblue: function () {
var that = this;
wx.createBLEConnection({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: that.data.deviceId,
success: function (res) {
console.log(res)
that.setData({
motto: "连接蓝牙设备:" + res.errMsg
});
},
fail: function (res) {
that.setData({
motto: "连接蓝牙设备失败:" + res.errMsg
});
}
})
},
getservice: function () {
var that = this;
wx.getBLEDeviceServices({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: that.data.deviceId,
success: function (res) {
console.log('device services:', res.services)
serviceId = res.services[0].uuid;
that.setData({
serviceId: serviceId,
motto: res.errMsg + " \n uuid:" + serviceId
});
},
fail: function () {
that.setData({
motto: "失败:" + res.errMsg
});
}
})
},
getchara: function () {
var that = this;
wx.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: that.data.deviceId,
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: that.data.serviceId,
success: function (res) {
console.log(res)
console.log('device getBLEDeviceCharacteristics:', res.characteristics);
that.setData({
characteristicId: res.characteristics[0].uuid,
readcharacteristicId: res.characteristics[0].uuid,
motto: res.errMsg + "\n 特征值UUID:" + res.characteristics[0].uuid
});
let characteristicId = res.characteristics[0].uuid
wx.notifyBLECharacteristicValueChange({
state: true,
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: characteristicId,
success() {
console.log('开始监听特征值')
console.log(characteristicId)
wx.onBLECharacteristicValueChange(function (onNotityChangeRes) {
console.log('监听到特征值更新', onNotityChangeRes);
let characteristicValue = Decrypt.decrypt(onNotityChangeRes.value, [58, 96, 67, 42, 92, 1, 33, 31, 41, 30, 15, 78, 12, 19, 40, 37]);
console.log(characteristicValue)
})
},
fail: (res) => {
console.warn("监听特征值失败");
}
})
},
fail: function (res) {
that.setData({
motto: "失败:" + res.errMsg
});
}
})
},
writedata: function () {
var that = this;
var buffer1 = that.string2buffer('UL123456554C31323334353600')
console.log("发送内容:", buffer1)
wx.writeBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.characteristicId,
// 这里的value是ArrayBuffer类型
value: buffer1,
success: function (res) {
console.log(res)
console.log('writeBLECharacteristicValue success', res.errMsg);
that.setData({
motto: "写入蓝入设备(降):" + res.errMsg
});
wx.readBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.readcharacteristicId,
success: function (res) {
console.log('readBLECharacteristicValue success', res)
},
fail(res) {
console.log('readBLECharacteristicValue fail', res)
}
})
},
fail: function (res) {
console.log(res)
that.setData({
motto: "写数据到蓝牙设备失败:" + res.errMsg
});
}
})
},
writedata2: function () {
var that = this;
var buffer1 = that.string2buffer('LO1234564C4F31323334353600')
console.log("发送内容:", buffer1)
wx.writeBLECharacteristicValue({
// 这里的 deviceId 需要在上面的 getBluetoothDevices 或 onBluetoothDeviceFound 接口中获取
deviceId: that.data.deviceId,
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: that.data.serviceId,
// 这里的 characteristicId 需要在上面的 getBLEDeviceCharacteristics 接口中获取
characteristicId: that.data.characteristicId,
// 这里的value是ArrayBuffer类型
value: buffer1,
success: function (res) {
console.log('writeBLECharacteristicValue success', res.errMsg);
that.setData({
motto: "写入蓝入设备(升):" + res.errMsg
});
wx.readBLECharacteristicValue({
deviceId: that.data.deviceId,
serviceId: that.data.serviceId,
characteristicId: that.data.readcharacteristicId,
success: function (res) {
console.log('readBLECharacteristicValue success', res)
},
fail(res) {
console.log('readBLECharacteristicValue fail', res)
}
})
},
fail: function (res) {
that.setData({
motto: "写数据到蓝牙设备失败:" + res.errMsg
});
}
})
},
shaomiao: function () {
var that = this;
// 以微信硬件平台的蓝牙智能灯为例,主服务的 UUID 是 FEE7。传入这个参数,只搜索主服务 UUID 为 FEE7 的设备
wx.startBluetoothDevicesDiscovery({
// services: ['FEE7'],
success: function (res) {
console.log(res);
that.setData({
motto: res.errMsg
});
},
fail: function (res) {
that.setData({
motto: "失败:" + res.errMsg
});
}
})
/*
wx.createBLEConnection({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: 'YH000001222',
success: function (res) {
console.log(res);
that.setData({ motto: "连接蓝牙设备:" + res.errMsg });
}
,fail:function(res){
that.setData({ motto: "连接蓝牙设备失败:" + res.errMsg });
}
})*/
},
closeblue: function () {
var that = this;
wx.closeBluetoothAdapter({
success: function (res) {
console.log(res);
that.setData({
motto: "关闭蓝牙:" + res.errMsg
});
}
})
},
shao1shao: function () {
var that = this;
//只允许从相机扫码
wx.scanCode({
onlyFromCamera: true,
success(res_scan) {
console.log(res_scan);
var msg = "设备号:" + res_scan.result + "\r\n";
var devname = res_scan.result;
wx.openBluetoothAdapter({
success: function (res_openblue) {
console.log(res_openblue);
msg += "开启蓝牙:" + res_openblue.errMsg + "\r\n";
wx.startBluetoothDevicesDiscovery({
success: function (res_searchblue) {
console.log(res_searchblue);
msg += "搜索附近蓝牙设备成功\r\n";
wx.getBluetoothDevices({
success: function (res_getallblue) {
console.log(res_getallblue)
for (var i = 0; i < res_getallblue.devices.length; i++) {
if (res_getallblue.devices[i].name == devname) {
deviceId = res_getallblue.devices[i].deviceId;
break;
}
}
if (deviceId == '') {
that.setData({
motto: "找不到设备名为" + devname + "的deviceId" + "\r\n"
})
return;
}
msg += "找到设备号对应的设备ID:" + deviceId + "\r\n";
wx.createBLEConnection({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: deviceId,
success: function (res) {
console.log(res)
msg += "连接蓝牙设备:" + res.errMsg + "\r\n"
wx.getBLEDeviceServices({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: deviceId,
success: function (res) {
console.log('device services:', res.services)
serviceId = res.services[1].uuid;
msg += "获取服务ID:" + serviceId + "\r\n";
wx.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: deviceId,
// 这里的 serviceId 需要在上面的 getBLEDeviceServices 接口中获取
serviceId: serviceId,
success: function (res) {
characteristicId = res.characteristics[5].uuid;
msg += "获取特征值:" + characteristicId + "\r\n";
that.setData({
motto: msg
});
},
fail: function (res) {
that.setData({
motto: "取特征值失败:" + res.errMsg
});
}
})
},
fail: function () {
that.setData({
motto: "取服务ID失败:" + res.errMsg
});
}
})
},
fail: function (res) {
msg += "连接蓝牙设备失败:" + res.errMsg;
that.setData({
motto: msg
});
}
})
}
})
},
fail: function (res) {
that.setData({
motto: "搜索附近蓝牙设备失败:" + res.errMsg
});
}
})
},
fail: function (res) {
console.log("蓝牙打开失败:" + JSON.stringify(res));
msg += "开启蓝牙失败:" + res.errMsg;
that.setData({
motto: msg
});
}
})
}
})
},
onLoad: function () {
if (app.globalData.userInfo) {
this.setData({
userInfo: app.globalData.userInfo,
hasUserInfo: true
})
} else if (this.data.canIUse) {
// 由于 getUserInfo 是网络请求,可能会在 Page.onLoad 之后才返回
// 所以此处加入 callback 以防止这种情况
app.userInfoReadyCallback = res => {
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
} else {
// 在没有 open-type=getUserInfo 版本的兼容处理
wx.getUserInfo({
success: res => {
app.globalData.userInfo = res.userInfo
this.setData({
userInfo: res.userInfo,
hasUserInfo: true
})
}
})
}
},
getUserInfo: function (e) {
console.log(e)
app.globalData.userInfo = e.detail.userInfo
this.setData({
userInfo: e.detail.userInfo,
hasUserInfo: true
})
}
})
开关锁指令
开锁成功
关锁成功
大功告成!!!