文章目录
- 前言
- 连接逻辑
- 建议
参考资料:https://www.hc01.com/downloads
前言
微信小程序通过蓝牙连接设备,所以需要使用到BLE连接。
思路:
小程序连接BLE的步骤+已经知道设备的BLE名称、服务id、特征值ID。需要根据蓝牙模块提供商的说明书去选择相应的服务、特征值。
注意:监听和写入不一定是同一个特征值。
连接逻辑
假设设备的蓝牙名称是MAX-8080
1、扫一扫二维码获取蓝牙名称;
2、连接BLE准备;
3、根据蓝牙名称链接BLE;
4、连接成功监听特征值;
5、收发数据。
代码:
<script>
export default {data() {return {connected:null,deviceId:null,scan_result:null,// 蓝牙适配器参数adapterState: {discovering: false,available: false}, // 搜索出来的蓝牙设备列表devicesLsits: [],/*** 定时器*/_discoveryTimer: null,_discoveryTimeout: 30000, // 搜索设备超时时间,单位msHC02CharacteristicNotifyUUID:"49535343-1E4D-4BD9-BA61-23C647249616",HC02ServiceUUID:'49535343-FE7D-4AE5-8FA9-9FAFD205E455',}},methods: {/*** 扫一扫调用接口,如果执行成功,app.scan_result会有值*/scan_weixi() {uni.scanCode({success: (res) => {// 取出扫码的设备名称 MAX-8080const 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} = resconst 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);})},}
建议
还是参考资料中的源码吧,我写的毕竟是定制需求,并非适合所有人。附链接:
微信小程序源码