文章目录
参考资料:https://www.hc01.com/downloads
前言
微信小程序通过蓝牙连接设备,所以需要使用到BLE连接。
思路:
小程序连接BLE的步骤+已经知道设备的BLE名称、服务id、特征值ID。需要根据蓝牙模块提供商的说明书去选择相应的服务、特征值。
注意:监听和写入不一定是同一个特征值。
连接逻辑
假设设备的蓝牙名称是MAX-8080
1、扫一扫二维码获取蓝牙名称;
2、连接BLE准备;
3、根据蓝牙名称链接BLE;
4、连接成功监听特征值;
5、收发数据。
代码:
js
<script>
export default {
data() {
return {
connected:null,
deviceId:null,
scan_result:null,
// 蓝牙适配器参数
adapterState: {
discovering: false,
available: false
},
// 搜索出来的蓝牙设备列表
devicesLsits: [],
/**
* 定时器
*/
_discoveryTimer: null,
_discoveryTimeout: 30000, // 搜索设备超时时间,单位ms
HC02CharacteristicNotifyUUID:"49535343-1E4D-4BD9-BA61-23C647249616",
HC02ServiceUUID:'49535343-FE7D-4AE5-8FA9-9FAFD205E455',
}
},
methods: {
/**
* 扫一扫调用接口,如果执行成功,app.scan_result会有值
*/
scan_weixi() {
uni.scanCode({
success: (res) => {
// 取出扫码的设备名称 MAX-8080
const result = res.result.split("?")[1];
this.scan_result = result;
this.closeBLEConnection();
this.openBluetoothAdapter();
},
fail: (err) => {
// 如果失败返回空
}
});
},
/**
* 断开蓝牙连接
*/
async closeBLEConnection(OBJECT) {
try {
const state = uni.getStorageSync('bluetoothAdapterState');
if (state) {
console.log("===断开连接操作===");
uni.removeStorageSync('bluetoothAdapterState');
await uni.closeBLEConnection({
deviceId: this.deviceId,
success(res) {
console.log("===蓝牙已断开===", res)
}
})
}
} catch (e) {
// error
}
// 关闭蓝牙特征值的监听
wx.offBLECharacteristicValueChange();
},
/**
* 初始化蓝牙设备
*/
openBluetoothAdapter() {
const that = this;
console.log("初始化log_scan_result", this.scan_result);
uni.openBluetoothAdapter({
success: e => {
try {
uni.setStorageSync('bluetoothAdapterState', true);
} catch (e) {
// error
}
console.log('初始化蓝牙成功:' + JSON.stringify(e));
},
fail: e => {
try {
uni.setStorageSync('bluetoothAdapterState', false);
} catch (err) {
// error
}
console.log(e)
console.log('初始化蓝牙失败,错误码:' + (e.errCode || e.errMsg));
},
complete: () => {
wx.offBluetoothAdapterStateChange();
// 语法将结果res传入到handleBluetoothAdapterStateChange方法中
wx.onBluetoothAdapterStateChange(this.handleBluetoothAdapterStateChange);
/** 监听蓝牙连接 */
// console.log('【监听蓝牙连接...】')
wx.offBLEConnectionStateChange();
wx.onBLEConnectionStateChange(this.handleBLEConnectionStateChange);
/** 开始搜索附近设备 */
this.onDevicesDiscovery()
}
});
},
/**
* 蓝牙适配器状态改变(例如手动关闭蓝牙)
*/
async handleBluetoothAdapterStateChange(res) {
console.log("BLE适配器发生变化", res, this.scan_result);
// available 蓝牙适配器是否可用
// discovering 蓝牙适配器是否处于搜索状态
const {
available
} = res
const originState = wx.getStorageSync('bluetoothAdapterState')
wx.setStorageSync('bluetoothAdapterState', available)
if (!available) {
this.offDevicesDiscovery()
uni.showToast({
title: '请打开手机蓝牙',
icon: "error",
duration: 2000
});
} else if (!originState) {
this.onDevicesDiscovery();
}
},
/** 开启搜索附近设备 */
onDevicesDiscovery() {
console.log('【开始搜索附近设备...】')
if (wx.getStorageSync('bluetoothAdapterState')) {
wx.startBluetoothDevicesDiscovery({
allowDuplicatesKey: true, // 重复上报发现设备
powerLevel: 'height',
interval: 1000,
success: () => {
// this._deviceIdsList = []
// this.setData({
// devicesList: []
// })
/** 发现设备 */
wx.onBluetoothDeviceFound(this.handleFoundBluetoothDevices)
/** 超时关闭搜索 */
this._discoveryTimer = setTimeout(() => {
this.offDevicesDiscovery();
}, this._discoveryTimeout)
},
fail: err => {
console.error(err)
}
})
}
},
/**
* 搜索附近设备回调
*/
handleFoundBluetoothDevices({
devices
}) {
console.log("发现的设备列表devices", devices, this.scan_result);
for (let item of devices) {
if (this.scan_result == item.localName) {
// 保存在全局变量中
this.connectDevice = item;
this.offDevicesDiscovery();
console.log("找到设备", item, this.scan_result);
if (!this.connected && this.connectDetermine(item.localName) && wx.getStorageSync(
'bluetoothAdapterState')) {
console.log("==开始连接==", item.localName);
this.createBLEConnection();
} else {
console.log("校验失败,不给予连接:", app.connected, wx.getStorageSync(
'bluetoothAdapterState'));
}
}
}
},
/**
* 连接低功耗蓝牙(连接开始)
*/
async createBLEConnection() {
let that = this;
let deviceId = this.deviceId;
// 弹窗
uni.showToast({
title: '连接蓝牙中...',
icon: 'loading',
duration: 2000
});
await uni.createBLEConnection({
deviceId,
success: res => {
console.log("createBLEConnection连接蓝牙成功", res);
uni.hideLoading();
uni.showToast({
title: '连接成功',
icon: 'success',
duration: 1500
});
// this.getSystemInfo();
this.setMTU();
setTimeout(() => {
// 订阅特征值
this.getBLESC();
}, 500)
},
fail: e => {
let res = JSON.stringify(e);
console.log('连接低功耗蓝牙失败,错误码:' + res);
// 表示已经连接,不能再次连接的错误提示
if (res.errCode == -1 && res.errno == 1509007) {
app.connected = true;
}
}
});
},
/**
* 获取服务(Services)和特征值(Characteristics)
* 必须的一步:IOS要调用特征值之后才能监听 notifyBLECharacteristicValueChange,否则会报错(找不到服务/特征值)
*/
getBLESC() {
const that = this;
console.log("====进入getBLESC====", this.deviceId, this.HC02ServiceUUID);
uni.getBLEDeviceServices({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: this.deviceId,
success(res) {
console.log('获取服务类别device services:', res.services)
},
fail(e) {
console.log('getBLEDeviceServices失败', e);
}
})
uni.getBLEDeviceCharacteristics({
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: this.deviceId,
// 这里的 serviceId 需要在 getBLEDeviceServices 接口中获取
serviceId: this.HC02ServiceUUID,
success(res) {
console.log('获取特征值device getBLEDeviceCharacteristics:', res
.characteristics)
that.notifyBLECharacteristicValueChange();
},
fail(e) {
console.log('getBLEDeviceCharacteristics失败', e);
that.getBLESC();
}
})
},
/**
* 订阅操作成功后需要设备主动更新特征值的 value,才会触发 uni.onBLECharacteristicValueChange 回调。
*/
async notifyBLECharacteristicValueChange() {
await uni.notifyBLECharacteristicValueChange({
state: true, // 启用 notify 功能
// 这里的 deviceId 需要已经通过 createBLEConnection 与对应设备建立链接
deviceId: this.deviceId,
// 固定写死
serviceId: this.HC02ServiceUUID,
// 固定写死
characteristicId: this.HC02CharacteristicNotifyUUID,
success: (res) => {
console.log('notifyBLECharacteristicValueChange执行 success:' + res.errMsg);
onBLECharacteristicValueChange();
},
fail: (err) => {
}
});
},
onBLECharacteristicValueChange(){
console.log("==========调用监听蓝牙======");
uni.onBLECharacteristicValueChange(function(res) {
console.log("==========在Send方法收到蓝牙信息======", res);})
},
}
建议
还是参考资料中的源码吧,我写的毕竟是定制需求,并非适合所有人。附链接:
微信小程序源码